import { get, put } from '../../utils/request/index' import { lefuService } from '../../lefu/index' /** GET /weighingScale/v3/selectUserBySn/user 返回的单条结构(编辑回填用) */ interface SysUserDevice { id: string realname: string idCard: string height: number sex: number birthday: string } /** 表单数据模型 */ interface MemberForm { /** 姓名 */ name: string /** 身份证号 */ idCard: string /** 性别(由身份证解析,只读) */ gender: string /** 年龄(由身份证解析,只读) */ age: string /** 身高(cm) */ height: string /** 体重(kg) */ weight: string } /** 身份证解析结果 */ interface IdCardParsed { gender: string age: string sex: number birthday: string } /** 从抽屉组件 select 事件接收的成员数据 */ interface ExistingMember { name: string gender: '男' | '女' age: number height: number weight: number idCard: string } /** * 添加/编辑成员页 * URL 参数含 userId 时为编辑模式,隐藏「从已有成员中选择」按钮并预填表单 */ Page({ data: { /** 编辑模式标记 */ isEdit: false, /** 编辑时的用户 ID */ userId: '', form: { name: '', idCard: '', gender: '', age: '', height: '', weight: '' } as MemberForm, showSelectDrawer: false, }, onLoad(options: Record) { const { userId } = options if (!userId) return this.setData({ isEdit: true, userId }) get('weighingScale/v2/getUserInfo', { id: userId }, { loading: false }) .then((res: any) => { const u: SysUserDevice = res.result if (!u) return const parsed = this.parseIdCard(u.idCard ?? '') this.setData({ 'form.name': u.realname ?? '', 'form.idCard': u.idCard ?? '', 'form.gender': parsed.gender, 'form.age': parsed.age, 'form.height': String(u.height ?? ''), }) }) }, onNameInput(e: WechatMiniprogram.Input) { this.setData({ 'form.name': e.detail.value }) }, onIdCardInput(e: WechatMiniprogram.Input) { const idCard = (e.detail.value || '').trim().toUpperCase() const parsed = this.parseIdCard(idCard) this.setData({ 'form.idCard': idCard, 'form.gender': parsed.gender, 'form.age': parsed.age }) }, onHeightInput(e: WechatMiniprogram.Input) { this.setData({ 'form.height': e.detail.value }) }, onWeightInput(e: WechatMiniprogram.Input) { this.setData({ 'form.weight': e.detail.value }) }, /** * 解析身份证,返回性别、年龄、sex 数值、出生日期 */ parseIdCard(idCard: string): IdCardParsed { const empty: IdCardParsed = { gender: '', age: '', sex: 0, birthday: '' } if (!/^\d{17}[\dX]$/.test(idCard)) return empty const genderCode = parseInt(idCard.charAt(16), 10) const sex = genderCode % 2 === 1 ? 1 : 2 const gender = sex === 1 ? '男' : '女' const year = parseInt(idCard.substr(6, 4), 10) const month = parseInt(idCard.substr(10, 2), 10) const day = parseInt(idCard.substr(12, 2), 10) if (!year || month < 1 || month > 12 || day < 1 || day > 31) return empty const now = new Date() let age = now.getFullYear() - year if (now.getMonth() + 1 < month || (now.getMonth() + 1 === month && now.getDate() < day)) age -= 1 if (age < 0 || age > 150) return empty const mm = String(month).padStart(2, '0') const dd = String(day).padStart(2, '0') return { gender, age: String(age), sex, birthday: `${year}-${mm}-${dd}` } }, onTapSelectExisting() { this.setData({ showSelectDrawer: true }) }, onSelectMemberClose() { this.setData({ showSelectDrawer: false }) }, onSelectMember(e: WechatMiniprogram.CustomEvent) { const { name, gender, age, height, weight, idCard } = e.detail this.setData({ showSelectDrawer: false, 'form.name': name, 'form.idCard': idCard, 'form.gender': gender, 'form.age': String(age), 'form.height': String(height), 'form.weight': String(weight), }) }, onCancel() { wx.navigateBack() }, onSubmit() { const { name, idCard, gender, age, height, weight } = this.data.form const heightNum = parseFloat(height) const weightNum = parseFloat(weight) if (!name.trim()) { wx.showToast({ title: '请填写姓名', icon: 'none' }) return } if (idCard.length !== 18) { wx.showToast({ title: '请填写正确的身份证号', icon: 'none' }) return } if (!gender || !age) { wx.showToast({ title: '身份证号有误,请检查', icon: 'none' }) return } if (!height || isNaN(heightNum) || heightNum <= 0) { wx.showToast({ title: '请填写身高', icon: 'none' }) return } if (!weight || isNaN(weightNum) || weightNum <= 0) { wx.showToast({ title: '请填写体重', icon: 'none' }) return } const parsed = this.parseIdCard(idCard) const userInfo = wx.getStorageSync('userInfo') const connectDeviceInfoRaw = wx.getStorageSync('connectDeviceInfo') const payload: Record = { parentUserId: userInfo?.userId ?? '', scaleDeviceId: lefuService.deviceInfo?.serialNumber ?? '', realname: name.trim(), idCard, sex: parsed.sex, birthday: parsed.birthday, height: heightNum, weight: weightNum, connectDeviceInfo: connectDeviceInfoRaw ? JSON.stringify(connectDeviceInfoRaw) : '', } if (this.data.isEdit) { payload.id = this.data.userId } const successMsg = this.data.isEdit ? '保存成功' : '添加成功' const failMsg = this.data.isEdit ? '保存失败,请重试' : '添加失败,请重试' put('weighingScale/v3/edit/user', payload) .then(() => { wx.showToast({ title: successMsg, icon: 'success' }) setTimeout(() => { // 通知上一页(equipmentMember)刷新成员列表 const pages = getCurrentPages() const prevPage = pages[pages.length - 2] as any if (prevPage && prevPage.data?.sn) { prevPage._loadData(prevPage.data.sn) } wx.navigateBack() }, 1500) }) .catch(() => { wx.showToast({ title: failMsg, icon: 'none' }) }) } })