import { get } from '../../utils/request/index' import { leFuService } from '../../lefu/index' import type { UserInfo } from '../../api/index' /** 体重设备(对应 /weighingScale/list/device 返回的 result 元素) */ interface ScaleDevice { /** 记录 ID */ id: string /** 设备 SN */ scaleDeviceId: string /** 连接设备信息(JSON 字符串,含 name、deviceId) */ connectDeviceInfo: string /** 用户数量 */ userNum: number /** 状态 */ status: false } /** 获取体重设备列表 */ const getDeviceList = (userId: string) => get('weighingScale/v3/list/device', { userId }) /** 展示用设备项 */ interface DeviceItem { id: string name: string status: boolean deviceId: string sn: string userNum: number connectDeviceInfo: string } let unsubDevicesList: (() => void) | null = null let unsubConnect: (() => void) | null = null let unsubDisconnected: (() => void) | null = null let scanTimer: number | null = null Page({ data: { devices: [] as DeviceItem[], loadingShow: false, loadingTitle: '正在连接设备', loadingContent: '请确保设备处于开启状态\n请勿离开...' }, onShow() { this.loadDevices() this._subscribeDisconnected() }, onHide() { leFuService.stopScan() unsubDisconnected?.() unsubDisconnected = null }, onUnload() { leFuService.stopScan() unsubDisconnected?.() unsubDisconnected = null unsubDevicesList?.() unsubDevicesList = null unsubConnect?.() unsubConnect = null if (scanTimer !== null) { clearTimeout(scanTimer); scanTimer = null } }, /** 订阅断开事件:设备长时间未操作或意外断开时,同步页面状态为未连接 */ _subscribeDisconnected() { unsubDisconnected?.() unsubDisconnected = leFuService.onDisconnected(() => { this.setData({ devices: this.data.devices.map(d => ({ ...d, status: false })), }) }) }, /** 拉取体重设备列表 */ async loadDevices() { const raw = wx.getStorageSync('userInfo') as UserInfo | null if (!raw?.userId) return try { const res = await getDeviceList(raw.userId) this.setData({ devices: res.result.map(item => { let info: Record = {} try { info = JSON.parse(item.connectDeviceInfo || '{}') } catch {} return { id: item.id, name: info.name ?? '', status: leFuService.isConnected && leFuService.lastRawDevice?.deviceId === info.deviceId, deviceId: info.deviceId ?? '', sn: item.scaleDeviceId, userNum: item.userNum ?? 0, connectDeviceInfo: item.connectDeviceInfo ?? '', } }), }) } catch { // 请求失败已由 request 层统一 toast } }, /** 取消配对:使用小程序自带 showModal */ onTapUnpair() { wx.showModal({ title: '取消配对', content: '是否确认取消配对当前设备?', cancelText: '取消', confirmText: '确定', confirmColor: '#F24439' }) }, /** 点击设备状态:已连接则断开,未连接则扫描连接 */ onTapStatus(e: WechatMiniprogram.TouchEvent) { const item = e.currentTarget.dataset.item as DeviceItem if (item.status) { leFuService.disconnect() this._updateStatus(item.deviceId, false) return } this._connectDevice(item) }, /** 扫描蓝牙,找到 deviceId 匹配的设备后连接 */ _connectDevice(item: DeviceItem) { const targetDeviceId = item.deviceId if (!targetDeviceId) return if (leFuService.isConnected) { leFuService.disconnect() // 断开后全部置未连接,等新设备连上再标回 this.setData({ devices: this.data.devices.map(d => ({ ...d, status: false })), }) } // 清理上一次连接流程的订阅与定时器,避免重复订阅累积 unsubDevicesList?.() unsubDevicesList = null unsubConnect?.() unsubConnect = null if (scanTimer !== null) { clearTimeout(scanTimer); scanTimer = null } wx.showLoading({ title: '连接中...', mask: true }) wx.openBluetoothAdapter({ success: () => { scanTimer = setTimeout(() => { unsubDevicesList?.() unsubDevicesList = null wx.hideLoading() wx.showToast({ title: '未找到设备', icon: 'none' }) }, 15000) unsubDevicesList = leFuService.onDevicesList((devices) => { const matched = devices.find(d => d.raw.deviceId === targetDeviceId) if (!matched) return if (scanTimer !== null) { clearTimeout(scanTimer); scanTimer = null } unsubDevicesList?.() unsubDevicesList = null leFuService.stopScan() leFuService.connect(matched.raw) unsubConnect = leFuService.onDeviceConnect(() => { unsubConnect?.() unsubConnect = null wx.hideLoading() wx.setStorageSync('connectDeviceInfo', matched.raw) this._updateStatus(targetDeviceId, true) }) }) leFuService.startScan() }, fail: () => { wx.hideLoading() wx.showToast({ title: '蓝牙未开启', icon: 'none' }) }, }) }, _updateStatus(deviceId: string, status: boolean) { this.setData({ devices: this.data.devices.map(item => item.deviceId === deviceId ? { ...item, status } : item ), }) }, /** 底部操作:数据补传 / 设备连接 弹 loading */ onTapAction(e: WechatMiniprogram.TouchEvent) { const action = e.currentTarget.dataset.action as string if (action === '数据补传') { this.setData({ loadingShow: true, loadingTitle: '正在获取设备本地未上传数据', loadingContent: '请稍等...' }) } else if (action === '设备连接') { this.setData({ loadingShow: true, loadingTitle: '正在连接设备', loadingContent: '请确保设备处于开启状态\n请勿离开...' }) } }, onCloseLoading() { this.setData({ loadingShow: false }) }, /** 用户管理 */ onTapUser(e: WechatMiniprogram.TouchEvent) { const item = e.currentTarget.dataset.item as DeviceItem wx.navigateTo({ url: `/pages/userManagement/userManagement?sn=${encodeURIComponent(item.sn)}&deviceId=${encodeURIComponent(item.deviceId)}&name=${encodeURIComponent(item.name)}&status=${item.status}&connectDeviceInfo=${encodeURIComponent(item.connectDeviceInfo)}`, }) }, onTapAdd() { wx.navigateTo({ url: '/pages/connectedDevice/connectedDevice' }) }, /** 关闭运维模式 */ onCloseOps() { // 关闭运维模式(待接入) }, /** 取消全部配对 */ onUnpairAll() { wx.showModal({ title: '取消全部配对', content: '是否确认取消全部设备的配对?', cancelText: '取消', confirmText: '确定', confirmColor: '#F24439' }) } })