Files
bodyWeight/app.js
T
17792275749andClaude Opus 4.6 81f9301c64 [AI Generated]: refactor(*): 重构蓝牙生命周期管理,修复最小化后重连与进度跳步问题
- app.js: 提取 registerBusListeners 方法,新增自动重连机制(3次上限)
- configureDevice: bus 订阅迁移至 onShow,deviceConnect 按步骤区分处理逻辑
- configureDevice_2: setUserInfo 兼容 WIFISUCCESS 状态,WXML 覆盖六态
- configureDevice_3: 新增 reInitWifi 方法,最小化后重置 WiFi 列表
- replaceNetwork: 订阅迁移至 onShow,修复 selectComponent 空指针
- replaceNetwork_3: 修复 domain1 配网参数引用错误
- userInfo: 订阅迁移至 onShow,setUserInfo 兼容 WIFISUCCESS
- searchDevice: 移除 onLoad 重复初始化,统一由 onShow 处理
- 所有 BLE 页面统一 onHide/onUnload 清理:resetReconnectCount + setGlobalData(null) + stop()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 17:34:08 +08:00

287 lines
8.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
App({
onLaunch() {
this.initPpScale();
},
globalData: {
// wx.request 请求的服务地址
wxRequestUrl: "https://device.shuziweidao.com/gateway/",
// wxRequestUrl: "http://192.168.1.12:8889/",
// 秤的所有信息
ppScale: {
version: "",
plugin: null,
activeProtocol: null,
domain1: "http://device.shuziweidao.com:80/gateway", // 老版本 没有鉴权
domain2: "http://device.shuziweidao.com:80/weight", // 新版本 有鉴权
wifi: {
ssid: "",
password: ""
},
options: {
key: "lefudc91611833e18d94",
secret: "eQ50JYimMp0X7uhNLj6D3lTEk4TUUvEG7dvaqKM9t1U="
},
device: {
setting: [{
"advLength": 999,
"calorieStatus": 0,
"createBy": null,
"deviceAccuracyType": 2,
"deviceCalcuteType": 3,
"deviceConnectType": 2,
"deviceFuncType": 223,
"deviceName": "CF568_G",
"devicePowerType": 3,
"deviceProtocolType": 3,
"deviceType": 1,
"deviceUnitType": "0,1,11",
"id": 65,
"imgUrl": null,
"macAddressStart": 6,
"remark": null,
"sign": "FF",
"status": 0,
"uhStatus": 1,
"updateBy": null
}, {
"advLength": 999,
"calorieStatus": 0,
"createBy": null,
"deviceAccuracyType": 2,
"deviceCalcuteType": 3,
"deviceConnectType": 2,
"deviceFuncType": 223,
"deviceName": "YX-B4-568-BW",
"devicePowerType": 3,
"deviceProtocolType": 3,
"deviceType": 1,
"deviceUnitType": "0,1,11",
"id": 65,
"imgUrl": null,
"macAddressStart": 6,
"remark": null,
"sign": "FF",
"status": 0,
"uhStatus": 1,
"updateBy": null
}, {
"advLength": 999,
"calorieStatus": 0,
"createBy": null,
"deviceAccuracyType": 2,
"deviceCalcuteType": 4,
"deviceConnectType": 2,
"deviceFuncType": 65759,
"deviceName": "CF636_G",
"devicePowerType": 3,
"deviceProtocolType": 3,
"deviceType": 1,
"deviceUnitType": "0,1,2",
"id": 216,
"imgUrl": null,
"macAddressStart": 6,
"remark": null,
"sign": "FF",
"status": 0,
"uhStatus": 1,
"updateBy": null
}, {
"advLength": 999,
"calorieStatus": 0,
"createBy": null,
"deviceAccuracyType": 2,
"deviceCalcuteType": 4,
"deviceConnectType": 2,
"deviceFuncType": 65759,
"deviceName": "YX-B8-636-BW",
"devicePowerType": 3,
"deviceProtocolType": 3,
"deviceType": 1,
"deviceUnitType": "0,1,2",
"id": 216,
"imgUrl": null,
"macAddressStart": 6,
"remark": null,
"sign": "FF",
"status": 0,
"uhStatus": 1,
"updateBy": null
}, {
"advLength": 999,
"calorieStatus": 0,
"createBy": null,
"deviceAccuracyType": 2,
"deviceCalcuteType": 4,
"deviceConnectType": 2,
"deviceFuncType": 223,
"deviceName": "CF577",
"devicePowerType": 3,
"deviceProtocolType": 3,
"deviceType": 1,
"deviceUnitType": "0,1,11",
"id": 51,
"imgUrl": null,
"macAddressStart": 6,
"remark": null,
"sign": "FF",
"status": 0,
"uhStatus": 1,
"updateBy": null
}], // 即将要搜索周边秤的配置
list: [], // 根据配置搜索到秤的列表
name: "",
mac: null, // 选中的设备mac地址/SN码
connection: null, // 默认选中连接的设备
connectState: null, // 当前连接设备的状态
}
},
_callbacks: {} // 用于存储所有 globalData 属性的监听回调
},
_reconnectCount: 0, // 自动重连已尝试次数
_reconnectMax: 3, // 最大自动重连次数
_reconnectTimer: null, // 重连定时器
initPpScale() {
this.globalData.ppScale.plugin = requirePlugin('ppScale-plugin');
},
/**
* 注册全局 bus 事件监听(connectState / syncDeviceTimeSuccess / deviceWillDisconnect
* stop() 会销毁所有订阅,页面在 onShow 中需重新调用此方法
*/
registerBusListeners() {
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 次,超过后停止,由用户手动重连
* 流程:先断开旧连接,再重新扫描设备,由页面级 devicesList 订阅自动接管连接
*/
reconnectDevice() {
if (this._reconnectCount >= this._reconnectMax) {
console.log("app.js ===> 自动重连已达上限,等待用户手动重试");
return;
}
this._reconnectCount++;
console.log(`app.js ===> 自动重连第 ${this._reconnectCount}/${this._reconnectMax} 次`);
// 延迟 2 秒后重连,避免连续冲突
if (this._reconnectTimer) {
clearTimeout(this._reconnectTimer);
}
this._reconnectTimer = setTimeout(() => {
this.globalData.ppScale.plugin.Blue.disconnect((disres) => {
if (disres.errCode == 0) {
console.log("app.js ===> 断开成功,开始重新扫描设备");
this.globalData.ppScale.plugin.Blue.startBluetoothDevicesDiscovery();
} else {
console.log("app.js ===> 断开失败,errCode:", disres.errCode);
}
});
}, 2000);
},
/**
* 重置重连计数,用于用户手动点击重试时调用
*/
resetReconnectCount() {
this._reconnectCount = 0;
if (this._reconnectTimer) {
clearTimeout(this._reconnectTimer);
this._reconnectTimer = null;
}
},
/**
* 注册 globalData 某个属性的监听
* @param {string} keyPath 要监听的 globalData 属性路径,例如 'ppScale.device.connectState'
* @param {function} callback 属性变化时执行的回调函数 (newValue, oldValue) => {}
*/
watch(keyPath, callback) {
if (!this.globalData._callbacks[keyPath]) {
this.globalData._callbacks[keyPath] = [];
}
this.globalData._callbacks[keyPath].push(callback);
},
/**
* 取消 globalData 某个属性的监听
* @param {string} keyPath 要取消监听的 globalData 属性路径
* @param {function} callback 之前注册的回调函数
*/
unwatch(keyPath, callback) {
if (this.globalData._callbacks[keyPath]) {
this.globalData._callbacks[keyPath] = this.globalData._callbacks[keyPath].filter(cb => cb !== callback);
}
},
/**
* 设置 globalData 的值并触发所有相关监听器
* 支持点表示法设置嵌套属性,例如 'ppScale.device.connectState'
* @param {string} keyPath 要设置的 globalData 属性路径
* @param {*} value 要设置的新值
*/
setGlobalData(keyPath, value) {
const keys = keyPath.split('.');
let current = this.globalData;
let oldValue = undefined;
// 遍历到目标属性的父级
for (let i = 0; i < keys.length - 1; i++) {
if (!current[keys[i]]) {
current[keys[i]] = {}; // 如果路径不存在,创建空对象
}
current = current[keys[i]];
}
// 获取旧值
oldValue = current[keys[keys.length - 1]];
// 只有当值发生变化时才更新并通知
if (oldValue !== value) {
current[keys[keys.length - 1]] = value; // 设置新值
// 触发监听器
if (this.globalData._callbacks[keyPath]) {
this.globalData._callbacks[keyPath].forEach(callback => {
callback(value, oldValue);
});
}
}
},
})