fix(device): 修复配网页蓝牙搜索无法停止与网络配置按钮失效
与重构前 uni-app 版逐项对比定位三处回归: - useDidHide 停搜索:旧版 onHide/onUnload 双触发,迁移版只有 useEffect 卸载清理,navigateTo 进入配网页或切后台时组件不卸载,扫描持续空转 - prepareWifiConfig 加 60s 超时兜底:createBLEConnection 在部分机型 失败后不回调,discoverServices/notify 无原生超时,loading 遮罩 永不撤除导致按钮永久禁用 - 连接失败后安全断开(对齐旧版 safeDisconnect):清掉 OS 层残留连接, 避免"已连接(10010)"卡死后续重试;并补回"设备已连接"成功提示
This commit is contained in:
parent
1baca70e35
commit
58d0ee8ad7
|
|
@ -1,20 +1,35 @@
|
|||
import { useEffect, useState } from 'react'
|
||||
import Taro from '@tarojs/taro'
|
||||
import Taro, { useDidHide } from '@tarojs/taro'
|
||||
import { View, Text } from '@tarojs/components'
|
||||
import { Navbar } from '@/components/navbar'
|
||||
import { useBle } from '@/ble/hooks/useBle'
|
||||
import { navigateTo } from '@/utils/navigation'
|
||||
import { ROUTES } from '@/constants/routes'
|
||||
import { getErrorMessage } from '@/utils/error'
|
||||
import { showToast } from '@/utils/toast'
|
||||
import { DEVICE_ACTION_KEYS, ACTION_REGISTRY, isEp832Device } from '@/constants/deviceActions'
|
||||
import type { BleDevice } from '@/ble/hooks/useBle'
|
||||
import styles from './ble-config.module.scss'
|
||||
|
||||
// createBLEConnection 最多 3 次尝试(15s 超时 + 1.2s 重试间隔)约 47s,
|
||||
// 兜底覆盖 discoverServices/notify 无原生超时的场景,保证 loading 遮罩必然撤除
|
||||
const PREPARE_WIFI_TIMEOUT_MS = 60000
|
||||
|
||||
function withTimeout<T>(promise: Promise<T>, ms: number, message: string): Promise<T> {
|
||||
return Promise.race([
|
||||
promise,
|
||||
new Promise<never>((_, reject) => {
|
||||
setTimeout(() => reject(new Error(message)), ms)
|
||||
})
|
||||
])
|
||||
}
|
||||
|
||||
export default function DeviceBleConfig() {
|
||||
const { state, discovery } = useBle()
|
||||
const [preparingId, setPreparingId] = useState('')
|
||||
|
||||
// 页面隐藏/卸载时清理搜索(对齐旧版 onHide/onUnload),连接保持供配网页使用
|
||||
// 页面隐藏(navigateTo 配网页/切后台)与卸载(返回)时停搜索,连接保持供配网页使用。
|
||||
// useEffect 的清理只在卸载触发,压栈后台时组件不卸载,必须补 useDidHide(对齐旧版 onHide/onUnload)
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (discovery.getState().isSearching) {
|
||||
|
|
@ -24,6 +39,12 @@ export default function DeviceBleConfig() {
|
|||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
useDidHide(() => {
|
||||
if (discovery.getState().isSearching) {
|
||||
discovery.stopSearch(false)
|
||||
}
|
||||
})
|
||||
|
||||
const startScan = async () => {
|
||||
if (state.searching) {
|
||||
await discovery.stopSearch()
|
||||
|
|
@ -46,10 +67,19 @@ export default function DeviceBleConfig() {
|
|||
|
||||
let prepError: unknown = null
|
||||
try {
|
||||
await discovery.prepareWifiConfig(deviceId)
|
||||
// createBLEConnection 部分机型失败后不回调(微信基础库缺陷),
|
||||
// discoverServices/notify 也无原生超时;不设兜底会导致 loading 永不消失、按钮永久失效
|
||||
await withTimeout(
|
||||
discovery.prepareWifiConfig(deviceId),
|
||||
PREPARE_WIFI_TIMEOUT_MS,
|
||||
`连接设备超时(${PREPARE_WIFI_TIMEOUT_MS / 1000}s),请重试`
|
||||
)
|
||||
navigateTo(ROUTES.DEVICE_CONFIG)
|
||||
} catch (error) {
|
||||
prepError = error
|
||||
// 对齐旧版 safeDisconnect:连接半途失败时清掉 OS 层残留连接,
|
||||
// 否则后续重试会被"已连接(10010)"错误卡死
|
||||
discovery.disconnectDevice().catch(() => {})
|
||||
} finally {
|
||||
setPreparingId('')
|
||||
// showLoading 与 showToast 共用同一遮罩层,必须先 hideLoading 再弹提示
|
||||
|
|
@ -64,6 +94,8 @@ export default function DeviceBleConfig() {
|
|||
showCancel: false,
|
||||
confirmText: '知道了'
|
||||
})
|
||||
} else {
|
||||
showToast('设备已连接,请填写WiFi信息')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue