Files
bodyWeight/miniprogram/pages/connectedWifi/connectedWifi.ts
T
17792275749andClaude Opus 4.7 ea52c495f6 [AI Generated]: feat(device): 配网/绑定后下发主用户到设备并兜底超时
- configWifi 加 20s 超时与 settled 互锁,避免回调不触发导致 loading 死转
- supplementPersonal 提交后、connectedWifi 二次配网确认后均下发主用户
- 设备成员唯一标识从 idCard 切换为 userId,清理 MemberDisplay.idCard

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 15:56:44 +08:00

175 lines
5.8 KiB
TypeScript

import { lefuService } from '../../lefu/index'
import type { LeFuWifiItem, DeviceMember } from '../../lefu/index'
/** 本地 userInfo 关键字段,用于下发主用户到新设备 */
interface StoredUserInfo {
userId: string
realname: string
sex: number
height: number
birthday: string
}
/** 从生日字符串(YYYY-MM-DD)计算周岁 */
const calcAge = (birthday: string): number => {
if (!birthday) return 0
const [y, m, d] = birthday.split('-').map(Number)
if (!y || !m || !d) return 0
const now = new Date()
let age = now.getFullYear() - y
if (now.getMonth() + 1 < m || (now.getMonth() + 1 === m && now.getDate() < d)) age -= 1
return Math.max(0, age)
}
interface WifiItem {
ssid: string
connected: boolean
}
type WifiStatus = 'idle' | 'searching' | 'list' | 'empty' | 'password' | 'configuring'
type BleStatus = 'connected' | 'failed' | 'connecting'
Page({
data: {
status: 'idle' as WifiStatus,
deviceName: '智能体重秤',
bleStatus: 'connecting' as BleStatus,
wifiList: [] as WifiItem[],
hasConnected: false,
selectedSsid: '',
selectWifiPWD: '',
type: true,
},
_toBleStatus(state: string): BleStatus {
const bs = lefuService.BLUE_STATE
if (state === bs.CONNECTSUCCESS || state === bs.WIFISUCCESS) return 'connected'
if (state === bs.CONNECTFAILED) return 'failed'
return 'connecting'
},
onLoad() {
// 尽早注册 deviceInfo 回调,防止 onShow 前已触发而错过
lefuService.onDeviceInfo((info) => {
this.setData({ deviceName: info.modelNumber })
})
this.setData({
bleStatus: this._toBleStatus(lefuService.connectState),
deviceName: lefuService.deviceInfo?.modelNumber ?? '智能体重秤',
})
this.onStartSearch()
},
onShow() {
lefuService.onConnectState((state) => {
const bs = lefuService.BLUE_STATE
if (state === bs.CONNECTSUCCESS || state === bs.WIFISUCCESS || state === bs.CONNECTFAILED) {
this.setData({ bleStatus: this._toBleStatus(state) })
}
})
},
onUnload() {
wx.hideLoading()
if (this.data.status === 'configuring') {
lefuService.disconnect()
}
},
onStartSearch() {
this.setData({ status: 'searching', wifiList: [] })
wx.showLoading({ title: '正在获取 WiFi 列表...', mask: true })
lefuService.getWifiList()
.then((items: LeFuWifiItem[]) => {
wx.hideLoading()
if (!items.length) {
this.setData({ status: 'empty' })
return
}
this.setData({
status: 'list',
wifiList: items.map(item => ({ ssid: item.ssid, connected: false })),
})
})
.catch(() => {
wx.hideLoading()
this.setData({ status: 'empty' })
})
},
onRefresh() {
this.onStartSearch()
},
onTapWifi(e: WechatMiniprogram.TouchEvent) {
const ssid = e.currentTarget.dataset.ssid as string
const target = this.data.wifiList.find(item => item.ssid === ssid)
if (!target || target.connected) return
this.setData({ status: 'password', selectedSsid: ssid, selectWifiPWD: '', type: true })
},
passwordInput(e: WechatMiniprogram.Input) {
this.setData({ selectWifiPWD: e.detail.value })
},
inputTypeChange() {
this.setData({ type: !this.data.type })
},
onCancelPwd() {
this.setData({ status: 'list', selectedSsid: '', selectWifiPWD: '' })
},
onConfirmPwd() {
const { selectedSsid, selectWifiPWD } = this.data
if (!selectedSsid) return
this.setData({ status: 'configuring' })
wx.showLoading({ title: '正在配网...', mask: true })
lefuService.configWifi(selectedSsid, selectWifiPWD)
.then(() => {
wx.hideLoading()
this.setData({
status: 'list',
wifiList: this.data.wifiList.map(item => ({ ...item, connected: item.ssid === selectedSsid })),
hasConnected: true,
selectedSsid: '',
selectWifiPWD: '',
})
})
.catch((err: Error) => {
wx.hideLoading()
wx.showToast({ title: err.message || '配网失败,请重试', icon: 'none' })
this.setData({ status: 'password' })
})
},
onConfirm() {
if (!this.data.hasConnected) return
// 已有 userInfo 表示是从首页/设备页添加新设备,需把主用户下发到新设备后回首页
const userInfo = wx.getStorageSync('userInfo') as StoredUserInfo | null
if (userInfo) {
const mainUser: DeviceMember = {
id: userInfo.userId,
name: userInfo.realname,
gender: userInfo.sex === 1 ? 1 : 0,
age: calcAge(userInfo.birthday),
height: userInfo.height,
isSelf: true,
}
wx.showLoading({ title: '正在下发主用户...', mask: true })
lefuService.syncMembersToDevice([mainUser])
.then(() => {
wx.hideLoading()
wx.switchTab({ url: '/pages/home/home' })
})
.catch((err: Error) => {
wx.hideLoading()
wx.showToast({ title: err.message || '主用户下发失败', icon: 'none' })
})
return
}
wx.navigateTo({ url: '/pages/supplementPersonal/supplementPersonal' })
},
})