refactor: 项目重构,仅保留 login 和 supplementPersonal 页面

删除 11 个旧页面、组件、lefu SDK、旧资源文件。
新增 request 封装(GET/POST/PUT)、api 层、utils/common 身份证工具。
重写 login(登录流程提取到 app.ts) 和 supplementPersonal(简化表单逻辑)。

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
17792275749
2026-08-10 14:21:00 +08:00
co-authored by Claude Sonnet 4.6
parent 439f560218
commit 83d909b95b
96 changed files with 370 additions and 9040 deletions
-4
View File
@@ -1,4 +0,0 @@
{
"usingComponents": {},
"navigationStyle": "custom"
}
-496
View File
@@ -1,496 +0,0 @@
.header {
width: 100%;
position: relative;
height: 450rpx;
margin-bottom: 25rpx;
.bg {
width: 100%;
height: 450rpx;
}
.device {
position: absolute;
z-index: 2;
top: 285rpx;
left: 60rpx;
right: 60rpx;
bottom: 0;
display: flex;
align-items: center;
.device-icon {
width: 90rpx;
height: 90rpx;
overflow: hidden;
border-radius: 24rpx;
margin-right: 24rpx;
}
.device-info {
flex: 1;
.device-name {
color: #FFFFFF;
font-size: 32rpx;
font-weight: 700;
line-height: 36rpx;
margin-bottom: 14rpx;
}
.device-status {
display: flex;
align-items: center;
.status-dot {
width: 12rpx;
height: 12rpx;
border-radius: 50%;
margin-right: 10rpx;
}
.dot-on {
background-color: #FFFFFF;
}
.dot-off {
background-color: rgba(255, 255, 255, 0.5);
}
.status-text {
color: #FFFFFF;
font-size: 28rpx;
line-height: 28rpx;
}
}
}
.device-switch {
color: #FFFFFF;
height: 48rpx;
padding: 0 20rpx;
font-size: 24rpx;
font-weight: 500;
line-height: 44rpx;
border-radius: 8rpx;
box-sizing: border-box;
border: 2rpx solid #FFFFFF;
}
}
}
.scrollViewContent {
width: 100%;
padding: 0 30rpx;
box-sizing: border-box;
/* ===== 最近测量卡 ===== */
.weight-card {
width: 100%;
position: relative;
margin-bottom: 24rpx;
padding: 2rpx 2rpx 50rpx;
border-radius: 24rpx;
box-sizing: border-box;
background-color: #FFFFFF;
/* 卡头(带渐变背景) */
.card-header {
width: 100%;
height: 88rpx;
padding-left: 30rpx;
padding-right: 10rpx;
box-sizing: border-box;
display: flex;
align-items: center;
margin-bottom: 18rpx;
justify-content: space-between;
background: linear-gradient(180deg, rgba(211, 233, 255, 0.6) 0%, rgba(252, 251, 253, 0.6) 100%);
.card-header-left {
display: flex;
align-items: center;
.card-title-bar {
width: 6rpx;
height: 24rpx;
border-radius: 3rpx;
background-color: #1385FA;
margin-right: 14rpx;
}
.card-title {
color: #252535;
font-size: 30rpx;
font-weight: 700;
line-height: 30rpx;
}
}
.card-header-right {
display: flex;
align-items: center;
.link-text {
color: #77849E;
font-size: 24rpx;
line-height: 24rpx;
}
.arrow {
padding-right: 40rpx;
box-sizing: border-box;
}
}
}
.card-content {
width: 100%;
padding: 0 30rpx;
box-sizing: border-box;
/* ===== 最近测量:体重主数据行 ===== */
.weight-row {
display: flex;
align-items: flex-end;
margin-bottom: 30rpx;
.weight-main {
flex: 1;
display: flex;
flex-direction: column;
.weight-num-wrap {
height: 96rpx;
display: flex;
margin-bottom: 20rpx;
align-items: baseline;
.weight-int {
color: #252535;
height: 96rpx;
font-size: 96rpx;
font-weight: bold;
line-height: 96rpx;
}
.weight-dec {
color: #252535;
font-size: 56rpx;
font-weight: bold;
line-height: 56rpx;
margin-right: 6rpx;
}
.weight-unit {
color: #808080;
font-size: 28rpx;
font-weight: bold;
line-height: 28rpx;
}
}
.weight-date {
color: #B6B6B6;
height: 24rpx;
font-size: 24rpx;
line-height: 24rpx;
}
}
/* 右侧变化量 */
.weight-diff {
width: 250rpx;
display: flex;
flex-direction: column;
align-items: flex-start;
.diff-num-wrap {
display: flex;
align-items: flex-end;
margin-bottom: 14rpx;
.diff-num {
height: 48rpx;
font-size: 48rpx;
font-weight: bold;
line-height: 48rpx;
margin-right: 6rpx;
}
.diff-unit {
position: relative;
color: #808080;
height: 28rpx;
font-weight: bold;
font-size: 28rpx;
line-height: 28rpx;
text {
position: absolute;
left: 0;
bottom: 42rpx;
}
}
/* 向下箭头(减轻) */
.arrow-down {
border-left: 10rpx solid transparent;
border-right: 10rpx solid transparent;
border-top: 16rpx solid #2AC79F;
}
/* 向上箭头(增重) */
.arrow-up {
border-left: 10rpx solid transparent;
border-right: 10rpx solid transparent;
border-bottom: 16rpx solid #FF4D4F;
}
.diff-down {
color: #2AC79F;
}
.diff-up {
color: #FF4D4F;
}
.diff-neutral {
color: #000000;
}
}
.diff-label {
color: #B6B6B6;
font-size: 24rpx;
line-height: 28rpx;
margin-top: 8rpx;
}
}
}
/* 分割线 */
.card-divider {
width: 100%;
height: 2rpx;
background-color: #EAECF1;
margin-bottom: 35rpx;
}
/* 身高 / BMI / 标准体重 指标行 */
.metrics-row {
display: flex;
padding: 0 10rpx;
justify-content: space-between;
.metric-col {
display: flex;
flex-direction: column;
.metric-label {
color: #808080;
height: 30rpx;
display: flex;
font-size: 26rpx;
line-height: 30rpx;
margin-bottom: 20rpx;
.metric-label-text {
color: #808080;
height: 30rpx;
font-size: 26rpx;
line-height: 30rpx;
margin-right: 6rpx;
}
.metric-label-value {
color: #FFFFFF;
height: 30rpx;
padding: 0 6rpx;
font-size: 18rpx;
line-height: 30rpx;
background-color: #2AC79F;
border-radius: 8rpx;
}
}
/* BMI 行(标签 + badge 并排) */
.metric-label-row {
height: 30rpx;
display: flex;
align-items: center;
margin-bottom: 20rpx;
.metric-label {
margin-bottom: 0;
}
/* BMI 标准/偏高 badge */
.bmi-badge {
height: 30rpx;
padding: 0 10rpx;
margin-left: 10rpx;
font-size: 18rpx;
line-height: 30rpx;
border-radius: 8rpx;
color: #FFFFFF;
background-color: #2AC79F;
}
}
.metric-value-row {
display: flex;
align-items: baseline;
.metric-value {
color: #252535;
height: 44rpx;
font-size: 44rpx;
font-weight: 700;
line-height: 44rpx;
margin-right: 6rpx;
}
.metric-unit {
color: #252535;
height: 26rpx;
font-size: 26rpx;
font-weight: bold;
line-height: 26rpx;
}
}
}
}
}
.card-lianjie {
position: absolute;
right: 24rpx;
width: 32rpx;
height: 84rpx;
bottom: -55rpx;
}
}
/* ===== 详细数据卡 ===== */
.detail-card {
width: 100%;
margin-bottom: 24rpx;
padding: 2rpx 2rpx 30rpx;
border-radius: 24rpx;
box-sizing: border-box;
background-color: #FFFFFF;
/* 卡头(带渐变背景) */
.card-header {
width: 100%;
height: 88rpx;
padding-left: 30rpx;
padding-right: 50rpx;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
.card-header-left {
display: flex;
align-items: center;
.card-title-bar {
width: 6rpx;
height: 24rpx;
border-radius: 3rpx;
background-color: #1385FA;
margin-right: 14rpx;
}
.card-title {
color: #252535;
font-size: 30rpx;
font-weight: 700;
line-height: 30rpx;
}
}
.card-header-right {
display: flex;
align-items: center;
.link-text {
color: #77849E;
height: 24rpx;
font-size: 24rpx;
line-height: 24rpx;
}
}
}
/* ===== 详细数据:三格 ===== */
.detail-grid {
display: flex;
padding: 0 30rpx;
justify-content: space-between;
.detail-item {
width: 195rpx;
padding: 24rpx;
box-sizing: border-box;
border-radius: 16rpx;
background-color: #F3F4F6;
display: flex;
flex-direction: column;
.detail-label {
color: #808080;
font-size: 24rpx;
line-height: 24rpx;
margin-bottom: 30rpx;
}
.detail-value-row {
display: flex;
align-items: baseline;
.detail-value {
color: #252535;
height: 44rpx;
font-size: 44rpx;
font-weight: bold;
line-height: 44rpx;
margin-right: 2rpx;
}
.detail-unit {
color: #252535;
height: 26rpx;
font-size: 26rpx;
line-height: 26rpx;
}
}
}
}
}
/* ===== 空态 ===== */
.empty-state {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
padding-top: 280rpx;
.empty-icon {
width: 193rpx;
height: 138rpx;
margin-bottom: 40rpx;
border-radius: 20rpx;
}
.empty-text {
color: #808080;
height: 30rpx;
font-size: 30rpx;
line-height: 30rpx;
}
}
}
-174
View File
@@ -1,174 +0,0 @@
import { get } from '../../utils/request/index'
import { lefuService } from '../../lefu/index'
/** 设备信息 */
interface DeviceInfo {
name: string
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
}
/** 将体重数字拆成整数 + 小数字符串 */
const splitWeight = (weight: number): { int: number; decimal: string } => {
const str = weight.toFixed(2)
const [intPart, decPart] = str.split('.')
return { int: Number(intPart), decimal: `.${decPart}` }
}
Page({
_otaChecked: false as boolean,
data: {
hasData: false,
device: {
name: '智能体重秤',
connected: false,
} as DeviceInfo,
record: null as WeightRecord | null,
},
onLoad() {
lefuService.onDeviceInfo((info) => {
this.setData({ 'device.name': info.modelNumber ?? '智能体重秤' })
})
lefuService.onDeviceConnect(() => {
this.setData({ 'device.connected': true })
this._checkOta()
})
lefuService.onDisconnected(() => {
this.setData({ 'device.connected': false })
})
},
onShow() {
// 每次进入 tab 同步最新设备状态
const connected = lefuService.isConnected
this.setData({
'device.connected': connected,
'device.name': lefuService.deviceInfo?.modelNumber ?? '智能体重秤',
})
// 进来时设备已连接(如热启动/切 tab 回来),onDeviceConnect 不会再触发,需在此补一次检测
if (connected && !this._otaChecked) {
this._checkOta()
}
// 断连时自动扫描重连,重连成功后 onDeviceConnect 回调会触发 OTA 检测
if (!connected) {
lefuService.autoConnect()
}
this.loadData()
},
onUnload() {
lefuService.onDeviceConnect(() => {})
lefuService.onDisconnected(() => {})
lefuService.onDeviceInfo(() => {})
},
onShareAppMessage(): WechatMiniprogram.Page.ICustomShareContent {
return {
title: '智能蓝牙秤',
path: '/pages/home/home',
imageUrl: '/images/share/share.jpg',
}
},
/** 拉取最新一次测量记录 */
loadData() {
const raw = wx.getStorageSync('userInfo') as StorageUserInfo | null
if (!raw?.userId) return
get<MeasureHistoryVO>('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 })
})
},
/** OTA 固件检测,连接成功后自动调用,有新版本直接升级,整个页面生命周期只触发一次 */
_checkOta() {
if (this._otaChecked) return
this._otaChecked = true
lefuService.checkAndUpgrade()
.then(() => {
wx.showLoading({ title: '加载中...', mask: true })
setTimeout(() => {
wx.hideLoading()
// 升级完成后设备重启,旧连接与订阅失效,重新扫描连接
this.setData({ 'device.connected': false })
lefuService.autoConnect()
}, 15000)
})
.catch(() => {})
},
/** 跳转历史数据页 */
onTapHistory() {
wx.switchTab({ url: '/pages/data/data' })
},
/** 跳转设备列表页 */
onTapSwitchDevice() {
wx.switchTab({ url: '/pages/equipment/equipment' })
},
})
-148
View File
@@ -1,148 +0,0 @@
<scroll-view class="scrollView" scroll-y>
<view class="header">
<view class="bg">
<image src="/images/home/header.jpg" mode=""/>
</view>
<view class="device">
<image class="device-icon" src="/images/device/{{ device.name }}.png" mode="aspectFit"></image>
<view class="device-info">
<view class="device-name">{{ device.name }}</view>
<view class="device-status">
<view class="status-dot {{ device.connected ? 'dot-on' : 'dot-off' }}"></view>
<view class="status-text">{{ device.connected ? '设备已连接' : '未连接' }}</view>
</view>
</view>
<view class="device-switch" bind:tap="onTapSwitchDevice">切换设备</view>
</view>
</view>
<view class="scrollViewContent">
<!-- 有数据态 -->
<block wx:if="{{ hasData }}">
<!-- 最近测量卡 -->
<view class="weight-card">
<!-- 卡头 -->
<view class="card-header">
<view class="card-header-left">
<view class="card-title-bar"></view>
<view class="card-title">最近测量</view>
</view>
<view class="card-header-right" bind:tap="onTapHistory">
<view class="link-text">查看历史</view>
<view class="arrow"></view>
</view>
</view>
<view class="card-content">
<!-- 体重主数据行 -->
<view class="weight-row">
<view class="weight-main">
<view class="weight-num-wrap">
<text class="weight-int">{{ record.weight }}</text>
<text class="weight-dec">{{ record.weightDecimal }}</text>
<text class="weight-unit">kg</text>
</view>
<view class="weight-date">{{ record.date }}</view>
</view>
<view class="weight-diff">
<view class="diff-num-wrap">
<view class="diff-num {{ record.diff < 0 ? 'diff-down' : (record.diff > 0 ? 'diff-up' : 'diff-neutral') }}">{{ record.diff < 0 ? -record.diff : record.diff }}</view>
<view class="diff-unit">
kg
<text wx:if="{{ record.diff !== 0 }}" class="diff-arrow {{ record.diff < 0 ? 'arrow-down' : 'arrow-up' }}"></text>
</view>
</view>
<view class="diff-label">{{ record.diff < 0 ? '体重较上次减轻' : (record.diff > 0 ? '体重较上次增加' : '与上次持平') }}</view>
</view>
</view>
<!-- 分割线 -->
<view class="card-divider"></view>
<!-- 身高 / BMI / 标准体重 指标行 -->
<view class="metrics-row">
<view class="metric-col">
<view class="metric-label">
<view class="metric-label-text">身高</view>
</view>
<view class="metric-value-row">
<text class="metric-value">{{ record.height }}</text>
<text class="metric-unit">cm</text>
</view>
</view>
<view class="metric-col">
<view class="metric-label">
<view class="metric-label-text">BMI</view>
<view class="metric-label-value">{{ record.bmiLabel }}</view>
</view>
<view class="metric-value-row">
<text class="metric-value">{{ record.bmi }}</text>
</view>
</view>
<view class="metric-col">
<view class="metric-label">
<view class="metric-label-text">标准体重</view>
</view>
<view class="metric-value-row">
<text class="metric-value">{{ record.stdWeight }}</text>
<text class="metric-unit">kg</text>
</view>
</view>
</view>
</view>
<view class="card-lianjie">
<image src="/images/home/lianjie.png" mode=""/>
</view>
</view>
<!-- 详细数据卡 -->
<view class="detail-card">
<!-- 卡头 -->
<view class="card-header">
<view class="card-header-left">
<view class="card-title-bar"></view>
<view class="card-title">详细数据</view>
</view>
</view>
<!-- 三格数据 -->
<view class="detail-grid">
<view class="detail-item">
<view class="detail-label">体脂率</view>
<view class="detail-value-row">
<text class="detail-value">{{ record.bodyFat }}</text>
<text class="detail-unit">%</text>
</view>
</view>
<view class="detail-item">
<view class="detail-label">体脂肪</view>
<view class="detail-value-row">
<text class="detail-value">{{ record.bodyFatMass }}</text>
<text class="detail-unit">kg</text>
</view>
</view>
<view class="detail-item">
<view class="detail-label">基础代谢</view>
<view class="detail-value-row">
<text class="detail-value">{{ record.bmr }}</text>
<text class="detail-unit">kcal</text>
</view>
</view>
</view>
</view>
</block>
<!-- 空态(无称重数据) -->
<block wx:else>
<view class="empty-state">
<view class="empty-icon">
<image src="/images/home/noData.png" mode="aspectFit"/>
</view>
<view class="empty-text">暂无称重数据</view>
</view>
</block>
</view>
</scroll-view>