From db865748f2e3c80bd84cc2c7f8c3fda3e45f7584 Mon Sep 17 00:00:00 2001 From: 17792275749 <812100002@qq.com> Date: Fri, 21 Aug 2026 09:35:18 +0800 Subject: [PATCH] =?UTF-8?q?fix(device):=20=E4=BF=AE=E5=A4=8D=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E8=BF=9E=E6=8E=A5=E4=B8=8E=E9=85=8D=E7=BD=91=E5=A4=9A?= =?UTF-8?q?=E5=9C=BA=E6=99=AF=E9=97=AE=E9=A2=98=EF=BC=8C=E5=90=8C=E5=90=8D?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E7=94=A8=20deviceId=20=E5=8C=BA=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 连接中关闭蓝牙立即结束 loading,不再卡到超时 - onShow 已连接时同步标记,重新搜索不误标已连接设备 - 连接中防重入,搜索中切后台重置状态 - 配网成功立即退出配网模式,密码必填且 8-16 位 - 配网失败重试定时器可清理 - 同名设备改用 deviceId 唯一标识并展示 Co-Authored-By: Claude Opus 4.7 --- miniprogram/app.json | 2 +- .../connectedDevice/connectedDevice.less | 136 ++++++++++-------- .../pages/connectedDevice/connectedDevice.ts | 42 ++++-- .../connectedDevice/connectedDevice.wxml | 35 ++--- .../pages/connectedWifi/connectedWifi.ts | 19 ++- .../pages/connectedWifi/connectedWifi.wxml | 2 + 6 files changed, 146 insertions(+), 90 deletions(-) diff --git a/miniprogram/app.json b/miniprogram/app.json index 99c2c69..e1b8129 100644 --- a/miniprogram/app.json +++ b/miniprogram/app.json @@ -1,8 +1,8 @@ { "pages": [ + "pages/connectedDevice/connectedDevice", "pages/login/login", "pages/supplementPersonal/supplementPersonal", - "pages/connectedDevice/connectedDevice", "pages/connectedWifi/connectedWifi", "pages/home/home", "pages/detailedReport/detailedReport", diff --git a/miniprogram/pages/connectedDevice/connectedDevice.less b/miniprogram/pages/connectedDevice/connectedDevice.less index 682e481..c6f867b 100644 --- a/miniprogram/pages/connectedDevice/connectedDevice.less +++ b/miniprogram/pages/connectedDevice/connectedDevice.less @@ -200,84 +200,98 @@ .device-card { width: 100%; - height: 150rpx; - display: flex; - align-items: center; - padding: 0 30rpx; - background-color: #FFFFFF; - border: 2rpx solid #E6E6EA; + padding: 30rpx; border-radius: 16rpx; box-sizing: border-box; margin-bottom: 24rpx; + background-color: #FFFFFF; + border: 2rpx solid #E6E6EA; - .card-icon { - width: 90rpx; + .device-card-top { + width: 100%; height: 90rpx; - overflow: hidden; - border-radius: 24rpx; - margin-right: 24rpx; - } - - .card-info { - flex: 1; display: flex; - flex-direction: column; - justify-content: center; + flex-wrap: nowrap; + align-items: center; - .card-name { - color: #252535; - font-size: 32rpx; - font-weight: bold; - height: 32rpx; - line-height: 32rpx; + .card-icon { + width: 90rpx; + height: 90rpx; + overflow: hidden; + border-radius: 24rpx; + margin-right: 24rpx; } - .card-status { - margin-top: 18rpx; + .card-info { + flex: 1; display: flex; - align-items: center; + flex-direction: column; + justify-content: center; - .card-dot { - width: 12rpx; - height: 12rpx; - border-radius: 50%; - background-color: #2AC79F; - margin-right: 15rpx; + .card-name { + color: #252535; + font-size: 32rpx; + font-weight: bold; + height: 32rpx; + line-height: 32rpx; } - .card-status-text { - color: #2AC79F; - height: 28rpx; - font-size: 28rpx; - font-weight: 500; - line-height: 28rpx; + .card-status { + margin-top: 18rpx; + display: flex; + align-items: center; + + .card-dot { + width: 12rpx; + height: 12rpx; + border-radius: 50%; + background-color: #2AC79F; + margin-right: 15rpx; + } + + .card-status-text { + color: #2AC79F; + height: 28rpx; + font-size: 28rpx; + font-weight: 500; + line-height: 28rpx; + } } } + + .card-btn-primary { + color: #FFFFFF; + font-size: 24rpx; + font-weight: 500; + width: 88rpx; + height: 48rpx; + line-height: 48rpx; + text-align: center; + border-radius: 8rpx; + background-color: #2AC79F; + } + + .card-btn-danger { + color: #F24439; + font-size: 24rpx; + font-weight: 500; + width: 120rpx; + height: 48rpx; + line-height: 44rpx; + text-align: center; + border: 2rpx solid #F24439; + border-radius: 8rpx; + box-sizing: border-box; + } } - .card-btn-primary { - color: #FFFFFF; - font-size: 24rpx; - font-weight: 500; - width: 88rpx; - height: 48rpx; - line-height: 48rpx; - text-align: center; - border-radius: 8rpx; - background-color: #2AC79F; - } - - .card-btn-danger { - color: #F24439; - font-size: 24rpx; - font-weight: 500; - width: 120rpx; - height: 48rpx; - line-height: 44rpx; - text-align: center; - border: 2rpx solid #F24439; - border-radius: 8rpx; - box-sizing: border-box; + .device-card-bottom { + color: #B6B6B6; + height: 22rpx; + font-size: 22rpx; + font-weight: normal; + line-height: 22rpx; + margin-top: 10rpx; } } } diff --git a/miniprogram/pages/connectedDevice/connectedDevice.ts b/miniprogram/pages/connectedDevice/connectedDevice.ts index 90112d3..02f8dc9 100644 --- a/miniprogram/pages/connectedDevice/connectedDevice.ts +++ b/miniprogram/pages/connectedDevice/connectedDevice.ts @@ -4,6 +4,7 @@ import type { RawDevice } from '../../lefu/types' /** 渲染用的设备项(RawDevice 含复杂对象,不进 setData) */ interface DeviceItem { + deviceId: string name: string connected: boolean } @@ -34,13 +35,19 @@ Page({ onShow() { // 从其他页面返回时同步连接状态 - if (!leFuService.isConnected) { + if (leFuService.isConnected) { + this._markConnected() + } else { this._markAllDisconnected() } }, onHide() { leFuService.stopScan() + // 搜索中切后台:停止扫描后重置状态,避免回来显示「搜索中」假状态 + if (this.data.status === 'searching') { + this.setData({ status: 'idle' }) + } }, onUnload() { @@ -91,16 +98,19 @@ Page({ }) }, + /** 获取当前已连接设备的 deviceId(未连接返回空字符串) */ + _getConnectedId(): string { + if (!leFuService.isConnected) return '' + const cached = wx.getStorageSync('connectDeviceInfo') as Record | null + return cached?.deviceId || '' + }, + /** 连接成功后把对应设备卡片标记为已连接(覆盖手动连接与自动重连) */ _markConnected() { - const cached = wx.getStorageSync('connectDeviceInfo') as Record | null - const name = leFuService.deviceInfo?.modelNumber - || cached?.scaleDeviceName - || cached?.name - || cached?.deviceName - if (!name) return + const id = this._getConnectedId() + if (!id) return this.setData({ - deviceList: this.data.deviceList.map(item => ({ ...item, connected: item.name === name })), + deviceList: this.data.deviceList.map(item => ({ ...item, connected: item.deviceId === id })), }) }, @@ -174,10 +184,14 @@ Page({ this.setData({ status: 'empty', deviceList: [] }) return } - const connectedName = this.data.deviceList.find(d => d.connected)?.name + const connectedId = this._getConnectedId() this.setData({ status: 'found', - deviceList: devices.map(d => ({ name: d.name, connected: d.name === connectedName })), + deviceList: devices.map(d => ({ + deviceId: d.raw.deviceId || '', + name: d.name, + connected: !!connectedId && d.raw.deviceId === connectedId, + })), }) this._tryAutoConnect() }) @@ -193,6 +207,8 @@ Page({ /** 命中缓存设备时自动连接一次 */ _tryAutoConnect() { if (autoConnectTried) return + // 已连接时不自动重连,避免触发断开重连 + if (leFuService.isConnected) return const cached = wx.getStorageSync('connectDeviceInfo') as RawDevice | null if (!cached?.deviceId) return const index = scannedDevices.findIndex(d => d.raw.deviceId === cached.deviceId) @@ -205,6 +221,8 @@ Page({ _connectByIndex(index: number, isAuto: boolean) { const scanned = scannedDevices[index] if (!scanned) return + // 连接中:防止重复点击导致连接流程被重复触发 + if (connectCleanup) return wx.showLoading({ title: '连接中...', mask: true }) leFuService.stopScan() @@ -230,6 +248,10 @@ Page({ if (state === leFuService.BLUE_STATE.CONNECTFAILED) { finish() wx.showToast({ title: '连接失败,请重试', icon: 'none' }) + } else if (state === leFuService.BLUE_STATE.UNAVAILABLE) { + // 连接过程中蓝牙被关闭:立即结束 loading,避免卡到超时 + finish() + wx.showToast({ title: '蓝牙已断开,请重新开启', icon: 'none' }) } }) diff --git a/miniprogram/pages/connectedDevice/connectedDevice.wxml b/miniprogram/pages/connectedDevice/connectedDevice.wxml index c8be7f0..be564bc 100644 --- a/miniprogram/pages/connectedDevice/connectedDevice.wxml +++ b/miniprogram/pages/connectedDevice/connectedDevice.wxml @@ -54,26 +54,29 @@ - + - - - - - {{ item.name }} + + + + + + {{ item.name }} + + + + 已连接 + + + - - - 已连接 - + 断开连接 + + + 连接 - - 断开连接 - - - 连接 - + deviceId:{{ item.deviceId }} diff --git a/miniprogram/pages/connectedWifi/connectedWifi.ts b/miniprogram/pages/connectedWifi/connectedWifi.ts index a9e52d1..fb0fd43 100644 --- a/miniprogram/pages/connectedWifi/connectedWifi.ts +++ b/miniprogram/pages/connectedWifi/connectedWifi.ts @@ -3,6 +3,7 @@ import { leFuService } from '../../lefu/index' /** 连接状态事件的取消订阅句柄 */ let unsubDisconnected: (() => void) | null = null let unsubDeviceConnect: (() => void) | null = null +let retryTimer: number | null = null /** 渲染用的 WiFi 项(在 SSID 基础上追加连接状态) */ interface WifiItem { @@ -33,6 +34,7 @@ Page({ onUnload() { wx.hideLoading() + if (retryTimer !== null) { clearTimeout(retryTimer); retryTimer = null } unsubDisconnected?.() unsubDeviceConnect?.() unsubDisconnected = null @@ -125,11 +127,22 @@ Page({ if (!this._ensureConnected()) return const { selectedSsid, selectWifiPWD } = this.data if (!selectedSsid) return + const pwd = selectWifiPWD.trim() + if (!pwd) { + wx.showToast({ title: '请输入 Wi-Fi 密码', icon: 'none' }) + return + } + if (pwd.length < 8 || pwd.length > 16) { + wx.showToast({ title: '密码长度需为 8-16 位', icon: 'none' }) + return + } this.setData({ status: 'configuring' }) wx.showLoading({ title: '正在配网...', mask: true }) try { - await leFuService.configWifi(selectedSsid, selectWifiPWD) + await leFuService.configWifi(selectedSsid, pwd) wx.hideLoading() + // 配网成功:立即退出配网模式(跳转走 onHide,不触发 onUnload) + leFuService.exitWifiConfig() this.setData({ status: 'list', wifiList: this.data.wifiList.map(item => ({ ...item, connected: item.ssid === selectedSsid })), @@ -143,7 +156,9 @@ Page({ this.setData({ selectedSsid: '', selectWifiPWD: '' }) wx.showToast({ title: err?.message || '配网失败', icon: 'none' }) // 配网失败:延时 1.5s 后清空数据并重新获取 WiFi 列表 - setTimeout(() => { + if (retryTimer !== null) { clearTimeout(retryTimer); retryTimer = null } + retryTimer = setTimeout(() => { + retryTimer = null this.onStartSearch() }, 1500) } diff --git a/miniprogram/pages/connectedWifi/connectedWifi.wxml b/miniprogram/pages/connectedWifi/connectedWifi.wxml index 4e2798b..3292315 100644 --- a/miniprogram/pages/connectedWifi/connectedWifi.wxml +++ b/miniprogram/pages/connectedWifi/connectedWifi.wxml @@ -16,6 +16,7 @@ @@ -24,6 +25,7 @@