feat(lefu): 迁移乐福体脂秤 SDK,接入设备扫描连接与 WiFi 配网

- 新增 lefu 服务层(扫描/连接/断开/保活重连/测量回调/WiFi 配网),事件回调支持多监听
- connectedDevice 接入真实蓝牙扫描连接,修复断线重连 UI 未同步、蓝牙/定位开关误判
- connectedWifi 接入真实 WiFi 配网,补连接状态校验与退出配网模式
- 新增 5 张设备图标并调整应用入口

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
17792275749
2026-08-20 15:57:16 +08:00
co-authored by Claude Opus 4.7
parent feb494080c
commit f53f11e6e9
14 changed files with 901 additions and 71 deletions
@@ -1,3 +1,10 @@
import { leFuService } from '../../lefu/index'
/** 连接状态事件的取消订阅句柄 */
let unsubDisconnected: (() => void) | null = null
let unsubDeviceConnect: (() => void) | null = null
/** 渲染用的 WiFi 项(在 SSID 基础上追加连接状态) */
interface WifiItem {
ssid: string
connected: boolean
@@ -6,17 +13,6 @@ interface WifiItem {
type WifiStatus = 'idle' | 'searching' | 'list' | 'empty' | 'password' | 'configuring'
type BleStatus = 'connected' | 'failed' | 'connecting'
/** 假 WiFi 列表 */
const MOCK_WIFI: WifiItem[] = [
{ ssid: 'TP-LINK_5G_8A3C', connected: false },
{ ssid: 'Home_WiFi', connected: false },
{ ssid: 'Xiaomi_1234', connected: false },
]
/** 搜索 / 配网定时器 */
let _searchTimer: number | null = null
let _configTimer: number | null = null
Page({
data: {
status: 'idle' as WifiStatus,
@@ -30,31 +26,74 @@ Page({
},
onLoad() {
this._initDeviceInfo()
this._subscribeDisconnect()
this.onStartSearch()
},
onUnload() {
wx.hideLoading()
this._clearTimers()
unsubDisconnected?.()
unsubDeviceConnect?.()
unsubDisconnected = null
unsubDeviceConnect = null
leFuService.exitWifiConfig()
},
_clearTimers() {
if (_searchTimer !== null) { clearTimeout(_searchTimer); _searchTimer = null }
if (_configTimer !== null) { clearTimeout(_configTimer); _configTimer = null }
/** 订阅连接状态事件:断开 / 重连时同步状态到 UI */
_subscribeDisconnect() {
unsubDisconnected?.()
unsubDeviceConnect?.()
unsubDisconnected = leFuService.onDisconnected(() => {
this.setData({ bleStatus: 'failed' })
})
unsubDeviceConnect = leFuService.onDeviceConnect(() => {
this.setData({ bleStatus: 'connected' })
})
},
/** 模拟获取 WiFi 列表 */
onStartSearch() {
if (_searchTimer !== null) { clearTimeout(_searchTimer); _searchTimer = null }
/** 初始化设备信息:读取缓存设备名 + 同步蓝牙连接状态 */
_initDeviceInfo() {
const cached = wx.getStorageSync('connectDeviceInfo') as Record<string, any> | null
const deviceName = cached?.scaleDeviceName || cached?.name
if (deviceName) {
this.setData({ deviceName })
}
this.setData({ bleStatus: leFuService.isConnected ? 'connected' : 'failed' })
},
/** 校验设备连接状态:未连接则同步状态 + 提示,返回是否可继续操作 */
_ensureConnected(): boolean {
if (leFuService.isConnected) return true
this.setData({ bleStatus: 'failed' })
wx.showToast({ title: '设备已断开,请重新连接', icon: 'none' })
return false
},
/** 通过设备协议获取周围 WiFi 列表 */
async onStartSearch() {
if (!this._ensureConnected()) {
this.setData({ status: 'idle', wifiList: [] })
return
}
this.setData({ status: 'searching', wifiList: [] })
wx.showLoading({ title: '正在获取 WiFi 列表...', mask: true })
_searchTimer = setTimeout(() => {
try {
const list = await leFuService.getWifiList()
wx.hideLoading()
if (!list.length) {
this.setData({ status: 'empty', wifiList: [] })
return
}
this.setData({
status: 'list',
wifiList: MOCK_WIFI.map(item => ({ ...item })),
wifiList: list.map(item => ({ ssid: item.ssid, connected: false })),
})
}, 1200)
} catch {
wx.hideLoading()
this.setData({ status: 'empty', wifiList: [] })
wx.showToast({ title: '获取 WiFi 列表失败', icon: 'none' })
}
},
onRefresh() {
@@ -62,6 +101,7 @@ Page({
},
onTapWifi(e: WechatMiniprogram.TouchEvent) {
if (!this._ensureConnected()) return
const ssid = e.currentTarget.dataset.ssid as string
const target = this.data.wifiList.find(item => item.ssid === ssid)
if (!target || target.connected) return
@@ -80,13 +120,15 @@ Page({
this.setData({ status: 'list', selectedSsid: '', selectWifiPWD: '' })
},
/** 模拟配网 */
onConfirmPwd() {
/** 下发配网指令,成功后标记对应 WiFi 已连接 */
async onConfirmPwd() {
if (!this._ensureConnected()) return
const { selectedSsid, selectWifiPWD } = this.data
if (!selectedSsid) return
this.setData({ status: 'configuring' })
wx.showLoading({ title: '正在配网...', mask: true })
_configTimer = setTimeout(() => {
try {
await leFuService.configWifi(selectedSsid, selectWifiPWD)
wx.hideLoading()
this.setData({
status: 'list',
@@ -95,11 +137,21 @@ Page({
selectedSsid: '',
selectWifiPWD: '',
})
}, 1500)
wx.showToast({ title: '配网成功', icon: 'success' })
} catch (err: any) {
wx.hideLoading()
this.setData({ selectedSsid: '', selectWifiPWD: '' })
wx.showToast({ title: err?.message || '配网失败', icon: 'none' })
// 配网失败:延时 1.5s 后清空数据并重新获取 WiFi 列表
setTimeout(() => {
this.onStartSearch()
}, 1500)
}
},
onConfirm() {
if (!this.data.hasConnected) return
wx.navigateTo({ url: '/pages/supplementPersonal/supplementPersonal' })
if (!this._ensureConnected()) return
wx.navigateTo({ url: '/pages/equipment/equipment' })
},
})