[AI Generated]: fix(*): 修复蓝牙连接全链路问题,包含 bus 重复订阅、activeProtocol 空指针、stop 竞速、重连计数器跨页面共享、OTA 超时保护、硬超时改事件驱动、保活定时器泄漏及回调错误处理
This commit is contained in:
@@ -95,7 +95,10 @@ Component({
|
||||
|
||||
addUser() {
|
||||
if (this.data.userList.length >= 10) {
|
||||
wx.showToast({ title: "超过最大用户数", icon: "none" });
|
||||
wx.showToast({
|
||||
title: "超过最大用户数",
|
||||
icon: "none"
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.selectComponent("#configureDevice2AddUser").showModal();
|
||||
@@ -178,19 +181,27 @@ Component({
|
||||
wx.showLoading({ title: "正在同步用户信息...", mask: true });
|
||||
app.globalData.ppScale.activeProtocol.dataFetchUserID((deviceUserIds) => {
|
||||
console.log("设备端已有用户ID列表", deviceUserIds);
|
||||
let rawList = Array.isArray(deviceUserIds) ? deviceUserIds : [];
|
||||
|
||||
// 回调返回非数组视为获取失败
|
||||
if (!Array.isArray(deviceUserIds)) {
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: "获取设备用户列表失败,请重试", icon: "none" });
|
||||
return;
|
||||
}
|
||||
|
||||
let rawList = deviceUserIds;
|
||||
// 兼容对象数组和纯ID数组,统一转为字符串比对
|
||||
let deviceIds = rawList.map(item => ({
|
||||
id: item,
|
||||
memberID: ""
|
||||
}));
|
||||
let localIds = userList.map(user => user.id);
|
||||
let localIds = userList.map(user => user.userId);
|
||||
|
||||
// 秤有、列表没有 → 需要从秤删除
|
||||
let needDeleteList = deviceIds.filter(d => !localIds.includes(d.id));
|
||||
let needDeleteList = deviceIds.filter(d => !localIds.includes(d.userId));
|
||||
|
||||
// 秤没有、列表有 → 需要下发到秤
|
||||
let needSyncList = userList.filter(user => !deviceIds.some(d => d.userID == user.id));
|
||||
let needSyncList = userList.filter(user => !deviceIds.some(d => d.userID == user.userId));
|
||||
|
||||
console.log("需删除", needDeleteList, "需下发", needSyncList);
|
||||
|
||||
@@ -218,7 +229,7 @@ Component({
|
||||
wx.showLoading({ title: "正在下发第" + (syncIndex + 1) + "/" + needSyncList.length + "个用户...", mask: true });
|
||||
let user = needSyncList[syncIndex];
|
||||
app.globalData.ppScale.activeProtocol.dataSyncUserInfo({
|
||||
userID: user.id,
|
||||
userID: user.userId,
|
||||
userName: user.realname,
|
||||
memberID: "",
|
||||
age: user.age || '',
|
||||
@@ -257,7 +268,7 @@ Component({
|
||||
wx.showLoading({ title: "正在删除第" + (delIndex + 1) + "/" + needDeleteList.length + "个多余用户...", mask: true });
|
||||
let item = needDeleteList[delIndex];
|
||||
app.globalData.ppScale.activeProtocol.dataDeleteUser({
|
||||
userID: item.id,
|
||||
userID: item.userId,
|
||||
memberID: ""
|
||||
}, (status) => {
|
||||
if (status == 0) {
|
||||
|
||||
@@ -14,31 +14,28 @@ Component({
|
||||
|
||||
lifetimes: {
|
||||
attached() {
|
||||
this.initWifi();
|
||||
// WiFi 列表获取由父页面在 activeProtocol 就绪后显式调用,此处不自动触发
|
||||
},
|
||||
detached() {
|
||||
// 在组件实例被从页面节点树移除时执行
|
||||
console.log('MyComponent detached!');
|
||||
console.log('configureDevice3 detached');
|
||||
}
|
||||
},
|
||||
|
||||
// 组件的方法
|
||||
methods: {
|
||||
initWifi() {
|
||||
wx.showLoading({
|
||||
title: "正在获取Wi-Fi列表...",
|
||||
mask: true
|
||||
wx.showLoading({ title: "正在获取Wi-Fi列表...", mask: true });
|
||||
// activeProtocol 由父页面在 deviceConnect 回调中赋值,此处直接使用
|
||||
const activeProtocol = app.globalData.ppScale.activeProtocol;
|
||||
if (!activeProtocol) {
|
||||
wx.hideLoading();
|
||||
wx.showToast({ title: '设备未连接,请重试', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
activeProtocol.dataFindSurroundDevice((res) => {
|
||||
wx.hideLoading();
|
||||
this.setData({ wifiList: res });
|
||||
});
|
||||
// 重新获取协议实例,避免用户同步操作后旧引用失效
|
||||
setTimeout(() => {
|
||||
app.globalData.ppScale.activeProtocol = app.globalData.ppScale.plugin.ScaleAction.getActiveProtocol();
|
||||
app.globalData.ppScale.activeProtocol.dataFindSurroundDevice((res) => {
|
||||
wx.hideLoading();
|
||||
this.setData({
|
||||
wifiList: res
|
||||
})
|
||||
})
|
||||
}, 1500);
|
||||
},
|
||||
|
||||
// 最小化后重连,重置所有状态并重新获取 WiFi 列表
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
const app = getApp();
|
||||
|
||||
// OTA 超时时间:3 分钟
|
||||
const OTA_TIMEOUT_MS = 3 * 60 * 1000;
|
||||
|
||||
Component({
|
||||
data: {
|
||||
otaProgress: 0,
|
||||
@@ -9,8 +12,11 @@ Component({
|
||||
|
||||
lifetimes: {
|
||||
attached() {
|
||||
// 组件挂载后自动触发 OTA 升级
|
||||
this.startOtaUpgrade();
|
||||
// OTA 升级由父页面在 activeProtocol 就绪后显式调用,此处不自动触发
|
||||
},
|
||||
detached() {
|
||||
// 组件销毁时清除超时定时器,防止泄漏
|
||||
this._clearOtaTimer();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -20,6 +26,14 @@ Component({
|
||||
this.triggerEvent('deviceEvent', { status: true });
|
||||
},
|
||||
|
||||
// 清除 OTA 超时定时器
|
||||
_clearOtaTimer() {
|
||||
if (this._otaTimer) {
|
||||
clearTimeout(this._otaTimer);
|
||||
this._otaTimer = null;
|
||||
}
|
||||
},
|
||||
|
||||
// 开始 OTA 升级
|
||||
startOtaUpgrade() {
|
||||
const activeProtocol = app.globalData.ppScale.activeProtocol;
|
||||
@@ -37,6 +51,13 @@ Component({
|
||||
otaMessage: '升级初始化中...'
|
||||
});
|
||||
|
||||
// 启动超时保护,3 分钟内未完成则视为失败
|
||||
this._clearOtaTimer();
|
||||
this._otaTimer = setTimeout(() => {
|
||||
console.log('OTA 升级超时');
|
||||
this.handleOtaFailed('升级超时,设备即将重启');
|
||||
}, OTA_TIMEOUT_MS);
|
||||
|
||||
// 回调参数为 { progress, isFailed }
|
||||
activeProtocol.codeOtaUpdate((res) => {
|
||||
console.log('OTA 升级回调:', res);
|
||||
@@ -49,8 +70,10 @@ Component({
|
||||
}
|
||||
|
||||
if (res && res.isFailed === false) {
|
||||
this._clearOtaTimer();
|
||||
this.handleOtaSuccess();
|
||||
} else if (res && res.isFailed === true) {
|
||||
this._clearOtaTimer();
|
||||
this.handleOtaFailed();
|
||||
}
|
||||
});
|
||||
@@ -66,21 +89,22 @@ Component({
|
||||
});
|
||||
wx.showToast({ title: 'OTA 升级成功', icon: 'success', duration: 2000 });
|
||||
setTimeout(() => {
|
||||
this.triggerEvent('deviceEvent', { status: true });
|
||||
this.bindOk();
|
||||
}, 2000);
|
||||
},
|
||||
|
||||
// OTA 升级失败处理
|
||||
handleOtaFailed() {
|
||||
handleOtaFailed(msg) {
|
||||
wx.hideLoading();
|
||||
const message = msg || '升级失败,设备即将重启';
|
||||
this.setData({
|
||||
otaProgress: 0,
|
||||
otaStatus: 'failed',
|
||||
otaMessage: '升级失败,设备即将重启'
|
||||
otaMessage: message
|
||||
});
|
||||
wx.showToast({ title: '升级失败,设备即将重启', icon: 'none', duration: 2000 });
|
||||
wx.showToast({ title: message, icon: 'none', duration: 2000 });
|
||||
setTimeout(() => {
|
||||
this.triggerEvent('deviceEvent', { status: true });
|
||||
this.bindOk();
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user