fix(device): 修复设备切换连接订阅累积与自动重连,连接后更新缓存
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
6ffda3f3f3
commit
f750d15150
@@ -94,6 +94,7 @@ class LeFuService {
|
|||||||
*/
|
*/
|
||||||
startScan(): void {
|
startScan(): void {
|
||||||
console.log(TAG, 'startScan()')
|
console.log(TAG, 'startScan()')
|
||||||
|
this._intentionalConnect = true
|
||||||
plugin.Blue.setDeviceSetting(DEVICE_SETTINGS)
|
plugin.Blue.setDeviceSetting(DEVICE_SETTINGS)
|
||||||
this._subscribeBus()
|
this._subscribeBus()
|
||||||
plugin.Blue.start(DEVICE_SETTINGS.map(s => s.deviceName), false)
|
plugin.Blue.start(DEVICE_SETTINGS.map(s => s.deviceName), false)
|
||||||
@@ -185,11 +186,9 @@ class LeFuService {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 蓝牙就绪:如有缓存设备且非主动断开,尝试重连
|
// 蓝牙就绪:非主动操作(意外断开)且有缓存设备时自动重连,主动扫描/连接期间不重连
|
||||||
if (res === plugin.BLUE_STATE.READY) {
|
if (res === plugin.BLUE_STATE.READY) {
|
||||||
if (this._intentionalConnect) {
|
if (!this._intentionalConnect && this._lastRawDevice && !this._activeProtocol && this._onDevicesListCbs.size === 0) {
|
||||||
this._intentionalConnect = false
|
|
||||||
} else if (this._lastRawDevice && !this._activeProtocol) {
|
|
||||||
this._stopReconnectTimer()
|
this._stopReconnectTimer()
|
||||||
wx.openBluetoothAdapter({
|
wx.openBluetoothAdapter({
|
||||||
success: () => this.connect(this._lastRawDevice!),
|
success: () => this.connect(this._lastRawDevice!),
|
||||||
|
|||||||
@@ -128,7 +128,6 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin-right: 24rpx;
|
margin-right: 24rpx;
|
||||||
border-radius: 24rpx;
|
border-radius: 24rpx;
|
||||||
background-color: #1385FA;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.device-info {
|
.device-info {
|
||||||
@@ -187,17 +186,17 @@
|
|||||||
font-size: 22rpx;
|
font-size: 22rpx;
|
||||||
line-height: 22rpx;
|
line-height: 22rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.connected {
|
|
||||||
background-color: #EAFAF6;
|
|
||||||
|
|
||||||
&.status-dot {
|
|
||||||
background-color: #2AC79F;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&.status-text {
|
.connected {
|
||||||
color: #2AC79F;
|
background-color: #EAFAF6 !important;
|
||||||
|
|
||||||
|
.status-dot {
|
||||||
|
background-color: #2AC79F !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status-text {
|
||||||
|
color: #2AC79F !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { get } from '../../utils/request/index'
|
import { get } from '../../utils/request/index'
|
||||||
|
import { leFuService } from '../../lefu/index'
|
||||||
import type { UserInfo } from '../../api/index'
|
import type { UserInfo } from '../../api/index'
|
||||||
|
|
||||||
/** 体重设备(对应 /weighingScale/list/device 返回的 result 元素) */
|
/** 体重设备(对应 /weighingScale/list/device 返回的 result 元素) */
|
||||||
@@ -30,6 +31,10 @@ interface DeviceItem {
|
|||||||
connectDeviceInfo: string
|
connectDeviceInfo: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let unsubDevicesList: (() => void) | null = null
|
||||||
|
let unsubConnect: (() => void) | null = null
|
||||||
|
let scanTimer: number | null = null
|
||||||
|
|
||||||
Page({
|
Page({
|
||||||
data: {
|
data: {
|
||||||
devices: [] as DeviceItem[],
|
devices: [] as DeviceItem[],
|
||||||
@@ -57,7 +62,7 @@ Page({
|
|||||||
return {
|
return {
|
||||||
id: item.id,
|
id: item.id,
|
||||||
name: info.name ?? '',
|
name: info.name ?? '',
|
||||||
status: false,
|
status: leFuService.isConnected && leFuService.lastRawDevice?.deviceId === info.deviceId,
|
||||||
deviceId: info.deviceId ?? '',
|
deviceId: info.deviceId ?? '',
|
||||||
sn: item.scaleDeviceId,
|
sn: item.scaleDeviceId,
|
||||||
userNum: item.userNum ?? 0,
|
userNum: item.userNum ?? 0,
|
||||||
@@ -81,6 +86,79 @@ Page({
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** 点击设备状态:已连接则断开,未连接则扫描连接 */
|
||||||
|
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 */
|
/** 底部操作:数据补传 / 设备连接 弹 loading */
|
||||||
onTapAction(e: WechatMiniprogram.TouchEvent) {
|
onTapAction(e: WechatMiniprogram.TouchEvent) {
|
||||||
const action = e.currentTarget.dataset.action as string
|
const action = e.currentTarget.dataset.action as string
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<view class="equipment">
|
<view class="equipment">
|
||||||
<!-- 运维模式提示行 -->
|
<!-- 运维模式提示行 -->
|
||||||
<!-- <view class="ops-bar">-->
|
<view class="ops-bar">
|
||||||
<!-- <view class="ops-mode">当前为:运维模式</view>-->
|
<view class="ops-mode">当前为:运维模式</view>
|
||||||
<!-- <view class="ops-btn ops-btn--blue" bind:tap="onCloseOps">关闭运维模式</view>-->
|
<view class="ops-btn ops-btn--blue" bind:tap="onCloseOps">关闭运维模式</view>
|
||||||
<!-- </view>-->
|
</view>
|
||||||
|
|
||||||
<!-- 顶部卡片(渐变背景 + 设备图片占位) -->
|
<!-- 顶部卡片(渐变背景 + 设备图片占位) -->
|
||||||
<view class="top-banner">
|
<view class="top-banner">
|
||||||
@@ -22,17 +22,26 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 设备列表 -->
|
<!-- 设备列表 -->
|
||||||
|
<!-- <view class="device">
|
||||||
|
<scroll-view class="scrollView" scroll-y>
|
||||||
|
<view class="scrollViewContent">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view> -->
|
||||||
<block wx:if="{{ devices && devices.length }}">
|
<block wx:if="{{ devices && devices.length }}">
|
||||||
<block wx:for="{{ devices }}" wx:key="id">
|
<block wx:for="{{ devices }}" wx:key="id">
|
||||||
<view class="device-card">
|
<view class="device-card">
|
||||||
<view class="device-top">
|
<view class="device-top">
|
||||||
<view class="device-icon"></view>
|
<view class="device-icon">
|
||||||
|
<image src="/images/device/{{ item.name }}.png"/>
|
||||||
|
</view>
|
||||||
<view class="device-info">
|
<view class="device-info">
|
||||||
<view class="device-info_">
|
<view class="device-info_">
|
||||||
<view class="device-name">{{ item.name }}</view>
|
<view class="device-name">{{ item.name }}</view>
|
||||||
<view class="device-unpair" bind:tap="onTapUnpair">取消配对</view>
|
<view class="device-unpair" bind:tap="onTapUnpair">取消配对</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="device-status">
|
<view class="device-status" bind:tap="onTapStatus" data-item="{{ item }}">
|
||||||
<view class="device-status_ {{item.status ? 'connected' : ''}}">
|
<view class="device-status_ {{item.status ? 'connected' : ''}}">
|
||||||
<view class="status-dot"></view>
|
<view class="status-dot"></view>
|
||||||
<view class="status-text">{{ item.status ? '已连接' : '未连接' }}</view>
|
<view class="status-text">{{ item.status ? '已连接' : '未连接' }}</view>
|
||||||
@@ -53,12 +62,22 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="device-actions">
|
<view class="device-actions">
|
||||||
|
<block wx:if="{{item.status}}">
|
||||||
<view class="device-action-btn">
|
<view class="device-action-btn">
|
||||||
<view>
|
<view>
|
||||||
<image src="/images/equipment/wifi.png"/>
|
<image src="/images/equipment/wifi.png"/>
|
||||||
</view>
|
</view>
|
||||||
<view>设备WIFI</view>
|
<view>设备WIFI</view>
|
||||||
</view>
|
</view>
|
||||||
|
</block>
|
||||||
|
<block wx:else>
|
||||||
|
<view class="device-action-btn" bind:tap="onTapStatus" data-item="{{ item }}">
|
||||||
|
<view>
|
||||||
|
<image src="/images/equipment/bluetooth.png"/>
|
||||||
|
</view>
|
||||||
|
<view>设备连接</view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
<view class="device-action-btn" bind:tap="onTapUser">
|
<view class="device-action-btn" bind:tap="onTapUser">
|
||||||
<view>
|
<view>
|
||||||
<image src="/images/equipment/users.png"/>
|
<image src="/images/equipment/users.png"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user