Files
bodyWeight/miniprogram/pages/equipment/equipment.ts
T

241 lines
7.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<ScaleDevice[]>('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<string, any> = {}
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'
})
}
})