[AI Generated]: feat(*): 新增蓝牙保活机制、设备初始化功能及用户双向同步逻辑
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
0a6578c2c9
commit
c41c7d9f63
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user