优化设备配置流程,重构用户增删改查及信息下发逻辑
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.6
parent
05b388020b
commit
f89f0f9531
@@ -1,6 +1,25 @@
|
||||
const app = getApp();
|
||||
import $ from "../../utils/request";
|
||||
|
||||
/**
|
||||
* 根据生日计算年龄
|
||||
* @param {string} birthday 生日字符串,如 "1990-05-20"
|
||||
* @returns {number|null} 年龄,无法计算时返回 null
|
||||
*/
|
||||
function calcAge(birthday) {
|
||||
if (!birthday) return null;
|
||||
let birthDate = new Date(birthday.replace(/-/g, '/'));
|
||||
if (isNaN(birthDate.getTime())) return null;
|
||||
let today = new Date();
|
||||
let age = today.getFullYear() - birthDate.getFullYear();
|
||||
let monthDiff = today.getMonth() - birthDate.getMonth();
|
||||
// 未过生日则减一岁
|
||||
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthDate.getDate())) {
|
||||
age--;
|
||||
}
|
||||
return age;
|
||||
}
|
||||
|
||||
Component({
|
||||
data: {
|
||||
BLUE_STATE: {},
|
||||
@@ -49,6 +68,10 @@ Component({
|
||||
},
|
||||
|
||||
addUser() {
|
||||
if (this.data.userList.length >= 10) {
|
||||
wx.showToast({ title: "超过最大用户数", icon: "none" });
|
||||
return;
|
||||
}
|
||||
this.selectComponent("#configureDevice2AddUser").showModal();
|
||||
},
|
||||
|
||||
@@ -61,7 +84,14 @@ Component({
|
||||
let sn = app.globalData.ppScale.device.mac.replace(/:/g, '');
|
||||
$.ajax("weighingScale/v2/select/user", { sn }, "GET", true, "正在获取用户列表...").then(res => {
|
||||
if (res.result && res.result.length) {
|
||||
this.setData({ userList: res.result });
|
||||
let list = res.result.map(user => {
|
||||
// 没有 age 时通过 birthday 计算
|
||||
if (!user.age && user.birthday) {
|
||||
user.age = calcAge(user.birthday);
|
||||
}
|
||||
return user;
|
||||
});
|
||||
this.setData({ userList: list });
|
||||
} else {
|
||||
this.setData({ userList: [] });
|
||||
}
|
||||
@@ -81,12 +111,14 @@ Component({
|
||||
content: "确定要删除该用户吗?",
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
$.ajax("weighingScale/v2/del/user", { id }, "DELETE", true, "正在删除...").then(() => {
|
||||
$.ajax("weighingScale/v2/del/user", { id }, "DELETE", true, "正在删除...", "application/x-www-form-urlencoded").then(() => {
|
||||
wx.showToast({
|
||||
title: "删除成功",
|
||||
icon: "success"
|
||||
})
|
||||
this.fetchUserList();
|
||||
setTimeout(() => {
|
||||
this.fetchUserList();
|
||||
}, 1500)
|
||||
}).catch(() => {
|
||||
wx.showToast({
|
||||
title: "删除失败,请重试",
|
||||
@@ -120,9 +152,11 @@ Component({
|
||||
wx.showLoading({ title: "正在下发用户信息...", mask: true });
|
||||
app.globalData.ppScale.activeProtocol.dataFetchUserID((deviceUserIds) => {
|
||||
console.log("设备端已有用户ID列表", deviceUserIds);
|
||||
let existIds = Array.isArray(deviceUserIds) ? deviceUserIds : [];
|
||||
let needSyncList = userList.filter(user => !existIds.includes(user.userId));
|
||||
|
||||
let rawList = Array.isArray(deviceUserIds) ? deviceUserIds : [];
|
||||
// 兼容对象数组和纯ID数组,统一转为字符串比对
|
||||
let existIds = rawList.map(item => String(item.userID || item));
|
||||
let needSyncList = userList.filter(user => !existIds.includes(String(user.id)));
|
||||
console.log(needSyncList);
|
||||
if (!needSyncList.length) {
|
||||
wx.hideLoading();
|
||||
wx.showToast({
|
||||
@@ -150,17 +184,17 @@ Component({
|
||||
}
|
||||
let user = needSyncList[index];
|
||||
app.globalData.ppScale.activeProtocol.dataSyncUserInfo({
|
||||
userID: user.userId,
|
||||
userName: user.realname,
|
||||
memberID: "",
|
||||
age: user.age,
|
||||
gender: user.sex,
|
||||
height: user.height,
|
||||
isAthleteMode: 0,
|
||||
currentWeight: String(user.weight),
|
||||
deviceHeaderIndex: index,
|
||||
targetWeight: "",
|
||||
idealWeight: "",
|
||||
userID: user.id, // 用户唯一标识 ID。
|
||||
userName: user.realname, // 用户昵称/姓名。
|
||||
memberID: "", // 成员 ID(用于区分主账号下的子成员,例如一家人共用一台体脂秤)。
|
||||
age: user.age, // 年龄。
|
||||
gender: user.sex, // 性别(通常 0 代表女性,1 代表男性,或者根据具体协议定义)。
|
||||
height: user.height, // 身高(单位通常为 cm)。
|
||||
isAthleteMode: 0, // 运动员模式开关(0 表示普通人,1 表示运动员。该模式会影响体脂率等算法的计算)。
|
||||
deviceHeaderIndex: index, // 设备头像索引(用于在秤端或 App 列表显示的头像图标编号)。
|
||||
currentWeight: String(user.weight), // 当前体重。
|
||||
targetWeight: "", // 目标体重。
|
||||
idealWeight: "", // 理想体重(通常由系统根据身高、年龄自动计算得出)。
|
||||
recentData: [],
|
||||
}, (res) => {
|
||||
if (res == 0) {
|
||||
|
||||
@@ -33,49 +33,59 @@
|
||||
</view>
|
||||
<view class="section">
|
||||
<view class="from">
|
||||
<scroll-view class="~scrollView" scroll-y>
|
||||
<view class="scrollViewContent">
|
||||
<block wx:for="{{userList}}" wx:key="userId">
|
||||
<view class="userList">
|
||||
<view class="userAvatar">
|
||||
<block wx:if="{{item.avatar}}">
|
||||
<image src="{{item.avatar}}" />
|
||||
</block>
|
||||
<block wx:else>
|
||||
<block wx:if="{{item.sex === 1}}">
|
||||
<image src="/images/configureDevice/userAvatarMan.png" />
|
||||
<block wx:if="{{userList && userList.length}}">
|
||||
<scroll-view class="~scrollView" scroll-y>
|
||||
<view class="scrollViewContent">
|
||||
<block wx:for="{{userList}}" wx:key="id">
|
||||
<view class="userList">
|
||||
<view class="userAvatar">
|
||||
<block wx:if="{{item.avatar}}">
|
||||
<image src="{{item.avatar}}" />
|
||||
</block>
|
||||
<block wx:else>
|
||||
<image src="/images/configureDevice/userAvatarWoman.png" />
|
||||
<block wx:if="{{item.sex === 1}}">
|
||||
<image src="/images/configureDevice/userAvatarMan.png" />
|
||||
</block>
|
||||
<block wx:else>
|
||||
<image src="/images/configureDevice/userAvatarWoman.png" />
|
||||
</block>
|
||||
</block>
|
||||
</block>
|
||||
</view>
|
||||
<view class="userInfo">
|
||||
<view class="userInfo_1">
|
||||
<view>{{item.realname}}</view>
|
||||
<view class="{{item.sex === 1 ? 'man' : 'woman'}}">
|
||||
<view>
|
||||
<block wx:if="{{item.sex === 1}}">
|
||||
<image src="/images/configureDevice/man.png" />
|
||||
</block>
|
||||
<block wx:else>
|
||||
<image src="/images/configureDevice/woman.png" mode=""/>
|
||||
</block>
|
||||
</view>
|
||||
<view>{{item.age}}</view>
|
||||
</view>
|
||||
<view class="userInfo">
|
||||
<view class="userInfo_1">
|
||||
<view>{{item.realname}}</view>
|
||||
<view class="{{item.sex === 1 ? 'man' : 'woman'}}">
|
||||
<view>
|
||||
<block wx:if="{{item.sex === 1}}">
|
||||
<image src="/images/configureDevice/man.png" />
|
||||
</block>
|
||||
<block wx:else>
|
||||
<image src="/images/configureDevice/woman.png" mode=""/>
|
||||
</block>
|
||||
</view>
|
||||
<view>{{item.age}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="userInfo_2">
|
||||
<view>身高:{{item.height}}cm</view>
|
||||
<view></view>
|
||||
<view>体重:{{item.weight}}kg</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="userInfo_2">
|
||||
<view>身高:{{item.height}}cm</view>
|
||||
<view></view>
|
||||
<view>体重:{{item.weight}}kg</view>
|
||||
</view>
|
||||
<view class="delUser" bind:tap="delUserClick" data-id="{{item.id}}">-</view>
|
||||
</view>
|
||||
<view class="delUser" bind:tap="delUserClick" data-id="{{item.id}}">-</view>
|
||||
</view>
|
||||
</block>
|
||||
</block>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</block>
|
||||
<block wx:else>
|
||||
<view class="nullData">
|
||||
<view>
|
||||
<image src="/images/configureDevice/null.png" />
|
||||
</view>
|
||||
<view>暂无用户数据</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="btn">
|
||||
<view bind:tap="addUser">添加用户</view>
|
||||
|
||||
@@ -213,6 +213,25 @@ input {
|
||||
background-color: #F24439;
|
||||
}
|
||||
|
||||
.nullData {
|
||||
width: 100%;
|
||||
padding: 200rpx 0 250rpx;
|
||||
}
|
||||
|
||||
.nullData>view:first-of-type {
|
||||
width: 230rpx;
|
||||
height: 160rpx;
|
||||
margin: 0 auto 15rpx;
|
||||
}
|
||||
|
||||
.nullData>view:last-of-type {
|
||||
color: #B6B6B6;
|
||||
height: 30rpx;
|
||||
font-size: 30rpx;
|
||||
line-height: 30rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
padding: 0 55rpx;
|
||||
|
||||
@@ -81,6 +81,16 @@ Component({
|
||||
this.setData({ workNo: e.detail.value });
|
||||
},
|
||||
|
||||
// 监听身高输入
|
||||
onHeightInput(e) {
|
||||
this.setData({ 'userInfo.height': e.detail.value });
|
||||
},
|
||||
|
||||
// 监听体重输入
|
||||
onWeightInput(e) {
|
||||
this.setData({ 'userInfo.weight': e.detail.value });
|
||||
},
|
||||
|
||||
// 根据工号查询用户信息
|
||||
searchUser() {
|
||||
let workNo = this.data.workNo.trim();
|
||||
@@ -105,9 +115,11 @@ Component({
|
||||
icon: "none"
|
||||
})
|
||||
}
|
||||
}).catch(() => {
|
||||
}).catch((err) => {
|
||||
console.log(err);
|
||||
this.setData({ userInfo: null });
|
||||
wx.showToast({
|
||||
title: "查询失败,请重试",
|
||||
title: (err && err.message) || "查询失败",
|
||||
icon: "none"
|
||||
})
|
||||
})
|
||||
@@ -122,21 +134,24 @@ Component({
|
||||
})
|
||||
return;
|
||||
}
|
||||
let sn = app.globalData.ppScale.device.mac.replace(/:/g, '');
|
||||
let user = this.data.userInfo;
|
||||
$.ajax("weighingScale/v2/edit/user", {
|
||||
sn,
|
||||
realname: user.realname,
|
||||
sex: user.sex,
|
||||
birthday: user.birthday,
|
||||
height: user.height,
|
||||
weight: user.weight
|
||||
}, "POST", true, "正在添加...").then(res => {
|
||||
let userInfo = this.data.userInfo;
|
||||
// 校验身高
|
||||
if (!userInfo.height) {
|
||||
wx.showToast({ title: "请输入身高", icon: "none" });
|
||||
return;
|
||||
}
|
||||
// 校验体重
|
||||
if (!userInfo.weight) {
|
||||
wx.showToast({ title: "请输入体重", icon: "none" });
|
||||
return;
|
||||
}
|
||||
userInfo.sn = app.globalData.ppScale.device.mac.replace(/:/g, '')
|
||||
$.ajax("weighingScale/v2/edit/user", userInfo, "POST", true, "正在添加...").then(res => {
|
||||
wx.showToast({
|
||||
title: "添加成功",
|
||||
icon: "success"
|
||||
})
|
||||
this.triggerEvent('returnDate', { userInfo: user });
|
||||
this.triggerEvent('returnDate', { userInfo });
|
||||
this.closeModal();
|
||||
}).catch(() => {
|
||||
wx.showToast({
|
||||
|
||||
@@ -11,43 +11,68 @@
|
||||
<view class="input">
|
||||
<view>工号:</view>
|
||||
<view>
|
||||
<input type="text" placeholder="输入工号自动显示员工信息" value="{{workNo}}" bindinput="onWorkNoInput" bindconfirm="searchUser" />
|
||||
<input type="text" maxlength="8" placeholder="输入工号自动显示员工信息" value="{{workNo}}" bindinput="onWorkNoInput" bindconfirm="searchUser" />
|
||||
</view>
|
||||
<!-- <view class="searchBtn" bind:tap="searchUser">查询</view>-->
|
||||
</view>
|
||||
<view class="only">
|
||||
<view>姓名:</view>
|
||||
<view>
|
||||
<view>{{userInfo.realname || ''}}</view>
|
||||
<view>
|
||||
<block wx:if="{{userInfo}}">
|
||||
{{userInfo.realname || ''}}
|
||||
</block>
|
||||
<block wx:else>
|
||||
<text style="color: #808080;">请先输入工号</text>
|
||||
</block>
|
||||
</view>
|
||||
<view></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="only">
|
||||
<view>性别:</view>
|
||||
<view>
|
||||
<view>{{userInfo.sex === 1 ? '男' : userInfo.sex === 2 ? '女' : ''}}</view>
|
||||
<view>
|
||||
<block wx:if="{{userInfo}}">
|
||||
{{userInfo.sex === 1 ? '男' : userInfo.sex === 2 ? '女' : ''}}
|
||||
</block>
|
||||
<block wx:else>
|
||||
<text style="color: #808080;">请先输入工号</text>
|
||||
</block>
|
||||
</view>
|
||||
<view></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="only">
|
||||
<view>生日:</view>
|
||||
<view>
|
||||
<view>{{userInfo.birthday || ''}}</view>
|
||||
<view>
|
||||
<block wx:if="{{userInfo}}">
|
||||
{{userInfo.birthday || ''}}
|
||||
</block>
|
||||
<block wx:else>
|
||||
<text style="color: #808080;">请先输入工号</text>
|
||||
</block>
|
||||
</view>
|
||||
<view></view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="only">
|
||||
<view class="inputUnit">
|
||||
<view>身高:</view>
|
||||
<view>
|
||||
<view>{{userInfo.height || ''}}</view>
|
||||
<view wx:if="{{userInfo.height}}">cm</view>
|
||||
<view>
|
||||
<input type="digit" value="{{userInfo.height || ''}}" bindinput="onHeightInput" placeholder="请输入身高" />
|
||||
</view>
|
||||
<view>cm</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="only">
|
||||
<view class="inputUnit">
|
||||
<view>体重:</view>
|
||||
<view>
|
||||
<view>{{userInfo.weight || ''}}</view>
|
||||
<view wx:if="{{userInfo.weight}}">kg</view>
|
||||
<view>
|
||||
<input type="digit" value="{{userInfo.weight || ''}}" bindinput="onWeightInput" placeholder="请输入体重" />
|
||||
</view>
|
||||
<view>kg</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -55,7 +55,8 @@
|
||||
}
|
||||
|
||||
.only,
|
||||
.input {
|
||||
.input,
|
||||
.inputUnit {
|
||||
width: 100%;
|
||||
height: 104rpx;
|
||||
display: flex;
|
||||
@@ -64,14 +65,16 @@
|
||||
}
|
||||
|
||||
.only>view:nth-of-type(1),
|
||||
.input>view:nth-of-type(1) {
|
||||
.input>view:nth-of-type(1),
|
||||
.inputUnit>view:nth-of-type(1) {
|
||||
color: #333333;
|
||||
height: 104rpx;
|
||||
font-size: 32rpx;
|
||||
line-height: 104rpx;
|
||||
}
|
||||
|
||||
.only>view:nth-of-type(2) {
|
||||
.only>view:nth-of-type(2),
|
||||
.inputUnit>view:nth-of-type(2) {
|
||||
flex: 1;
|
||||
width: 0;
|
||||
height: 104rpx;
|
||||
@@ -84,7 +87,8 @@
|
||||
border: 1rpx solid #E6E6EA;
|
||||
}
|
||||
|
||||
.only>view:nth-of-type(2)>view:nth-of-type(1) {
|
||||
.only>view:nth-of-type(2)>view:nth-of-type(1),
|
||||
.inputUnit>view:nth-of-type(2)>view:nth-of-type(1) {
|
||||
flex: 1;
|
||||
width: 0;
|
||||
color: #252535;
|
||||
@@ -94,7 +98,8 @@
|
||||
line-height: 100rpx;
|
||||
}
|
||||
|
||||
.only>view:nth-of-type(2)>view:nth-of-type(2) {
|
||||
.only>view:nth-of-type(2)>view:nth-of-type(2),
|
||||
.inputUnit>view:nth-of-type(2)>view:nth-of-type(2) {
|
||||
color: #77849E;
|
||||
height: 28rpx;
|
||||
font-size: 28rpx;
|
||||
@@ -110,7 +115,8 @@
|
||||
border: 1rpx solid #E6E6EA;
|
||||
}
|
||||
|
||||
.input>view:nth-of-type(2) input {
|
||||
.input>view:nth-of-type(2) input,
|
||||
.inputUnit>view:nth-of-type(2)>view:nth-of-type(1) input {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: #252535;
|
||||
@@ -118,6 +124,10 @@
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.inputUnit>view:nth-of-type(2) {
|
||||
|
||||
}
|
||||
|
||||
.searchBtn {
|
||||
color: #FFFFFF;
|
||||
width: 120rpx;
|
||||
|
||||
@@ -104,73 +104,9 @@ Component({
|
||||
app.globalData.ppScale.wifi.ssid = this.data.selectWifi.ssid;
|
||||
app.globalData.ppScale.wifi.password = this.data.selectWifiPWD;
|
||||
|
||||
let mac = app.globalData.ppScale.device.mac;
|
||||
let deviceId = app.globalData.ppScale.device.connection.deviceId;
|
||||
if(mac && deviceId) {
|
||||
let scaleDeviceId = mac.replace(/:/g, '');
|
||||
let params = {
|
||||
equipmentName: app.globalData.ppScale.device.name,
|
||||
scaleDeviceId: scaleDeviceId,
|
||||
deviceId: deviceId
|
||||
};
|
||||
$.ajax("weighingScale/binding/device", params, "POST").then(res => {
|
||||
if (res.success) {
|
||||
app.globalData.ppScale.activeProtocol.codeSetBindingState((res) => {
|
||||
console.log("setNetwork.js codeSetBindingState", res);
|
||||
|
||||
if(res == 0) {
|
||||
this.triggerEvent('deviceEvent', {
|
||||
status: true
|
||||
});
|
||||
} else {
|
||||
app.globalData.ppScale.plugin.Blue.stop();
|
||||
wx.showToast({
|
||||
title: "绑定失败,请重试。",
|
||||
icon: "none"
|
||||
})
|
||||
setTimeout(() => {
|
||||
wx.navigateBack({
|
||||
delta: 2
|
||||
})
|
||||
}, 1500)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
app.globalData.ppScale.plugin.Blue.stop();
|
||||
wx.showToast({
|
||||
icon: "none",
|
||||
title: res.message
|
||||
})
|
||||
setTimeout(() => {
|
||||
wx.navigateBack({
|
||||
delta: 2
|
||||
})
|
||||
}, 1500)
|
||||
}
|
||||
}).catch(err => {
|
||||
app.globalData.ppScale.plugin.Blue.stop();
|
||||
wx.showToast({
|
||||
icon: "none",
|
||||
title: err.message
|
||||
})
|
||||
setTimeout(() => {
|
||||
wx.navigateBack({
|
||||
delta: 2
|
||||
})
|
||||
}, 1500)
|
||||
})
|
||||
} else {
|
||||
app.globalData.ppScale.plugin.Blue.stop();
|
||||
wx.showToast({
|
||||
icon: "none",
|
||||
title: "Mac 地址与 deviceId 获取失败,请重新绑定"
|
||||
})
|
||||
setTimeout(() => {
|
||||
wx.navigateBack({
|
||||
delta: 2
|
||||
})
|
||||
}, 1500)
|
||||
}
|
||||
this.triggerEvent('deviceEvent', {
|
||||
status: true
|
||||
});
|
||||
} else {
|
||||
app.globalData.ppScale.plugin.Blue.stop();
|
||||
wx.showToast({
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -24,9 +24,9 @@ Page({
|
||||
app.registerBusListeners();
|
||||
|
||||
// 页面级 bus 订阅
|
||||
ppScale.plugin.bus.subscribe("deviceInfo", (res) => {
|
||||
console.log("===》deviceInfo", res);
|
||||
ppScale.device.mac = res.serialNumber;
|
||||
ppScale.plugin.bus.subscribe("devicesModel", (res) => {
|
||||
console.log("===》devicesModel", res);
|
||||
ppScale.device.mac = res.deviceMac;
|
||||
this._macReady = true;
|
||||
this._tryProgress();
|
||||
});
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ const hideLoading = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const ajax = (url, params, methos, loading = true, title = "加载中...") => {
|
||||
const ajax = (url, params, methos, loading = true, title = "加载中...", contentType = "application/json") => {
|
||||
let requestUrl = app.globalData.wxRequestUrl + url;
|
||||
if (loading) {
|
||||
showLoading(title);
|
||||
@@ -28,7 +28,7 @@ const ajax = (url, params, methos, loading = true, title = "加载中...") => {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let header = {
|
||||
"content-type": "application/json"
|
||||
"content-type": contentType
|
||||
};
|
||||
|
||||
let token = wx.getStorageSync("token");
|
||||
|
||||
Reference in New Issue
Block a user