[AI Generated]: feat(*): 新增蓝牙保活机制、设备初始化功能及用户双向同步逻辑

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
17792275749
2026-03-11 13:36:06 +08:00
co-authored by Claude Opus 4.6
parent 0a6578c2c9
commit c41c7d9f63
5 changed files with 149 additions and 42 deletions
+102 -40
View File
@@ -59,6 +59,32 @@ Component({
// 组件的方法 // 组件的方法
methods: { methods: {
// 长按型号区域初始化设备
onDeviceLongPress() {
wx.showModal({
title: "提示",
content: "确定要初始化设备吗?将清除设备中的所有数据(用户信息、历史数据、配网数据、设置信息)。",
success: (res) => {
if (res.confirm) {
wx.showLoading({ title: "正在初始化设备...", mask: true });
app.globalData.ppScale.activeProtocol.codeClearDeviceData("00", (status) => {
wx.hideLoading();
if (status == 0) {
wx.showToast({ title: "设备初始化成功", icon: "success" });
// 断开蓝牙连接并返回上一页
app.globalData.ppScale.plugin.Blue.stop();
setTimeout(() => {
wx.navigateBack({ delta: 1 });
}, 1500);
} else {
wx.showToast({ title: "设备初始化失败,请重试", icon: "none" });
}
});
}
}
});
},
// 手动重连设备 // 手动重连设备
connectedDevice() { connectedDevice() {
app.resetReconnectCount(); app.resetReconnectCount();
@@ -148,68 +174,104 @@ Component({
return; return;
} }
// 获取设备端已有用户,只下发新用户 // 获取设备端已有用户,与用户列表做双向同步
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 : []; let rawList = Array.isArray(deviceUserIds) ? deviceUserIds : [];
// 兼容对象数组和纯ID数组,统一转为字符串比对 // 兼容对象数组和纯ID数组,统一转为字符串比对
let existIds = rawList.map(item => String(item.userID || item)); let deviceIds = rawList.map(item => ({
let needSyncList = userList.filter(user => !existIds.includes(String(user.id))); userID: String(item.userID || item),
console.log(needSyncList); memberID: String(item.memberID || "")
if (!needSyncList.length) { }));
let localIds = userList.map(user => String(user.id));
// 秤有、列表没有 → 需要从秤删除
let needDeleteList = deviceIds.filter(d => !localIds.includes(d.userID));
// 秤没有、列表有 → 需要下发到秤
let needSyncList = userList.filter(user => !deviceIds.some(d => d.userID === String(user.id)));
console.log("需删除", needDeleteList, "需下发", needSyncList);
// 无需操作时直接完成
if (!needDeleteList.length && !needSyncList.length) {
wx.hideLoading(); wx.hideLoading();
wx.showToast({ wx.showToast({ title: "用户信息已同步", icon: "success" });
title: "用户信息已同步",
icon: "success"
})
setTimeout(() => { setTimeout(() => {
this.triggerEvent('deviceEvent', { status: true }); this.triggerEvent('deviceEvent', { status: true });
}, 1500) }, 1500);
return; return;
} }
let index = 0; // 第一步:逐个下发新用户到秤
let syncIndex = 0;
const syncNext = () => { const syncNext = () => {
if (index >= needSyncList.length) { if (syncIndex >= needSyncList.length) {
wx.hideLoading(); // 下发完成,开始删除
wx.showToast({ if (needDeleteList.length) {
title: "用户信息下发成功", wx.showLoading({ title: "正在删除多余用户...", mask: true });
icon: "success" }
}) deleteNext();
setTimeout(() => {
this.triggerEvent('deviceEvent', { status: true });
}, 1500)
return; return;
} }
let user = needSyncList[index]; wx.showLoading({ title: "正在下发第" + (syncIndex + 1) + "/" + needSyncList.length + "个用户...", mask: true });
let user = needSyncList[syncIndex];
app.globalData.ppScale.activeProtocol.dataSyncUserInfo({ app.globalData.ppScale.activeProtocol.dataSyncUserInfo({
userID: user.id, // 用户唯一标识 ID。 userID: user.id,
userName: user.realname, // 用户昵称/姓名。 userName: user.realname,
memberID: "", // 成员 ID(用于区分主账号下的子成员,例如一家人共用一台体脂秤)。 memberID: "",
age: user.age, // 年龄。 age: user.age,
gender: user.sex, // 性别(通常 0 代表女性,1 代表男性,或者根据具体协议定义)。 gender: user.sex,
height: user.height, // 身高(单位通常为 cm)。 height: user.height,
isAthleteMode: 0, // 运动员模式开关(0 表示普通人,1 表示运动员。该模式会影响体脂率等算法的计算)。 isAthleteMode: 0,
deviceHeaderIndex: index, // 设备头像索引(用于在秤端或 App 列表显示的头像图标编号)。 deviceHeaderIndex: syncIndex,
currentWeight: String(user.weight), // 当前体重。 currentWeight: String(user.weight),
targetWeight: "", // 目标体重。 targetWeight: "",
idealWeight: "", // 理想体重(通常由系统根据身高、年龄自动计算得出)。 idealWeight: "",
recentData: [], recentData: [],
}, (res) => { }, (res) => {
if (res == 0) { if (res == 0) {
index++; syncIndex++;
syncNext(); syncNext();
} else { } else {
wx.hideLoading(); wx.hideLoading();
console.log("dataSyncUserInfo", res); console.log("dataSyncUserInfo 失败", res);
wx.showToast({ wx.showToast({ title: "用户信息下发失败,请重试。", icon: "none" });
title: "用户信息下发失败,请重试。",
icon: "none"
})
} }
}) });
}; };
// 第二步:逐个删除秤端多余用户
let delIndex = 0;
const deleteNext = () => {
if (delIndex >= needDeleteList.length) {
// 全部完成
wx.hideLoading();
wx.showToast({ title: "用户信息同步成功", icon: "success" });
setTimeout(() => {
this.triggerEvent('deviceEvent', { status: true });
}, 1500);
return;
}
wx.showLoading({ title: "正在删除第" + (delIndex + 1) + "/" + needDeleteList.length + "个多余用户...", mask: true });
let item = needDeleteList[delIndex];
app.globalData.ppScale.activeProtocol.dataDeleteUser({
userID: item.userID,
memberID: item.memberID
}, (status) => {
if (status == 0) {
delIndex++;
deleteNext();
} else {
wx.hideLoading();
console.log("dataDeleteUser 失败", status);
wx.showToast({ title: "删除设备用户失败,请重试。", icon: "none" });
}
});
};
// 从下发开始执行
syncNext(); syncNext();
}); });
}, },
@@ -2,7 +2,7 @@
<view class="header"> <view class="header">
<view> <view>
<view>智能蓝牙秤</view> <view>智能蓝牙秤</view>
<view>型号:{{device.name}}</view> <view bind:longpress="onDeviceLongPress">型号:{{device.name}}</view>
</view> </view>
<view> <view>
<block wx:if="{{connectState == BLUE_STATE.CONNECTSUCCESS || connectState == BLUE_STATE.WIFISUCCESS}}"> <block wx:if="{{connectState == BLUE_STATE.CONNECTSUCCESS || connectState == BLUE_STATE.WIFISUCCESS}}">
@@ -100,7 +100,7 @@ Component({
}, },
netWorkCallBack(res) { netWorkCallBack(res) {
if(res === 23) { if(res == 23) {
app.globalData.ppScale.wifi.ssid = this.data.selectWifi.ssid; app.globalData.ppScale.wifi.ssid = this.data.selectWifi.ssid;
app.globalData.ppScale.wifi.password = this.data.selectWifiPWD; app.globalData.ppScale.wifi.password = this.data.selectWifiPWD;
+23
View File
@@ -48,6 +48,7 @@ Page({
ppScale.device.connection = this.data.device; ppScale.device.connection = this.data.device;
wx.hideLoading(); wx.hideLoading();
this._startKeepAlive();
// 配网步骤:重新获取 WiFi 列表 // 配网步骤:重新获取 WiFi 列表
if (currentStep === 2) { if (currentStep === 2) {
@@ -68,6 +69,7 @@ Page({
console.log("===》codeSyncTime", codeSyncTime) console.log("===》codeSyncTime", codeSyncTime)
wx.hideLoading(); wx.hideLoading();
this._startKeepAlive();
ppScale.device.name = this.data.device.name; ppScale.device.name = this.data.device.name;
ppScale.device.connection = this.data.device; ppScale.device.connection = this.data.device;
const nameArr = this.data.device.name.split("-"); const nameArr = this.data.device.name.split("-");
@@ -175,6 +177,25 @@ Page({
} }
}, },
// 启动保活定时器,每10秒发送一次保活指令
_keepAliveTimer: null,
_startKeepAlive() {
this._stopKeepAlive();
this._keepAliveTimer = setInterval(() => {
if (ppScale.activeProtocol) {
ppScale.activeProtocol.sendKeepAliveCode();
}
}, 15000);
},
// 清除保活定时器
_stopKeepAlive() {
if (this._keepAliveTimer) {
clearInterval(this._keepAliveTimer);
this._keepAliveTimer = null;
}
},
checkBluetoothPermissionAndInit() { checkBluetoothPermissionAndInit() {
wx.getSetting({ wx.getSetting({
success: (res) => { success: (res) => {
@@ -233,6 +254,7 @@ Page({
onHide() { onHide() {
console.log("configureDevice onHide"); console.log("configureDevice onHide");
this._stopKeepAlive();
// 配网步骤:立即清空 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');
@@ -254,6 +276,7 @@ Page({
onUnload() { onUnload() {
console.log("configureDevice onUnload"); console.log("configureDevice onUnload");
this._stopKeepAlive();
app.resetReconnectCount(); app.resetReconnectCount();
app.setGlobalData('ppScale.device.connectState', null); app.setGlobalData('ppScale.device.connectState', null);
this._connectReady = false; this._connectReady = false;
+22
View File
@@ -64,6 +64,7 @@ Page({
app.globalData.ppScale.version = nameArr.length === 5 ? "domain2" : "domain1"; app.globalData.ppScale.version = nameArr.length === 5 ? "domain2" : "domain1";
wx.hideLoading(); wx.hideLoading();
this._startKeepAlive();
// 仅在 WiFi 列表步骤时获取列表(组件只在 progress === 0 时渲染) // 仅在 WiFi 列表步骤时获取列表(组件只在 progress === 0 时渲染)
if (this.data.progress === 0) { if (this.data.progress === 0) {
const comp = this.selectComponent('#replaceNetwork1Component'); const comp = this.selectComponent('#replaceNetwork1Component');
@@ -275,8 +276,28 @@ Page({
} }
}, },
// 启动保活定时器,每10秒发送一次保活指令
_keepAliveTimer: null,
_startKeepAlive() {
this._stopKeepAlive();
this._keepAliveTimer = setInterval(() => {
if (app.globalData.ppScale.activeProtocol) {
app.globalData.ppScale.activeProtocol.sendKeepAliveCode();
}
}, 15000);
},
// 清除保活定时器
_stopKeepAlive() {
if (this._keepAliveTimer) {
clearInterval(this._keepAliveTimer);
this._keepAliveTimer = null;
}
},
onHide() { onHide() {
console.log("replaceNetwork onHide"); console.log("replaceNetwork onHide");
this._stopKeepAlive();
app.resetReconnectCount(); app.resetReconnectCount();
app.setGlobalData('ppScale.device.connectState', null); app.setGlobalData('ppScale.device.connectState', null);
app.globalData.ppScale.plugin.Blue.stop(); app.globalData.ppScale.plugin.Blue.stop();
@@ -285,6 +306,7 @@ Page({
// 卸载事件监听 // 卸载事件监听
onUnload() { onUnload() {
console.log("replaceNetwork onUnload"); console.log("replaceNetwork onUnload");
this._stopKeepAlive();
app.resetReconnectCount(); app.resetReconnectCount();
app.setGlobalData('ppScale.device.connectState', null); app.setGlobalData('ppScale.device.connectState', null);
app.globalData.ppScale.plugin.Blue.stop(); app.globalData.ppScale.plugin.Blue.stop();