import { get } from '../../utils/request/index' import { calcAge } from '../../utils/idCard/index' import type { UserInfo } from '../../api/index' type RangeType = 1 | 2 | 3 interface RangeTab { key: RangeType label: string } /** 页面展示用用户信息 */ interface PageUserInfo { userId: string realname: string sex: number sex_dictText: string age: number height: number avatar: string | null birthday: string relationType: number | string | null isSelf: boolean } /** GET /weighingScale/v3/getMeasureStatistics 返回结构 */ interface MeasureStatistics { maxWeight: number minWeight: number avgWeight: number weightChange: number } /** GET /weighingScale/v3/getMeasureHistoryPage records 单条 */ interface MeasureRecord { recordId: string examTime: string weight: number bmi: number fatRate: number } /** GET /weighingScale/v3/getMeasureHistoryPage 返回结构 */ interface MeasureHistoryPageResult { records: MeasureRecord[] total: number } /** 切换用户抽屉 select 事件 detail */ interface MemberSelectDetail { id: string name: string gender: '男' | '女' age: number height: number userId?: string sex?: number birthday?: string relationType?: number | string | null avatar?: string } /** 统计空态默认值 */ const EMPTY_STATS: MeasureStatistics = { maxWeight: 0, minWeight: 0, avgWeight: 0, weightChange: 0, } Page({ data: { activeType: 1 as RangeType, rangeTabs: [ { key: 1, label: '近7天' }, { key: 2, label: '近30天' }, { key: 3, label: '近3月' }, ] as RangeTab[], userInfo: null as PageUserInfo | null, stats: EMPTY_STATS as MeasureStatistics, records: [] as MeasureRecord[], pageNo: 1, total: 0, hasMore: false, refresherTriggered: false, showSelectDrawer: false, }, onLoad() { const raw = wx.getStorageSync('userInfo') as UserInfo | null if (!raw?.userId) return this.setData({ userInfo: this._buildSelfUserInfo(raw) }) this.loadData() }, /** 由缓存用户信息构建「本人」展示信息 */ _buildSelfUserInfo(raw: UserInfo): PageUserInfo { return { userId: raw.userId, realname: raw.realname ?? '', sex: raw.sex, sex_dictText: raw.sex === 1 ? '男' : raw.sex === 2 ? '女' : '', age: calcAge(raw.birthday), height: raw.height ?? 0, avatar: raw.avatar ?? null, birthday: raw.birthday ?? '', relationType: raw.relationType ?? null, isSelf: true, } }, /** 重置分页,并行拉统计 + 第一页列表 */ loadData() { const userInfo = this.data.userInfo if (!userInfo?.userId) return this.setData({ pageNo: 1, records: [] }) const statsReq = get('weighingScale/v3/getMeasureStatistics', { userId: userInfo.userId, type: this.data.activeType, }, { loading: false }) const pageReq = get('weighingScale/v3/getMeasureHistoryPage', { userId: userInfo.userId, type: this.data.activeType, pageNo: 1, pageSize: 10, }, { loading: false }) wx.showLoading({ title: '加载中...', mask: true }) Promise.all([statsReq, pageReq]) .then(([statsRes, pageRes]) => { const rawStats = statsRes.result const stats: MeasureStatistics = rawStats ? { maxWeight: rawStats.maxWeight ?? 0, minWeight: rawStats.minWeight ?? 0, avgWeight: rawStats.avgWeight ?? 0, weightChange: rawStats.weightChange ?? 0, } : EMPTY_STATS const page = pageRes.result ?? {} const records: MeasureRecord[] = (page.records ?? []).map((r) => ({ recordId: r.recordId ?? '', examTime: r.examTime ?? '', weight: r.weight ?? 0, bmi: r.bmi ?? 0, fatRate: r.fatRate ?? 0, })) const total = page.total ?? 0 this.setData({ stats, records, total, hasMore: records.length < total, }) }) .catch(() => { this.setData({ stats: EMPTY_STATS, records: [], total: 0, hasMore: false }) }) .finally(() => { wx.hideLoading() this.setData({ refresherTriggered: false }) }) }, /** scroll-view 触底,加载下一页 */ onScrollToLower() { if (!this.data.hasMore) return const userInfo = this.data.userInfo if (!userInfo?.userId) return const nextPage = this.data.pageNo + 1 wx.showLoading({ title: '加载中...', mask: true }) get('weighingScale/v3/getMeasureHistoryPage', { userId: userInfo.userId, type: this.data.activeType, pageNo: nextPage, pageSize: 10, }, { loading: false }) .then((res) => { const page = res.result ?? {} const newRecords: MeasureRecord[] = (page.records ?? []).map((r) => ({ recordId: r.recordId ?? '', examTime: r.examTime ?? '', weight: r.weight ?? 0, bmi: r.bmi ?? 0, fatRate: r.fatRate ?? 0, })) const allRecords = [...this.data.records, ...newRecords] this.setData({ records: allRecords, pageNo: nextPage, hasMore: allRecords.length < this.data.total, }) }) .catch(() => { wx.showToast({ title: '加载失败,请重试', icon: 'none' }) }) .finally(() => { wx.hideLoading() }) }, /** scroll-view 下拉刷新 */ onRefresh() { this.setData({ refresherTriggered: true }) this.loadData() }, /** 切换时间范围 Tab */ onTapRange(e: WechatMiniprogram.TouchEvent) { const key = Number(e.currentTarget.dataset.key) as RangeType if (key === this.data.activeType) return this.setData({ activeType: key }) this.loadData() }, /** 点击记录行,跳转测量报告 */ onTapRecord(e: WechatMiniprogram.TouchEvent) { const recordId = e.currentTarget.dataset.recordId as string const userId = this.data.userInfo?.userId ?? '' wx.navigateTo({ url: `/pages/detailedReport/detailedReport?recordId=${recordId}&userId=${userId}`, }) }, /** 打开切换用户抽屉 */ onTapSwitchMember() { this.setData({ showSelectDrawer: true }) }, /** 抽屉关闭 */ onCloseDrawer() { this.setData({ showSelectDrawer: false }) }, /** 选中用户后更新 userInfo 并重新请求数据 */ onSelectMember(e: WechatMiniprogram.CustomEvent) { const m = e.detail as MemberSelectDetail if (!m.userId) { wx.showToast({ title: '用户信息异常', icon: 'none' }) return } const storedUserId = (wx.getStorageSync('userInfo') as UserInfo | null)?.userId ?? '' const userInfo: PageUserInfo = { userId: m.userId, realname: m.name, sex: m.sex ?? (m.gender === '男' ? 1 : 2), sex_dictText: m.gender, age: m.age, height: m.height, avatar: m.avatar ?? null, birthday: m.birthday ?? '', relationType: m.relationType ?? null, isSelf: m.userId === storedUserId, } this.setData({ showSelectDrawer: false, userInfo }) this.loadData() }, })