[AI Generated]: fix(*): 修复蓝牙连接全链路问题,包含 bus 重复订阅、activeProtocol 空指针、stop 竞速、重连计数器跨页面共享、OTA 超时保护、硬超时改事件驱动、保活定时器泄漏及回调错误处理
This commit is contained in:
@@ -6,7 +6,7 @@ App({
|
|||||||
globalData: {
|
globalData: {
|
||||||
// wx.request 请求的服务地址
|
// wx.request 请求的服务地址
|
||||||
// wxRequestUrl: "https://device.shuziweidao.com/gateway/",
|
// wxRequestUrl: "https://device.shuziweidao.com/gateway/",
|
||||||
wxRequestUrl: "http://192.168.1.209:8889/",
|
wxRequestUrl: "http://192.168.1.207:8889/",
|
||||||
|
|
||||||
// 秤的所有信息
|
// 秤的所有信息
|
||||||
ppScale: {
|
ppScale: {
|
||||||
@@ -14,8 +14,8 @@ App({
|
|||||||
|
|
||||||
plugin: null,
|
plugin: null,
|
||||||
activeProtocol: null,
|
activeProtocol: null,
|
||||||
domain1: "http://device.shuziweidao.com:80/gateway", // 老版本 没有鉴权
|
domain1: "http://192.168.1.207:8889", // 老版本 没有鉴权
|
||||||
domain2: "http://device.shuziweidao.com:80/weight", // 新版本 有鉴权
|
domain2: "http://192.168.1.207:8889/weight", // 新版本 有鉴权
|
||||||
wifi: {
|
wifi: {
|
||||||
ssid: "",
|
ssid: "",
|
||||||
password: ""
|
password: ""
|
||||||
@@ -136,75 +136,118 @@ App({
|
|||||||
mac: null, // 选中的设备mac地址/SN码
|
mac: null, // 选中的设备mac地址/SN码
|
||||||
connection: null, // 默认选中连接的设备
|
connection: null, // 默认选中连接的设备
|
||||||
connectState: null, // 当前连接设备的状态
|
connectState: null, // 当前连接设备的状态
|
||||||
|
},
|
||||||
|
reconnect: {
|
||||||
|
count: 0, // 当前已重连次数
|
||||||
|
max: 3, // 最大重连次数
|
||||||
|
timer: null // 重连定时器
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_callbacks: {} // 用于存储所有 globalData 属性的监听回调
|
_callbacks: {} // 用于存储所有 globalData 属性的监听回调
|
||||||
},
|
},
|
||||||
|
|
||||||
_reconnectCount: 0, // 自动重连已尝试次数
|
_reconnectCount: 0, // 已废弃,保留兼容,实际使用 globalData.ppScale.reconnect.count
|
||||||
_reconnectMax: 3, // 最大自动重连次数
|
_reconnectMax: 3, // 已废弃,保留兼容,实际使用 globalData.ppScale.reconnect.max
|
||||||
_reconnectTimer: null, // 重连定时器
|
_reconnectTimer: null, // 已废弃,保留兼容,实际使用 globalData.ppScale.reconnect.timer
|
||||||
|
|
||||||
initPpScale() {
|
initPpScale() {
|
||||||
this.globalData.ppScale.plugin = requirePlugin('ppScale-plugin');
|
this.globalData.ppScale.plugin = requirePlugin('ppScale-plugin');
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
// 存储 app 级 bus 回调引用,用于精准 unsubscribe
|
||||||
* 注册全局 bus 事件监听(connectState / syncDeviceTimeSuccess / deviceWillDisconnect)
|
_busCallbacks: {
|
||||||
* stop() 会销毁所有订阅,页面在 onShow 中需重新调用此方法
|
connectState: null,
|
||||||
*/
|
syncDeviceTimeSuccess: null,
|
||||||
registerBusListeners() {
|
deviceWillDisconnect: null,
|
||||||
const plugin = this.globalData.ppScale.plugin;
|
|
||||||
|
|
||||||
// 蓝牙连接状态监听
|
|
||||||
plugin.bus.subscribe("connectState", (res) => {
|
|
||||||
console.log("app.js ===> connectState", res);
|
|
||||||
this.setGlobalData('ppScale.device.connectState', res);
|
|
||||||
|
|
||||||
// 连接成功,重置重连计数
|
|
||||||
if (res == plugin.BLUE_STATE.CONNECTSUCCESS) {
|
|
||||||
this._reconnectCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 连接失败,自动重连(最多重试3次)
|
|
||||||
if (res == plugin.BLUE_STATE.CONNECTFAILED) {
|
|
||||||
this.reconnectDevice();
|
|
||||||
}
|
|
||||||
|
|
||||||
wx.hideLoading();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 同步时间
|
|
||||||
plugin.bus.subscribe("syncDeviceTimeSuccess", (res) => {
|
|
||||||
console.log("app.js ===> syncDeviceTimeSuccess", res);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 设备自动断开监听
|
|
||||||
plugin.bus.subscribe("deviceWillDisconnect", (res) => {
|
|
||||||
console.log("app.js ===> deviceWillDisconnect", res);
|
|
||||||
this.setGlobalData('ppScale.device.connectState', plugin.BLUE_STATE.CONNECTFAILED);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自动重连设备,最多重试 _reconnectMax 次,超过后停止,由用户手动重连
|
* 注销全局 bus 事件监听,防止重复订阅叠加
|
||||||
* 流程:先断开旧连接,再重新扫描设备,由页面级 devicesList 订阅自动接管连接
|
*/
|
||||||
|
unregisterBusListeners() {
|
||||||
|
const plugin = this.globalData.ppScale.plugin;
|
||||||
|
if (!plugin) return;
|
||||||
|
const cbs = this._busCallbacks;
|
||||||
|
if (cbs.connectState) {
|
||||||
|
plugin.bus.unsubscribe('connectState', cbs.connectState);
|
||||||
|
cbs.connectState = null;
|
||||||
|
}
|
||||||
|
if (cbs.syncDeviceTimeSuccess) {
|
||||||
|
plugin.bus.unsubscribe('syncDeviceTimeSuccess', cbs.syncDeviceTimeSuccess);
|
||||||
|
cbs.syncDeviceTimeSuccess = null;
|
||||||
|
}
|
||||||
|
if (cbs.deviceWillDisconnect) {
|
||||||
|
plugin.bus.unsubscribe('deviceWillDisconnect', cbs.deviceWillDisconnect);
|
||||||
|
cbs.deviceWillDisconnect = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册全局 bus 事件监听(connectState / syncDeviceTimeSuccess / deviceWillDisconnect)
|
||||||
|
* 调用前先 unsubscribe 旧的,防止多次 onShow 导致回调叠加
|
||||||
|
*/
|
||||||
|
registerBusListeners() {
|
||||||
|
this.unregisterBusListeners();
|
||||||
|
const plugin = this.globalData.ppScale.plugin;
|
||||||
|
|
||||||
|
// 蓝牙连接状态监听
|
||||||
|
this._busCallbacks.connectState = (res) => {
|
||||||
|
console.log("app.js ===> connectState", res);
|
||||||
|
this.setGlobalData('ppScale.device.connectState', res);
|
||||||
|
if (res == plugin.BLUE_STATE.CONNECTSUCCESS) {
|
||||||
|
this.globalData.ppScale.reconnect.count = 0;
|
||||||
|
}
|
||||||
|
if (res == plugin.BLUE_STATE.CONNECTFAILED) {
|
||||||
|
this.reconnectDevice();
|
||||||
|
}
|
||||||
|
wx.hideLoading();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 同步时间
|
||||||
|
this._busCallbacks.syncDeviceTimeSuccess = (res) => {
|
||||||
|
console.log("app.js ===> syncDeviceTimeSuccess", res);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 设备自动断开监听
|
||||||
|
this._busCallbacks.deviceWillDisconnect = (res) => {
|
||||||
|
console.log("app.js ===> deviceWillDisconnect", res);
|
||||||
|
this.setGlobalData('ppScale.device.connectState', plugin.BLUE_STATE.CONNECTFAILED);
|
||||||
|
};
|
||||||
|
|
||||||
|
plugin.bus.subscribe('connectState', this._busCallbacks.connectState);
|
||||||
|
plugin.bus.subscribe('syncDeviceTimeSuccess', this._busCallbacks.syncDeviceTimeSuccess);
|
||||||
|
plugin.bus.subscribe('deviceWillDisconnect', this._busCallbacks.deviceWillDisconnect);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动重连设备,最多重试 max 次,超过后停止,由用户手动重连
|
||||||
|
* 只在配置页(configureDevice)活跃时执行,防止跨页面干扰
|
||||||
*/
|
*/
|
||||||
reconnectDevice() {
|
reconnectDevice() {
|
||||||
if (this._reconnectCount >= this._reconnectMax) {
|
const reconnect = this.globalData.ppScale.reconnect;
|
||||||
|
|
||||||
|
// 仅在配置页活跃时执行重连
|
||||||
|
const pages = getCurrentPages();
|
||||||
|
const currentPage = pages[pages.length - 1];
|
||||||
|
if (!currentPage || !currentPage.route || !currentPage.route.includes('configureDevice')) {
|
||||||
|
console.log("app.js ===> 非配置页,跳过自动重连");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reconnect.count >= reconnect.max) {
|
||||||
console.log("app.js ===> 自动重连已达上限,等待用户手动重试");
|
console.log("app.js ===> 自动重连已达上限,等待用户手动重试");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._reconnectCount++;
|
reconnect.count++;
|
||||||
console.log(`app.js ===> 自动重连第 ${this._reconnectCount}/${this._reconnectMax} 次`);
|
console.log(`app.js ===> 自动重连第 ${reconnect.count}/${reconnect.max} 次`);
|
||||||
|
|
||||||
// 延迟 2 秒后重连,避免连续冲突
|
// 延迟 2 秒后重连,避免连续冲突
|
||||||
if (this._reconnectTimer) {
|
if (reconnect.timer) {
|
||||||
clearTimeout(this._reconnectTimer);
|
clearTimeout(reconnect.timer);
|
||||||
}
|
}
|
||||||
this._reconnectTimer = setTimeout(() => {
|
reconnect.timer = setTimeout(() => {
|
||||||
this.globalData.ppScale.plugin.Blue.disconnect((disres) => {
|
this.globalData.ppScale.plugin.Blue.disconnect((disres) => {
|
||||||
if (disres.errCode == 0) {
|
if (disres.errCode == 0) {
|
||||||
console.log("app.js ===> 断开成功,开始重新扫描设备");
|
console.log("app.js ===> 断开成功,开始重新扫描设备");
|
||||||
@@ -217,13 +260,14 @@ App({
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 重置重连计数,用于用户手动点击重试时调用
|
* 重置重连计数,用于用户手动点击重试或页面离开时调用
|
||||||
*/
|
*/
|
||||||
resetReconnectCount() {
|
resetReconnectCount() {
|
||||||
this._reconnectCount = 0;
|
const reconnect = this.globalData.ppScale.reconnect;
|
||||||
if (this._reconnectTimer) {
|
reconnect.count = 0;
|
||||||
clearTimeout(this._reconnectTimer);
|
if (reconnect.timer) {
|
||||||
this._reconnectTimer = null;
|
clearTimeout(reconnect.timer);
|
||||||
|
reconnect.timer = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,10 @@ Component({
|
|||||||
|
|
||||||
addUser() {
|
addUser() {
|
||||||
if (this.data.userList.length >= 10) {
|
if (this.data.userList.length >= 10) {
|
||||||
wx.showToast({ title: "超过最大用户数", icon: "none" });
|
wx.showToast({
|
||||||
|
title: "超过最大用户数",
|
||||||
|
icon: "none"
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.selectComponent("#configureDevice2AddUser").showModal();
|
this.selectComponent("#configureDevice2AddUser").showModal();
|
||||||
@@ -178,19 +181,27 @@ Component({
|
|||||||
wx.showLoading({ title: "正在同步用户信息...", mask: true });
|
wx.showLoading({ title: "正在同步用户信息...", mask: true });
|
||||||
app.globalData.ppScale.activeProtocol.dataFetchUserID((deviceUserIds) => {
|
app.globalData.ppScale.activeProtocol.dataFetchUserID((deviceUserIds) => {
|
||||||
console.log("设备端已有用户ID列表", 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数组,统一转为字符串比对
|
// 兼容对象数组和纯ID数组,统一转为字符串比对
|
||||||
let deviceIds = rawList.map(item => ({
|
let deviceIds = rawList.map(item => ({
|
||||||
id: item,
|
id: item,
|
||||||
memberID: ""
|
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);
|
console.log("需删除", needDeleteList, "需下发", needSyncList);
|
||||||
|
|
||||||
@@ -218,7 +229,7 @@ Component({
|
|||||||
wx.showLoading({ title: "正在下发第" + (syncIndex + 1) + "/" + needSyncList.length + "个用户...", mask: true });
|
wx.showLoading({ title: "正在下发第" + (syncIndex + 1) + "/" + needSyncList.length + "个用户...", mask: true });
|
||||||
let user = needSyncList[syncIndex];
|
let user = needSyncList[syncIndex];
|
||||||
app.globalData.ppScale.activeProtocol.dataSyncUserInfo({
|
app.globalData.ppScale.activeProtocol.dataSyncUserInfo({
|
||||||
userID: user.id,
|
userID: user.userId,
|
||||||
userName: user.realname,
|
userName: user.realname,
|
||||||
memberID: "",
|
memberID: "",
|
||||||
age: user.age || '',
|
age: user.age || '',
|
||||||
@@ -257,7 +268,7 @@ Component({
|
|||||||
wx.showLoading({ title: "正在删除第" + (delIndex + 1) + "/" + needDeleteList.length + "个多余用户...", mask: true });
|
wx.showLoading({ title: "正在删除第" + (delIndex + 1) + "/" + needDeleteList.length + "个多余用户...", mask: true });
|
||||||
let item = needDeleteList[delIndex];
|
let item = needDeleteList[delIndex];
|
||||||
app.globalData.ppScale.activeProtocol.dataDeleteUser({
|
app.globalData.ppScale.activeProtocol.dataDeleteUser({
|
||||||
userID: item.id,
|
userID: item.userId,
|
||||||
memberID: ""
|
memberID: ""
|
||||||
}, (status) => {
|
}, (status) => {
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
|
|||||||
@@ -14,31 +14,28 @@ Component({
|
|||||||
|
|
||||||
lifetimes: {
|
lifetimes: {
|
||||||
attached() {
|
attached() {
|
||||||
this.initWifi();
|
// WiFi 列表获取由父页面在 activeProtocol 就绪后显式调用,此处不自动触发
|
||||||
},
|
},
|
||||||
detached() {
|
detached() {
|
||||||
// 在组件实例被从页面节点树移除时执行
|
console.log('configureDevice3 detached');
|
||||||
console.log('MyComponent detached!');
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 组件的方法
|
// 组件的方法
|
||||||
methods: {
|
methods: {
|
||||||
initWifi() {
|
initWifi() {
|
||||||
wx.showLoading({
|
wx.showLoading({ title: "正在获取Wi-Fi列表...", mask: true });
|
||||||
title: "正在获取Wi-Fi列表...",
|
// activeProtocol 由父页面在 deviceConnect 回调中赋值,此处直接使用
|
||||||
mask: true
|
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 列表
|
// 最小化后重连,重置所有状态并重新获取 WiFi 列表
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
const app = getApp();
|
const app = getApp();
|
||||||
|
|
||||||
|
// OTA 超时时间:3 分钟
|
||||||
|
const OTA_TIMEOUT_MS = 3 * 60 * 1000;
|
||||||
|
|
||||||
Component({
|
Component({
|
||||||
data: {
|
data: {
|
||||||
otaProgress: 0,
|
otaProgress: 0,
|
||||||
@@ -9,8 +12,11 @@ Component({
|
|||||||
|
|
||||||
lifetimes: {
|
lifetimes: {
|
||||||
attached() {
|
attached() {
|
||||||
// 组件挂载后自动触发 OTA 升级
|
// OTA 升级由父页面在 activeProtocol 就绪后显式调用,此处不自动触发
|
||||||
this.startOtaUpgrade();
|
},
|
||||||
|
detached() {
|
||||||
|
// 组件销毁时清除超时定时器,防止泄漏
|
||||||
|
this._clearOtaTimer();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -20,6 +26,14 @@ Component({
|
|||||||
this.triggerEvent('deviceEvent', { status: true });
|
this.triggerEvent('deviceEvent', { status: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 清除 OTA 超时定时器
|
||||||
|
_clearOtaTimer() {
|
||||||
|
if (this._otaTimer) {
|
||||||
|
clearTimeout(this._otaTimer);
|
||||||
|
this._otaTimer = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// 开始 OTA 升级
|
// 开始 OTA 升级
|
||||||
startOtaUpgrade() {
|
startOtaUpgrade() {
|
||||||
const activeProtocol = app.globalData.ppScale.activeProtocol;
|
const activeProtocol = app.globalData.ppScale.activeProtocol;
|
||||||
@@ -37,6 +51,13 @@ Component({
|
|||||||
otaMessage: '升级初始化中...'
|
otaMessage: '升级初始化中...'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 启动超时保护,3 分钟内未完成则视为失败
|
||||||
|
this._clearOtaTimer();
|
||||||
|
this._otaTimer = setTimeout(() => {
|
||||||
|
console.log('OTA 升级超时');
|
||||||
|
this.handleOtaFailed('升级超时,设备即将重启');
|
||||||
|
}, OTA_TIMEOUT_MS);
|
||||||
|
|
||||||
// 回调参数为 { progress, isFailed }
|
// 回调参数为 { progress, isFailed }
|
||||||
activeProtocol.codeOtaUpdate((res) => {
|
activeProtocol.codeOtaUpdate((res) => {
|
||||||
console.log('OTA 升级回调:', res);
|
console.log('OTA 升级回调:', res);
|
||||||
@@ -49,8 +70,10 @@ Component({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (res && res.isFailed === false) {
|
if (res && res.isFailed === false) {
|
||||||
|
this._clearOtaTimer();
|
||||||
this.handleOtaSuccess();
|
this.handleOtaSuccess();
|
||||||
} else if (res && res.isFailed === true) {
|
} else if (res && res.isFailed === true) {
|
||||||
|
this._clearOtaTimer();
|
||||||
this.handleOtaFailed();
|
this.handleOtaFailed();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -66,21 +89,22 @@ Component({
|
|||||||
});
|
});
|
||||||
wx.showToast({ title: 'OTA 升级成功', icon: 'success', duration: 2000 });
|
wx.showToast({ title: 'OTA 升级成功', icon: 'success', duration: 2000 });
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.triggerEvent('deviceEvent', { status: true });
|
this.bindOk();
|
||||||
}, 2000);
|
}, 2000);
|
||||||
},
|
},
|
||||||
|
|
||||||
// OTA 升级失败处理
|
// OTA 升级失败处理
|
||||||
handleOtaFailed() {
|
handleOtaFailed(msg) {
|
||||||
wx.hideLoading();
|
wx.hideLoading();
|
||||||
|
const message = msg || '升级失败,设备即将重启';
|
||||||
this.setData({
|
this.setData({
|
||||||
otaProgress: 0,
|
otaProgress: 0,
|
||||||
otaStatus: 'failed',
|
otaStatus: 'failed',
|
||||||
otaMessage: '升级失败,设备即将重启'
|
otaMessage: message
|
||||||
});
|
});
|
||||||
wx.showToast({ title: '升级失败,设备即将重启', icon: 'none', duration: 2000 });
|
wx.showToast({ title: message, icon: 'none', duration: 2000 });
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.triggerEvent('deviceEvent', { status: true });
|
this.bindOk();
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,22 +16,46 @@ Page({
|
|||||||
// 一次性数据初始化,订阅逻辑在 onShow 中注册
|
// 一次性数据初始化,订阅逻辑在 onShow 中注册
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 存储页面级 bus 回调引用,用于精准 unsubscribe
|
||||||
|
_pageHandlers: {
|
||||||
|
devicesModel: null,
|
||||||
|
deviceConnect: null,
|
||||||
|
devicesList: null,
|
||||||
|
},
|
||||||
|
|
||||||
|
// 注销页面级 bus 订阅
|
||||||
|
_unsubscribePageBus() {
|
||||||
|
const bus = ppScale.plugin.bus;
|
||||||
|
const h = this._pageHandlers;
|
||||||
|
if (h.devicesModel) { bus.unsubscribe('devicesModel', h.devicesModel); h.devicesModel = null; }
|
||||||
|
if (h.deviceConnect) { bus.unsubscribe('deviceConnect', h.deviceConnect); h.deviceConnect = null; }
|
||||||
|
if (h.devicesList) { bus.unsubscribe('devicesList', h.devicesList); h.devicesList = null; }
|
||||||
|
},
|
||||||
|
|
||||||
|
// 记录 stop() 调用时间,用于 onShow 动态计算安全延迟
|
||||||
|
_stopTime: 0,
|
||||||
|
|
||||||
onShow() {
|
onShow() {
|
||||||
console.log("configureDevice onShow");
|
console.log("configureDevice onShow");
|
||||||
// 延迟 300ms 确保 stop() 完全释放后再重新注册(参照官方 demo)
|
// 动态计算距上次 stop() 已过去的时间,确保间隔至少 500ms 再重新注册
|
||||||
|
const elapsed = Date.now() - (this._stopTime || 0);
|
||||||
|
const delay = Math.max(0, 500 - elapsed);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// 重新注册 app 级别的全局 bus 订阅
|
// 重新注册 app 级别的全局 bus 订阅(内部已做 unsubscribe 防重)
|
||||||
app.registerBusListeners();
|
app.registerBusListeners();
|
||||||
|
|
||||||
// 页面级 bus 订阅
|
// 页面级 bus 订阅(先清理旧的,防止重复叠加)
|
||||||
ppScale.plugin.bus.subscribe("devicesModel", (res) => {
|
this._unsubscribePageBus();
|
||||||
|
|
||||||
|
this._pageHandlers.devicesModel = (res) => {
|
||||||
console.log("===》devicesModel", res);
|
console.log("===》devicesModel", res);
|
||||||
ppScale.device.mac = res.deviceMac;
|
ppScale.device.mac = res.deviceMac;
|
||||||
this._macReady = true;
|
this._macReady = true;
|
||||||
this._tryProgress();
|
this._tryProgress();
|
||||||
});
|
};
|
||||||
|
ppScale.plugin.bus.subscribe("devicesModel", this._pageHandlers.devicesModel);
|
||||||
|
|
||||||
ppScale.plugin.bus.subscribe("deviceConnect", (res) => {
|
this._pageHandlers.deviceConnect = (res) => {
|
||||||
console.log('===》deviceConnect', res);
|
console.log('===》deviceConnect', res);
|
||||||
|
|
||||||
ppScale.plugin.ScaleAction.startDataProgress(true);
|
ppScale.plugin.ScaleAction.startDataProgress(true);
|
||||||
@@ -78,18 +102,20 @@ Page({
|
|||||||
this._tryProgress();
|
this._tryProgress();
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
});
|
};
|
||||||
|
ppScale.plugin.bus.subscribe("deviceConnect", this._pageHandlers.deviceConnect);
|
||||||
|
|
||||||
// 如果之前已选择过设备,自动扫描并重连
|
// 如果之前已选择过设备,自动扫描并重连
|
||||||
if (this.data.device) {
|
if (this.data.device) {
|
||||||
wx.showLoading({ title: "正在重新连接...", mask: true });
|
wx.showLoading({ title: "正在重新连接...", mask: true });
|
||||||
ppScale.plugin.bus.subscribe("devicesList", (res) => {
|
this._pageHandlers.devicesList = (res) => {
|
||||||
let fIndex = res.findIndex(item => item.deviceId === this.data.device.deviceId);
|
let fIndex = res.findIndex(item => item.deviceId === this.data.device.deviceId);
|
||||||
if (fIndex >= 0) {
|
if (fIndex >= 0) {
|
||||||
ppScale.plugin.Blue.stopBluetoothDevicesDiscovery();
|
ppScale.plugin.Blue.stopBluetoothDevicesDiscovery();
|
||||||
ppScale.plugin.Blue.createBLEConnection(res[fIndex]);
|
ppScale.plugin.Blue.createBLEConnection(res[fIndex]);
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
ppScale.plugin.bus.subscribe("devicesList", this._pageHandlers.devicesList);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 通过完整链路重新初始化蓝牙(权限检查 → 打开适配器 → start)
|
// 通过完整链路重新初始化蓝牙(权限检查 → 打开适配器 → start)
|
||||||
@@ -153,6 +179,7 @@ Page({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setConfigSuccessful() {
|
setConfigSuccessful() {
|
||||||
|
this._stopKeepAlive();
|
||||||
ppScale.plugin.Blue.stop();
|
ppScale.plugin.Blue.stop();
|
||||||
wx.switchTab({
|
wx.switchTab({
|
||||||
url: "/pages/home/home"
|
url: "/pages/home/home"
|
||||||
@@ -160,9 +187,22 @@ Page({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setProgress() {
|
setProgress() {
|
||||||
this.setData({
|
const newIndex = this.data.progress.index + 1;
|
||||||
["progress.index"]: this.data.progress.index + 1
|
this.setData({ "progress.index": newIndex });
|
||||||
})
|
// 进入步骤2(配网)时,等待组件渲染完成后由父页面显式触发 WiFi 列表获取
|
||||||
|
if (newIndex === 2) {
|
||||||
|
setTimeout(() => {
|
||||||
|
const comp = this.selectComponent('#configureDevice3');
|
||||||
|
if (comp) comp.initWifi();
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
// 进入步骤3(OTA升级)时,等待组件渲染完成后由父页面显式触发升级
|
||||||
|
if (newIndex === 3) {
|
||||||
|
setTimeout(() => {
|
||||||
|
const comp = this.selectComponent('#configureDevice4');
|
||||||
|
if (comp) comp.startOtaUpgrade();
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 连接完成 + mac 获取完成,双条件满足后才进入下一步
|
// 连接完成 + mac 获取完成,双条件满足后才进入下一步
|
||||||
@@ -255,6 +295,8 @@ Page({
|
|||||||
onHide() {
|
onHide() {
|
||||||
console.log("configureDevice onHide");
|
console.log("configureDevice onHide");
|
||||||
this._stopKeepAlive();
|
this._stopKeepAlive();
|
||||||
|
this._unsubscribePageBus();
|
||||||
|
app.unregisterBusListeners();
|
||||||
// 配网步骤:立即清空 WiFi 列表(stop 后数据已失效)
|
// 配网步骤:立即清空 WiFi 列表(stop 后数据已失效)
|
||||||
if (this.data.progress.index === 2) {
|
if (this.data.progress.index === 2) {
|
||||||
const comp = this.selectComponent('#configureDevice3');
|
const comp = this.selectComponent('#configureDevice3');
|
||||||
@@ -271,16 +313,20 @@ Page({
|
|||||||
app.setGlobalData('ppScale.device.connectState', null);
|
app.setGlobalData('ppScale.device.connectState', null);
|
||||||
this._connectReady = false;
|
this._connectReady = false;
|
||||||
this._macReady = false;
|
this._macReady = false;
|
||||||
|
this._stopTime = Date.now();
|
||||||
ppScale.plugin.Blue.stop();
|
ppScale.plugin.Blue.stop();
|
||||||
},
|
},
|
||||||
|
|
||||||
onUnload() {
|
onUnload() {
|
||||||
console.log("configureDevice onUnload");
|
console.log("configureDevice onUnload");
|
||||||
this._stopKeepAlive();
|
this._stopKeepAlive();
|
||||||
|
this._unsubscribePageBus();
|
||||||
|
app.unregisterBusListeners();
|
||||||
app.resetReconnectCount();
|
app.resetReconnectCount();
|
||||||
app.setGlobalData('ppScale.device.connectState', null);
|
app.setGlobalData('ppScale.device.connectState', null);
|
||||||
this._connectReady = false;
|
this._connectReady = false;
|
||||||
this._macReady = false;
|
this._macReady = false;
|
||||||
|
this._stopTime = Date.now();
|
||||||
ppScale.plugin.Blue.stop();
|
ppScale.plugin.Blue.stop();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
<configureDevice3 id="configureDevice3" bind:deviceEvent="setDeviceConfig"></configureDevice3>
|
<configureDevice3 id="configureDevice3" bind:deviceEvent="setDeviceConfig"></configureDevice3>
|
||||||
</block>
|
</block>
|
||||||
<block wx:if="{{progress.index === 3}}">
|
<block wx:if="{{progress.index === 3}}">
|
||||||
<configureDevice4 bind:deviceEvent="setConfigSuccessful"></configureDevice4>
|
<configureDevice4 id="configureDevice4" bind:deviceEvent="setConfigSuccessful"></configureDevice4>
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
Reference in New Issue
Block a user