fix(lefu): 完善蓝牙连接状态处理,修复断开后 UI 不同步问题

- connectState 回调增加 UNAVAILABLE 清理和 READY 自动重连
- disconnect() 增加 _intentionalConnect 标记避免误重连
- deviceWillDisconnect 增加 _activeProtocol 防重入判断
- connectedDevice/equipment/connectedWifi 增加断开状态响应
- connectedWifi 设备断开后自动退出配网页

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
17792275749
2026-07-21 09:43:49 +08:00
co-authored by Claude Sonnet 4.6
parent 15e089f5e3
commit 439f560218
7 changed files with 60 additions and 12 deletions
+1 -1
View File
@@ -32,7 +32,7 @@
"lazyCodeLoading": "requiredComponents", "lazyCodeLoading": "requiredComponents",
"plugins": { "plugins": {
"ppScale-plugin": { "ppScale-plugin": {
"version": "0.0.25", "version": "0.0.29",
"provider": "wx0826af4e4908f524" "provider": "wx0826af4e4908f524"
} }
}, },
+28 -2
View File
@@ -168,6 +168,7 @@ class LeFuService {
this._onConnectStateCb?.(res) this._onConnectStateCb?.(res)
if (res === plugin.BLUE_STATE.CONNECTSUCCESS) { if (res === plugin.BLUE_STATE.CONNECTSUCCESS) {
this._startKeepAlive() this._startKeepAlive()
return
} }
if (res === plugin.BLUE_STATE.CONNECTFAILED) { if (res === plugin.BLUE_STATE.CONNECTFAILED) {
this._stopKeepAlive() this._stopKeepAlive()
@@ -176,6 +177,28 @@ class LeFuService {
} else { } else {
this._doReconnect() this._doReconnect()
} }
return
}
// 蓝牙不可用:做完整清理
if (res === plugin.BLUE_STATE.UNAVAILABLE) {
this._stopKeepAlive()
this._stopReconnectTimer()
if (this._activeProtocol) {
this._activeProtocol = null
this._onDisconnectedCb?.()
}
return
}
// 蓝牙就绪:如有缓存设备且非主动断开,尝试连接
if (res === plugin.BLUE_STATE.READY) {
if (this._intentionalConnect) {
this._intentionalConnect = false
} else if (this._lastRawDevice && !this._activeProtocol) {
this._stopReconnectTimer()
wx.openBluetoothAdapter({
success: () => this.connect(this._lastRawDevice!),
})
}
} }
}) })
@@ -189,9 +212,11 @@ class LeFuService {
plugin.bus.subscribe('deviceWillDisconnect', () => { plugin.bus.subscribe('deviceWillDisconnect', () => {
console.warn(TAG, 'bus[deviceWillDisconnect]intentionalConnect:', this._intentionalConnect) console.warn(TAG, 'bus[deviceWillDisconnect]intentionalConnect:', this._intentionalConnect)
this._activeProtocol = null
this._stopKeepAlive() this._stopKeepAlive()
this._onDisconnectedCb?.() if (this._activeProtocol) {
this._activeProtocol = null
this._onDisconnectedCb?.()
}
if (!this._intentionalConnect) { if (!this._intentionalConnect) {
this._doReconnect() this._doReconnect()
} }
@@ -221,6 +246,7 @@ class LeFuService {
disconnect(): void { disconnect(): void {
console.log(TAG, 'disconnect()') console.log(TAG, 'disconnect()')
this._intentionalConnect = true
this._stopKeepAlive() this._stopKeepAlive()
plugin.Blue.disconnect() plugin.Blue.disconnect()
} }
+2 -2
View File
@@ -326,7 +326,7 @@ Page({
get<any>('weighingScale/v3/getUserInfoByIdcard', { get<any>('weighingScale/v3/getUserInfoByIdcard', {
sn: lefuService.deviceInfo?.serialNumber ?? '', sn: lefuService.deviceInfo?.serialNumber ?? '',
idCard, idCard: idCard || null,
realname: name realname: name
}, { loading: true }) }, { loading: true })
.then(res => { .then(res => {
@@ -491,7 +491,7 @@ Page({
sn: lefuService.deviceInfo?.serialNumber ?? '', sn: lefuService.deviceInfo?.serialNumber ?? '',
scaleDeviceId: lefuService.deviceInfo?.serialNumber ?? '', scaleDeviceId: lefuService.deviceInfo?.serialNumber ?? '',
realname: name.trim(), realname: name.trim(),
idCard, idCard: idCard || null,
sex: finalSex, sex: finalSex,
birthday, birthday,
height: heightNum, height: heightNum,
@@ -28,6 +28,11 @@ Page({
onShow() { onShow() {
console.log(TAG, 'onShow') console.log(TAG, 'onShow')
// 回到页面时同步实际连接状态,避免回调被其他页面覆盖导致状态不同步
if (!lefuService.isConnected) {
const list = this.data.deviceList.map(item => ({ ...item, connected: false }))
this.setData({ deviceList: list })
}
}, },
onHide() { onHide() {
@@ -169,6 +174,10 @@ Page({
this.setData({ _autoConnectTried: true }) this.setData({ _autoConnectTried: true })
this._autoConnectByIndex(matchedIndex) this._autoConnectByIndex(matchedIndex)
}) })
lefuService.onDisconnected(() => {
const list = this.data.deviceList.map(item => ({ ...item, connected: false }))
this.setData({ deviceList: list })
})
lefuService.startScan() lefuService.startScan()
console.log(TAG, 'lefuService.startScan() 已调用') console.log(TAG, 'lefuService.startScan() 已调用')
}, },
@@ -25,7 +25,7 @@ Page({
_toBleStatus(state: string): BleStatus { _toBleStatus(state: string): BleStatus {
const bs = lefuService.BLUE_STATE const bs = lefuService.BLUE_STATE
if (state === bs.CONNECTSUCCESS || state === bs.WIFISUCCESS) return 'connected' if (state === bs.CONNECTSUCCESS || state === bs.WIFISUCCESS) return 'connected'
if (state === bs.CONNECTFAILED) return 'failed' if (state === bs.CONNECTFAILED || state === bs.UNAVAILABLE) return 'failed'
return 'connecting' return 'connecting'
}, },
@@ -34,6 +34,11 @@ Page({
lefuService.onDeviceInfo((info) => { lefuService.onDeviceInfo((info) => {
this.setData({ deviceName: info.modelNumber }) this.setData({ deviceName: info.modelNumber })
}) })
// 设备断开即退出配网页
lefuService.onDisconnected(() => {
wx.showToast({ title: '设备已断开连接', icon: 'none', duration: 1500 })
setTimeout(() => wx.navigateBack(), 1500)
})
this.setData({ this.setData({
bleStatus: this._toBleStatus(lefuService.connectState), bleStatus: this._toBleStatus(lefuService.connectState),
deviceName: lefuService.deviceInfo?.modelNumber ?? '智能体重秤', deviceName: lefuService.deviceInfo?.modelNumber ?? '智能体重秤',
@@ -43,15 +48,13 @@ Page({
onShow() { onShow() {
lefuService.onConnectState((state) => { lefuService.onConnectState((state) => {
const bs = lefuService.BLUE_STATE this.setData({ bleStatus: this._toBleStatus(state) })
if (state === bs.CONNECTSUCCESS || state === bs.WIFISUCCESS || state === bs.CONNECTFAILED) {
this.setData({ bleStatus: this._toBleStatus(state) })
}
}) })
}, },
onUnload() { onUnload() {
wx.hideLoading() wx.hideLoading()
lefuService.onDisconnected(() => {})
if (this.data.status === 'configuring') { if (this.data.status === 'configuring') {
lefuService.disconnect() lefuService.disconnect()
} }
+10
View File
@@ -68,6 +68,7 @@ Page({
lefuService.stopScan() lefuService.stopScan()
lefuService.onDeviceConnect(() => {}) lefuService.onDeviceConnect(() => {})
lefuService.onDeviceInfo(() => {}) lefuService.onDeviceInfo(() => {})
lefuService.onDisconnected(() => {})
}, },
/** 拉取已绑定设备列表,加载完成后检查缓存自动连接 */ /** 拉取已绑定设备列表,加载完成后检查缓存自动连接 */
@@ -112,6 +113,9 @@ Page({
lefuService.onDeviceInfo((info) => { lefuService.onDeviceInfo((info) => {
this._markConnected(info.serialNumber as string) this._markConnected(info.serialNumber as string)
}) })
lefuService.onDisconnected(() => {
this._markAllDisconnected()
})
lefuService.autoConnect() lefuService.autoConnect()
}, },
@@ -124,6 +128,12 @@ Page({
this.setData({ deviceList: list }) this.setData({ deviceList: list })
}, },
/** 将所有设备标记为未连接 */
_markAllDisconnected() {
const list = this.data.deviceList.map(item => ({ ...item, connected: false }))
this.setData({ deviceList: list })
},
/** 点击「连接」:扫描周边设备,找到 deviceId 匹配的设备后连接 */ /** 点击「连接」:扫描周边设备,找到 deviceId 匹配的设备后连接 */
onTapConnect(e: WechatMiniprogram.TouchEvent) { onTapConnect(e: WechatMiniprogram.TouchEvent) {
const userInfo = e.currentTarget.dataset.userInfo as DeviceItem const userInfo = e.currentTarget.dataset.userInfo as DeviceItem
+2 -2
View File
@@ -2,8 +2,8 @@ import type { ApiResponse, HttpMethod, RequestOptions } from './types'
export type { ApiResponse, RequestOptions } export type { ApiResponse, RequestOptions }
const BASE_URL = 'http://10.10.10.10:8889/' // 测试环境 // const BASE_URL = 'http://10.10.10.10:8889/' // 测试环境
// const BASE_URL = 'https://device.shuziweidao.com/gateway/' // 正式环境 const BASE_URL = 'https://device.shuziweidao.com/gateway/' // 正式环境
let _loadingCount = 0 let _loadingCount = 0