Files
bodyWeight/miniprogram/components/selectMemberDrawer/selectMemberDrawer.ts
T

177 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { get } from '../../utils/request/index'
import { lefuService } from '../../lefu/index'
/** GET /weighingScale/v3/select/addMembers/user 返回的单条结构 */
interface AddMemberApiItem {
id: string
realname: string
sex_dictText: '男' | '女'
birthday: string
height: number
weight: number
idCard: string | null
avatar: string | null
}
/** GET /weighingScale/v3/select/history/user 返回的单条结构 */
interface HistoryApiItem {
userId: string
realname: string
sex: number
height: number
birthday: string
avatar: string | null
relationType: number | string | null
}
/** 抽屉内部成员项(含回填所需全量字段) */
interface ExistingMember {
id: string
name: string
gender: '男' | '女'
age: number
height: number
weight: number
idCard: string
avatar?: string
selected?: boolean
/** history 模式额外携带,供页面构建 userInfo */
userId?: string
sex?: number
birthday?: string
relationType?: number | string | null
}
/**
* 选择已有成员抽屉组件
* Properties: show(控制显示)
* Events: close(关闭), select(选中成员,携带 ExistingMember)
*/
Component({
properties: {
/** 是否显示抽屉 */
show: {
type: Boolean,
value: false
},
/** 数据来源模式:addMember=新增成员选择 / history=历史数据切换成员 */
source: {
type: String,
value: 'addMember'
}
},
data: {
/** 控制 wx:ifDOM 是否存在 */
innerShow: false,
/** 控制 --visible 类,触发 CSS transition */
animVisible: false,
/** 成员列表(组件内部拉取) */
members: [] as ExistingMember[]
},
observers: {
/**
* 监听外部 show 变化:
* 打开时先拉数据再展示抽屉;关闭时移除动画类后移除 DOM
*/
show(val: boolean) {
if (val) {
this._fetchMembers()
this.setData({ innerShow: true })
setTimeout(() => {
this.setData({ animVisible: true })
}, 20)
} else {
this.setData({ animVisible: false })
setTimeout(() => {
this.setData({ innerShow: false })
}, 300)
}
}
},
methods: {
/** 从生日字符串(YYYY-MM-DD)计算周岁 */
_calcAge(birthday: string): number {
if (!birthday) return 0
const [year, month, day] = birthday.split('-').map(Number)
if (!year || !month || !day) return 0
const now = new Date()
let age = now.getFullYear() - year
if (now.getMonth() + 1 < month || (now.getMonth() + 1 === month && now.getDate() < day)) age -= 1
return Math.max(0, age)
},
/** 调接口获取可选成员列表,根据 source 调不同接口 */
_fetchMembers() {
const userInfo = wx.getStorageSync('userInfo') as { userId?: string } | null
const userId = userInfo?.userId ?? ''
wx.showLoading({ title: '加载中...', mask: true })
if (this.properties.source === 'history') {
get<HistoryApiItem[]>('weighingScale/v3/select/history/user', { userId }, { loading: false })
.then((res: any) => {
const members: ExistingMember[] = (res.result ?? []).map((item: HistoryApiItem) => ({
id: item.userId,
name: item.realname,
gender: item.sex === 1 ? '男' : '女',
age: this._calcAge(item.birthday),
height: item.height,
weight: 0,
idCard: '',
avatar: item.avatar ?? '',
userId: item.userId,
sex: item.sex,
birthday: item.birthday,
relationType: item.relationType,
}))
this.setData({ members })
})
.finally(() => {
wx.hideLoading()
})
} else {
const sn = lefuService.deviceInfo?.serialNumber ?? ''
get<AddMemberApiItem[]>('weighingScale/v3/select/addMembers/user', { userId, sn }, { loading: false })
.then((res: any) => {
const members: ExistingMember[] = (res.result ?? []).map((item: AddMemberApiItem) => ({
id: item.id,
name: item.realname,
gender: item.sex_dictText,
age: this._calcAge(item.birthday),
height: item.height,
weight: item.weight,
idCard: item.idCard ?? '',
avatar: item.avatar ?? '',
}))
this.setData({ members })
})
.finally(() => {
wx.hideLoading()
})
}
},
/** 点击遮罩关闭 */
onTapMask() {
this.triggerEvent('close')
},
/** 点击关闭按钮 */
onTapClose() {
this.triggerEvent('close')
},
/**
* 点击成员行,触发 select 事件
* @param e 携带 data-member 的点击事件
*/
onTapMember(e: WechatMiniprogram.TouchEvent) {
const member = e.currentTarget.dataset.member as ExistingMember
this.triggerEvent('select', member)
}
}
})