From fbef06b5c28b798d7022e0f77fa5b0cbfc56c1b2 Mon Sep 17 00:00:00 2001 From: 17792275749 <812100002@qq.com> Date: Fri, 15 May 2026 14:30:30 +0800 Subject: [PATCH] =?UTF-8?q?[AI=20Generated]:=20feat(*):=20=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E6=95=B0=E6=8D=AE=E9=A1=B5=E5=88=87=E6=8D=A2=E6=88=90?= =?UTF-8?q?=E5=91=98=E3=80=81=E9=A6=96=E9=A1=B5=E6=8E=A5=E5=8F=A3=E5=AF=B9?= =?UTF-8?q?=E6=8E=A5=E5=8F=8A=E6=88=91=E7=9A=84=E9=A1=B5=E7=BC=93=E5=AD=98?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../selectMemberDrawer.less | 20 ++++ .../selectMemberDrawer/selectMemberDrawer.ts | 87 +++++++++++---- .../selectMemberDrawer.wxml | 58 ++++++---- miniprogram/pages/data/data.json | 4 +- miniprogram/pages/data/data.ts | 53 +++++++-- miniprogram/pages/data/data.wxml | 11 +- miniprogram/pages/home/home.ts | 104 ++++++++++++++---- miniprogram/pages/home/home.wxml | 2 +- miniprogram/pages/my/my.less | 8 +- miniprogram/pages/my/my.ts | 47 +++++++- miniprogram/pages/my/my.wxml | 10 +- 11 files changed, 316 insertions(+), 88 deletions(-) diff --git a/miniprogram/components/selectMemberDrawer/selectMemberDrawer.less b/miniprogram/components/selectMemberDrawer/selectMemberDrawer.less index 47242ce..09f28d2 100644 --- a/miniprogram/components/selectMemberDrawer/selectMemberDrawer.less +++ b/miniprogram/components/selectMemberDrawer/selectMemberDrawer.less @@ -226,3 +226,23 @@ background-color: #EAEDF1; margin: 24rpx 30rpx 0; } + +/* 空态占位 */ +.drawer-empty { + display: flex; + flex-direction: column; + align-items: center; + padding-top: 80rpx; + + .drawer-empty-icon { + width: 193rpx; + height: 138rpx; + margin-bottom: 30rpx; + } + + .drawer-empty-text { + color: #808080; + font-size: 28rpx; + line-height: 28rpx; + } +} diff --git a/miniprogram/components/selectMemberDrawer/selectMemberDrawer.ts b/miniprogram/components/selectMemberDrawer/selectMemberDrawer.ts index a02bc3f..2e5e5d2 100644 --- a/miniprogram/components/selectMemberDrawer/selectMemberDrawer.ts +++ b/miniprogram/components/selectMemberDrawer/selectMemberDrawer.ts @@ -13,6 +13,17 @@ interface AddMemberApiItem { 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 @@ -24,6 +35,11 @@ interface ExistingMember { idCard: string avatar?: string selected?: boolean + /** history 模式额外携带,供页面构建 userInfo */ + userId?: string + sex?: number + birthday?: string + relationType?: number | string | null } /** @@ -37,6 +53,11 @@ Component({ show: { type: Boolean, value: false + }, + /** 数据来源模式:addMember=新增成员选择 / history=历史数据切换成员 */ + source: { + type: String, + value: 'addMember' } }, @@ -82,27 +103,55 @@ Component({ return Math.max(0, age) }, - /** 调接口获取可选成员列表 */ + /** 调接口获取可选成员列表,根据 source 调不同接口 */ _fetchMembers() { const userInfo = wx.getStorageSync('userInfo') as { userId?: string } | null - const sn = lefuService.deviceInfo?.serialNumber ?? '' - get('weighingScale/v3/select/addMembers/user', { - userId: userInfo?.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 }) - }) + 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() + }) + } }, /** 点击遮罩关闭 */ diff --git a/miniprogram/components/selectMemberDrawer/selectMemberDrawer.wxml b/miniprogram/components/selectMemberDrawer/selectMemberDrawer.wxml index de2307d..55d955e 100644 --- a/miniprogram/components/selectMemberDrawer/selectMemberDrawer.wxml +++ b/miniprogram/components/selectMemberDrawer/selectMemberDrawer.wxml @@ -21,33 +21,43 @@ - - - - - - - - - - + + + + + + + + + + + - - - {{ item.name }} - {{ item.gender }}·{{ item.age }}岁 + + + {{ item.name }} + {{ item.gender }}·{{ item.age }}岁 + + + + + + + {{ item.height }}cm - - + + + + + - - {{ item.height }}cm - - - - - - + + + + + 暂无可选成员 + + diff --git a/miniprogram/pages/data/data.json b/miniprogram/pages/data/data.json index a97367d..cf12031 100644 --- a/miniprogram/pages/data/data.json +++ b/miniprogram/pages/data/data.json @@ -1,3 +1,5 @@ { - "usingComponents": {} + "usingComponents": { + "select-member-drawer": "/components/selectMemberDrawer/selectMemberDrawer" + } } diff --git a/miniprogram/pages/data/data.ts b/miniprogram/pages/data/data.ts index 48bad4b..7643579 100644 --- a/miniprogram/pages/data/data.ts +++ b/miniprogram/pages/data/data.ts @@ -1,8 +1,5 @@ import { get } from '../../utils/request/index' -/** 加载状态机 */ -type LoadStatus = 'idle' | 'loading' | 'loaded' - /** 接口 type 参数:0=全部 1=近7天 2=近30天 3=近3月 */ type RangeType = 0 | 1 | 2 | 3 @@ -69,7 +66,6 @@ function calcAge(birthday: string): number { Page({ data: { - status: 'idle' as LoadStatus, activeType: 1 as RangeType, rangeTabs: [ { key: 1, label: '近7天' }, @@ -85,18 +81,19 @@ Page({ pageNo: 1, total: 0, hasMore: false, - hasData: false, refresherTriggered: false, + showSelectDrawer: false, }, onLoad() { const raw = wx.getStorageSync('userInfo') as StorageUserInfo | null if (!raw?.userId) return + const storedUserId = raw.userId const userInfo: PageUserInfo = { ...raw, sex_dictText: raw.sex === 1 ? '男' : raw.sex === 2 ? '女' : '', age: calcAge(raw.birthday), - isSelf: String(raw.relationType ?? '') === '1', + isSelf: raw.userId === storedUserId, } this.setData({ userInfo }) this.loadData() @@ -146,12 +143,11 @@ Page({ records, total, hasMore: records.length < total, - hasData: records.length > 0, }) }) .finally(() => { wx.hideLoading() - this.setData({ status: 'loaded', refresherTriggered: false }) + this.setData({ refresherTriggered: false }) }) }, @@ -213,8 +209,45 @@ Page({ }) }, - /** 切换成员占位 */ + /** 打开切换成员抽屉 */ onTapSwitchMember() { - wx.showToast({ title: '切换成员', icon: 'none' }) + this.setData({ showSelectDrawer: true }) + }, + + /** 抽屉关闭 */ + onCloseDrawer() { + this.setData({ showSelectDrawer: false }) + }, + + /** 选中成员后更新 userInfo 并重新请求数据 */ + onSelectMember(e: WechatMiniprogram.CustomEvent) { + const m = e.detail as { + userId?: string + id: string + name: string + gender: '男' | '女' + age: number + height: number + sex?: number + birthday?: string + relationType?: number | string | null + avatar?: string + } + const selectedUserId = m.userId ?? m.id + const storedUserId = (wx.getStorageSync('userInfo') as StorageUserInfo | null)?.userId ?? '' + const userInfo: PageUserInfo = { + userId: selectedUserId, + realname: m.name, + sex: m.sex ?? (m.gender === '男' ? 1 : 2), + height: m.height, + birthday: m.birthday ?? '', + avatar: m.avatar ?? null, + relationType: m.relationType ?? null, + sex_dictText: m.gender, + age: m.age, + isSelf: selectedUserId === storedUserId, + } + this.setData({ showSelectDrawer: false, userInfo }) + this.loadData() }, }) diff --git a/miniprogram/pages/data/data.wxml b/miniprogram/pages/data/data.wxml index 3f418cf..1b9ef92 100644 --- a/miniprogram/pages/data/data.wxml +++ b/miniprogram/pages/data/data.wxml @@ -69,7 +69,7 @@ - + @@ -85,7 +85,7 @@ - + @@ -96,3 +96,10 @@ + + diff --git a/miniprogram/pages/home/home.ts b/miniprogram/pages/home/home.ts index 4446f96..f50fc30 100644 --- a/miniprogram/pages/home/home.ts +++ b/miniprogram/pages/home/home.ts @@ -1,8 +1,4 @@ -import { mockLatestRecord } from '../../mock/home.mock' -import type { WeightRecord } from '../../mock/home.mock' - -/** 加载状态机 */ -type LoadStatus = 'idle' | 'loading' | 'loaded' +import { get } from '../../utils/request/index' /** 设备信息 */ interface DeviceInfo { @@ -10,9 +6,57 @@ interface DeviceInfo { connected: boolean } +/** GET /weighingScale/v3/getMeasureHistory result 结构 */ +interface MeasureHistoryVO { + recordId: string + height: number + weight: number + weightChange: number + bmi: number + bmiType: string + standardWeight: number + fatRate: number + fatValue: number + basalMetabolism: number + examTime: string + sn: string + userInfo: { + realname: string + sex: number + [key: string]: any + } | null +} + +/** 页面渲染用测量记录 */ +interface WeightRecord { + weight: number + weightDecimal: string + date: string + diff: number + height: number + bmi: number + bmiLabel: string + stdWeight: number + bodyFat: number + bodyFatMass: number + bmr: number +} + +/** 缓存中的用户信息 */ +interface StorageUserInfo { + userId: string + [key: string]: any +} + +/** 将体重数字拆成整数 + 小数字符串 */ +function splitWeight(weight: number): { int: number; decimal: string } { + const str = weight.toFixed(2) + const [intPart, decPart] = str.split('.') + return { int: Number(intPart), decimal: `.${decPart}` } +} + Page({ data: { - status: 'idle' as LoadStatus, hasData: false, device: { name: '智能体重秤', @@ -25,13 +69,6 @@ Page({ this.loadData() }, - onReady() {}, - onShow() {}, - onHide() {}, - onUnload() {}, - onPullDownRefresh() {}, - onReachBottom() {}, - onShareAppMessage(): WechatMiniprogram.Page.ICustomShareContent { return { title: '智能蓝牙秤', @@ -40,17 +77,40 @@ Page({ } }, - /** 加载首页数据(当前使用 mock,后续替换为真实接口) */ + /** 拉取最新一次测量记录 */ loadData() { - this.setData({ status: 'loading' }) - // 模拟异步加载 - setTimeout(() => { - this.setData({ - status: 'loaded', - hasData: true, - record: mockLatestRecord, + const raw = wx.getStorageSync('userInfo') as StorageUserInfo | null + if (!raw?.userId) return + + wx.showLoading({ title: '加载中...', mask: true }) + get('weighingScale/v3/getMeasureHistory', { + userId: raw.userId, + }, { loading: false }) + .then((res: any) => { + const d: MeasureHistoryVO = res.result + if (!d) { + this.setData({ hasData: false, record: null }) + return + } + const { int, decimal } = splitWeight(d.weight ?? 0) + const record: WeightRecord = { + weight: int, + weightDecimal: decimal, + date: d.examTime ?? '', + diff: d.weightChange ?? 0, + height: d.height ?? 0, + bmi: d.bmi ?? 0, + bmiLabel: d.bmiType ?? '', + stdWeight: d.standardWeight ?? 0, + bodyFat: d.fatRate ?? 0, + bodyFatMass: d.fatValue ?? 0, + bmr: d.basalMetabolism ?? 0, + } + this.setData({ hasData: true, record }) + }) + .finally(() => { + wx.hideLoading() }) - }, 300) }, /** 跳转历史数据页 */ diff --git a/miniprogram/pages/home/home.wxml b/miniprogram/pages/home/home.wxml index 082cf67..e9f48c8 100644 --- a/miniprogram/pages/home/home.wxml +++ b/miniprogram/pages/home/home.wxml @@ -139,7 +139,7 @@ - + 暂无称重数据 diff --git a/miniprogram/pages/my/my.less b/miniprogram/pages/my/my.less index 35bd6fd..3e83bb6 100644 --- a/miniprogram/pages/my/my.less +++ b/miniprogram/pages/my/my.less @@ -20,10 +20,16 @@ .user-avatar { width: 120rpx; height: 120rpx; - border-radius: 16rpx; margin-right: 30rpx; + border-radius: 24rpx; + color: #FFFFFF; + font-size: 48rpx; + font-weight: bold; + line-height: 110rpx; + text-align: center; box-sizing: border-box; border: 5rpx solid #ffffff; + background-color: #1385FA; } .user-info { diff --git a/miniprogram/pages/my/my.ts b/miniprogram/pages/my/my.ts index bd65cf6..f430662 100644 --- a/miniprogram/pages/my/my.ts +++ b/miniprogram/pages/my/my.ts @@ -1,7 +1,48 @@ -Page({ - data: {}, +/** 缓存中的用户信息 */ +interface StorageUserInfo { + userId: string + realname: string + sex: number + height: number + birthday: string + [key: string]: any +} - onLoad() {}, +/** 页面展示用用户信息 */ +interface PageUserInfo { + realname: string + sex_dictText: '男' | '女' | '' + age: number + height: number +} + +/** 从生日字符串(YYYY-MM-DD)计算周岁 */ +function 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) +} + +Page({ + data: { + userInfo: null as PageUserInfo | null, + }, + + onLoad() { + const raw = wx.getStorageSync('userInfo') as StorageUserInfo | null + if (!raw?.userId) return + const userInfo: PageUserInfo = { + realname: raw.realname ?? '', + sex_dictText: raw.sex === 1 ? '男' : raw.sex === 2 ? '女' : '', + age: calcAge(raw.birthday), + height: raw.height ?? 0, + } + this.setData({ userInfo }) + }, onShareAppMessage(): WechatMiniprogram.Page.ICustomShareContent { return { diff --git a/miniprogram/pages/my/my.wxml b/miniprogram/pages/my/my.wxml index ffbcb37..d4c1154 100644 --- a/miniprogram/pages/my/my.wxml +++ b/miniprogram/pages/my/my.wxml @@ -4,15 +4,15 @@ - + {{ userInfo.realname[0] }}