From 0a05fde0ba5d123895b321d459eab0f8ff180171 Mon Sep 17 00:00:00 2001 From: 17792275749 <812100002@qq.com> Date: Thu, 21 May 2026 22:02:56 +0800 Subject: [PATCH] =?UTF-8?q?[AI=20Generated]:=20feat(member,home):=20addMem?= =?UTF-8?q?ber=20=E6=8E=A5=E5=85=A5=E8=BA=AB=E4=BB=BD=E8=AF=81=E8=81=94?= =?UTF-8?q?=E5=8A=A8=E6=A0=A1=E9=AA=8C=EF=BC=9BOTA=20=E5=8D=87=E7=BA=A7=20?= =?UTF-8?q?15s=20=E5=90=8E=E8=87=AA=E5=8A=A8=E9=87=8D=E8=BF=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - addMember: 姓名+身份证输入联动调 getUserInfoByIdcard,result 非 null 时以服务端身份证重算性别年龄 - addMember: 新增 hasQueried 标记,result 为 null 视为合法新人允许提交;payload 以 serverResult 做底再用表单覆盖 - home: OTA 升级 setTimeout 到点后清 connected 状态并触发 lefuService.autoConnect() 重新扫连 Co-Authored-By: Claude Opus 4.7 --- miniprogram/pages/addMember/addMember.ts | 105 ++++++++++++++++++++++- miniprogram/pages/home/home.ts | 9 +- 2 files changed, 109 insertions(+), 5 deletions(-) diff --git a/miniprogram/pages/addMember/addMember.ts b/miniprogram/pages/addMember/addMember.ts index f2cd7ba..e87ea4d 100644 --- a/miniprogram/pages/addMember/addMember.ts +++ b/miniprogram/pages/addMember/addMember.ts @@ -12,6 +12,34 @@ interface SysUserDevice { birthday: string } +/** GET /weighingScale/v3/getUserInfoByIdcard 返回的 result 结构 */ +interface UserInfoFromServer { + id: string | null + userId: string + parentUserId: string | null + scaleDeviceId: string + deviceId: string | null + deviceType: string + dataType: number + userType: string | null + idCard: string + height: number + weight: number + birthday: string + sex: number + avatar: string | null + phone: string + thirdId: string | null + realname: string + bmi: number + workNo: string + remark: string | null + relationType: string | null + sn: string + delFlag: number + sex_dictText: string +} + /** 表单数据模型 */ interface MemberForm { /** 姓名 */ @@ -72,6 +100,12 @@ Page({ /** 从抽屉选中的完整成员数据,提交时作为 base spread */ selectedMember: null as ExistingMember | null, showSelectDrawer: false, + /** 正在请求身份证查询接口 */ + querying: false, + /** 是否已完成一次身份证查询(成功 200 即视为完成,无论 result 是否为 null) */ + hasQueried: false, + /** 接口返回的用户信息,姓名 + 身份证联动校正性别年龄 */ + serverResult: null as UserInfoFromServer | null, }, onLoad(options: Record) { @@ -91,11 +125,22 @@ Page({ 'form.height': String(u.height ?? ''), 'form.weight': String(u.weight ?? ''), }) + if ((u.realname ?? '').trim() && this.isIdCardValid(u.idCard ?? '')) { + this.fetchUserInfoByIdCard(u.realname.trim(), u.idCard) + } }) }, onNameInput(e: WechatMiniprogram.Input) { - this.setData({ 'form.name': e.detail.value }) + const name = e.detail.value + this.setData({ 'form.name': name }) + if (!name.trim()) { + this.setData({ serverResult: null, hasQueried: false }) + return + } + if (this.isIdCardValid(this.data.form.idCard)) { + this.fetchUserInfoByIdCard(name.trim(), this.data.form.idCard) + } }, onIdCardInput(e: WechatMiniprogram.Input) { @@ -106,6 +151,13 @@ Page({ 'form.gender': parsed.gender, 'form.age': parsed.age }) + if (!parsed.gender) { + this.setData({ serverResult: null, hasQueried: false }) + return + } + if (this.data.form.name.trim()) { + this.fetchUserInfoByIdCard(this.data.form.name.trim(), idCard) + } }, onHeightInput(e: WechatMiniprogram.Input) { @@ -116,12 +168,19 @@ Page({ this.setData({ 'form.weight': e.detail.value }) }, + /** + * 校验身份证格式:18 位,前 17 位数字,末位数字或 X + */ + isIdCardValid(idCard: string): boolean { + return /^\d{17}[\dX]$/.test(idCard) + }, + /** * 解析身份证,返回性别、年龄、sex 数值、出生日期 */ parseIdCard(idCard: string): IdCardParsed { const empty: IdCardParsed = { gender: '', age: '', sex: 0, birthday: '' } - if (!/^\d{17}[\dX]$/.test(idCard)) return empty + if (!this.isIdCardValid(idCard)) return empty const genderCode = parseInt(idCard.charAt(16), 10) const sex = genderCode % 2 === 1 ? 1 : 2 @@ -142,6 +201,41 @@ Page({ return { gender, age: String(age), sex, birthday: `${year}-${mm}-${dd}` } }, + /** + * 调用服务端接口校验身份证与姓名,成功后用接口返回的身份证重新计算性别年龄 + * result 为 null 视为「查无此人」,标记 hasQueried 允许新增提交 + */ + fetchUserInfoByIdCard(name: string, idCard: string) { + if (this.data.querying) return + this.setData({ querying: true, serverResult: null, hasQueried: false }) + + get('weighingScale/v3/getUserInfoByIdcard', { + sn: lefuService.deviceInfo?.serialNumber ?? '', + idCard, + realname: name + }, { loading: false }) + .then(res => { + const serverResult = res.result + if (!serverResult) { + this.setData({ hasQueried: true }) + return + } + const parsed = this.parseIdCard(serverResult.idCard) + this.setData({ + serverResult, + hasQueried: true, + 'form.gender': parsed.gender, + 'form.age': parsed.age + }) + }) + .catch(() => { + // 查询失败保留本地解析结果,hasQueried 维持 false 以便用户重试时再次触发 + }) + .finally(() => { + this.setData({ querying: false }) + }) + }, + onTapSelectExisting() { this.setData({ showSelectDrawer: true }) }, @@ -194,13 +288,20 @@ Page({ wx.showToast({ title: '请填写体重', icon: 'none' }) return } + if (!this.data.hasQueried) { + wx.showToast({ title: this.data.querying ? '身份信息验证中,请稍候' : '请检查姓名与身份证号', icon: 'none' }) + return + } const parsed = this.parseIdCard(idCard) const userInfo = wx.getStorageSync('userInfo') const connectDeviceInfoRaw = wx.getStorageSync('connectDeviceInfo') + const serverResult = this.data.serverResult + // selectedMember(抽屉选中) → serverResult(接口校验,可能为 null) → 表单/本地解析(用户输入) 依次覆盖 const payload: Record = { ...(this.data.selectedMember ?? {}), + ...(serverResult ?? {}), parentUserId: userInfo?.userId ?? '', scaleDeviceId: lefuService.deviceInfo?.serialNumber ?? '', realname: name.trim(), diff --git a/miniprogram/pages/home/home.ts b/miniprogram/pages/home/home.ts index 93bfad9..997604b 100644 --- a/miniprogram/pages/home/home.ts +++ b/miniprogram/pages/home/home.ts @@ -152,9 +152,12 @@ Page({ lefuService.checkAndUpgrade() .then(() => { wx.showLoading({ title: '固件升级中...', mask: true }) - setTimeout(() => { - wx.hideLoading() - }, 15000) + setTimeout(() => { + wx.hideLoading() + // 升级完成后设备重启,旧连接与订阅失效,重新扫描连接 + this.setData({ 'device.connected': false }) + lefuService.autoConnect() + }, 15000) }) .catch(() => {}) },