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:if,DOM 是否存在 */ 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('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('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) } } })