- service 恢复 clearDeviceMembers/syncMembersToDevice,操作中断开立即失败 - syncMembersToDevice 只负责逐个下发,参数由业务层组装 - _doReconnect 增加蓝牙不可用判断 - userManagement 接入真实同步(连接状态实时同步 + 进度弹框) - equipment 页增加用户管理入口 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
170 lines
5.9 KiB
TypeScript
170 lines
5.9 KiB
TypeScript
import { leFuService } from '../../lefu/index'
|
|
import type { SyncUserData } from '../../lefu/index'
|
|
|
|
/** 连接状态订阅句柄 */
|
|
let unsubDeviceConnect: (() => void) | null = null
|
|
let unsubDisconnected: (() => void) | null = null
|
|
/** 同步完成关闭弹框定时器 */
|
|
let syncCloseTimer: number | null = null
|
|
|
|
Page({
|
|
data: {
|
|
device: {
|
|
name: '智能体重秤',
|
|
connected: false,
|
|
model: '',
|
|
serial: ''
|
|
},
|
|
memberCount: 5,
|
|
hasData: true,
|
|
self: {
|
|
name: '张晓敏',
|
|
gender: '男',
|
|
age: 36,
|
|
height: 172,
|
|
sync: '已同步',
|
|
syncClass: 'done'
|
|
},
|
|
groups: [
|
|
{
|
|
title: '员工',
|
|
members: [
|
|
{ id: 2, name: '李建国', gender: '男', age: 36, height: 182, sync: '已同步', syncClass: 'done' },
|
|
{ id: 5, name: '赵明亮', gender: '男', age: 32, height: 172, sync: '已同步', syncClass: 'done' }
|
|
]
|
|
},
|
|
{
|
|
title: '家庭用户',
|
|
members: [
|
|
{ id: 3, name: '吉夏', gender: '女', age: 28, height: 165, sync: '已同步', syncClass: 'done' },
|
|
{ id: 4, name: '张雪', gender: '女', age: 32, height: 158, sync: '未同步', syncClass: 'pending' }
|
|
]
|
|
}
|
|
],
|
|
syncShow: false,
|
|
syncPercent: 0,
|
|
syncStatus: ''
|
|
},
|
|
|
|
onLoad() {
|
|
this._updateDeviceInfo()
|
|
this._subscribeDeviceState()
|
|
},
|
|
|
|
onUnload() {
|
|
unsubDeviceConnect?.()
|
|
unsubDisconnected?.()
|
|
unsubDeviceConnect = null
|
|
unsubDisconnected = null
|
|
if (syncCloseTimer !== null) { clearTimeout(syncCloseTimer); syncCloseTimer = null }
|
|
},
|
|
|
|
/** 从 service 读取设备信息 + 连接状态 */
|
|
_updateDeviceInfo() {
|
|
const info = leFuService.deviceInfo
|
|
this.setData({
|
|
'device.name': info?.modelNumber || '智能体重秤',
|
|
'device.model': info?.modelNumber || '',
|
|
'device.serial': info?.serialNumber || '',
|
|
'device.connected': leFuService.isConnected,
|
|
})
|
|
},
|
|
|
|
/** 订阅连接状态,实时同步设备卡 */
|
|
_subscribeDeviceState() {
|
|
unsubDeviceConnect?.()
|
|
unsubDisconnected?.()
|
|
unsubDeviceConnect = leFuService.onDeviceConnect(() => {
|
|
this._updateDeviceInfo()
|
|
})
|
|
unsubDisconnected = leFuService.onDisconnected(() => {
|
|
this.setData({ 'device.connected': false })
|
|
})
|
|
},
|
|
|
|
/** 校验设备连接状态:未连接则同步状态 + 提示 */
|
|
_ensureConnected(): boolean {
|
|
if (leFuService.isConnected) return true
|
|
this.setData({ 'device.connected': false })
|
|
wx.showToast({ title: '请先连接设备', icon: 'none' })
|
|
return false
|
|
},
|
|
|
|
/** 同步用户至设备 */
|
|
onTapSync() {
|
|
if (!this._ensureConnected()) return
|
|
|
|
// 组装所有用户(self 第一个,作为主用户),性别:男=1 女=0
|
|
const allUsers = [
|
|
{
|
|
id: 'self', name: this.data.self.name,
|
|
gender: this.data.self.gender === '男' ? 1 : 0,
|
|
age: this.data.self.age, height: this.data.self.height,
|
|
},
|
|
...this.data.groups.flatMap(g => g.members.map(m => ({
|
|
id: String(m.id), name: m.name,
|
|
gender: m.gender === '男' ? 1 : 0, age: m.age, height: m.height,
|
|
}))),
|
|
]
|
|
const mainUser = allUsers[0]
|
|
// 组装下发参数(SyncUserData),第一个为主用户(memberID 为空)
|
|
const syncDataList: SyncUserData[] = allUsers.map((user, index) => ({
|
|
userID: mainUser.id,
|
|
userName: user.name,
|
|
memberID: index === 0 ? '' : user.id,
|
|
age: user.age,
|
|
gender: user.gender,
|
|
height: user.height,
|
|
isAthleteMode: 0,
|
|
deviceHeaderIndex: index,
|
|
currentWeight: '',
|
|
targetWeight: '',
|
|
idealWeight: '',
|
|
recentData: [],
|
|
}))
|
|
|
|
// 阶段1:清空设备用户,进度 0% → 100%
|
|
this.setData({ syncShow: true, syncPercent: 0, syncStatus: '正在清空设备用户...' })
|
|
leFuService.clearDeviceMembers()
|
|
.then(() => {
|
|
this.setData({ syncPercent: 100, syncStatus: '清空完成' })
|
|
// 阶段2:下发用户,进度从 0% 重新开始
|
|
this.setData({ syncPercent: 0, syncStatus: '正在同步信息,请勿离开...' })
|
|
return leFuService.syncMembersToDevice(syncDataList, (current, total) => {
|
|
this.setData({
|
|
syncPercent: Math.round((current / total) * 100),
|
|
syncStatus: `正在同步 ${current}/${total}...`,
|
|
})
|
|
})
|
|
})
|
|
.then(() => {
|
|
this.setData({ syncPercent: 100, syncStatus: '同步完成' })
|
|
wx.showToast({ title: '用户同步成功', icon: 'success' })
|
|
if (syncCloseTimer !== null) { clearTimeout(syncCloseTimer); syncCloseTimer = null }
|
|
syncCloseTimer = setTimeout(() => {
|
|
syncCloseTimer = null
|
|
this.setData({ syncShow: false })
|
|
}, 1000)
|
|
})
|
|
.catch((err: Error) => {
|
|
this.setData({ syncShow: false })
|
|
wx.showToast({ title: err.message || '同步失败,请重试', icon: 'none' })
|
|
})
|
|
},
|
|
|
|
/** 添加用户 */
|
|
onTapAddUser() {
|
|
wx.navigateTo({ url: '/pages/addUser/addUser' })
|
|
},
|
|
|
|
/** 一键添加本人 */
|
|
onTapAddSelf() {
|
|
// 一键添加本人(待接入)
|
|
},
|
|
|
|
/** 添加新用户 */
|
|
onTapAddNew() {
|
|
wx.navigateTo({ url: '/pages/addUser/addUser' })
|
|
}
|
|
})
|