feat: 体重管理原型更新(员工端运动建议v2、管理端员工数据记录页调整及PRD、截图同步)

This commit is contained in:
liuyunqin
2026-08-25 14:32:22 +08:00
parent 9f8a80eae9
commit e76ca89ae6
25 changed files with 89 additions and 50 deletions
+5 -2
View File
@@ -567,13 +567,16 @@ stateDiagram-v2
**功能说明:** 为员工提供个性化运动指导方案,展示本周运动建议、周目标概览与每日运动安排。
**主要UI元素:**
- 周历(含月历弹窗):日期用圆环标记有无运动计划
- 周历(含月历弹窗):日期用圆环标记有无运动计划,圆环颜色区分日期类型——锻炼日绿圈、休息日橙圈,日历下方附图例说明
- 本周运动建议(可折叠):运动频率/强度建议 + 高血压/高尿酸提示条
- 本周目标概览卡片:运动天数 / 周消耗(kcal)/ 周时长(分钟)/ 休息日
- 每日运动安排卡片:日期徽章 + 当日目标消耗/时长 + 类型标签 + 运动项列表(图标 + 名称 + 描述 + 时长/强度 + 消耗)
- 每日运动安排卡片:日期徽章(休息日为橙色徽章)+ 当日目标消耗/时长 + 类型标签 + 运动项列表(图标 + 名称 + 描述 + 时长/强度 + 消耗)
**交互说明:**
- 点击周历日期切换查看当日运动安排;点击周历标题打开月历弹窗,可在弹窗内切换月份并点选日期
- 月历弹窗内同样以圆环标记有计划的日期(绿圈=锻炼日、橙圈=休息日),弹窗底部附图例说明
![月历弹窗](screenshots/exercise-advice-month.jpg)
- 点击运动建议标题折叠/展开
- 点击返回按钮返回上一页
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 173 KiB

@@ -40,11 +40,20 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
.month-picker__nav:hover { background: #f0f0f0; }
.month-picker__weekdays { display: grid; grid-template-columns: repeat(7, 1fr); text-align: center; font-size: 11px; color: #bbb; margin-bottom: 6px; }
.month-picker__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; text-align: center; }
.month-picker__day { padding: 6px 0; font-size: 13px; color: #333; border-radius: 8px; cursor: pointer; font-weight: 500; }
.month-picker__day { position: relative; padding: 6px 0; font-size: 13px; color: #333; border-radius: 8px; cursor: pointer; font-weight: 500; }
.month-picker__day:hover { background: #f5f5f5; }
.month-picker__day--other { color: #ddd; }
.month-picker__day--today { background: #f0fff0; color: #52c41a; font-weight: 700; }
.month-picker__day--selected { background: #52c41a; color: #fff; font-weight: 700; }
/* 圈圈区分锻炼日/休息日 */
.month-picker__day--plan .month-picker__ring { position: absolute; top: 50%; left: 50%; width: 24px; height: 24px; margin: -12px 0 0 -12px; border-radius: 50%; border: 2px solid #52c41a; opacity: 0.55; pointer-events: none; }
.month-picker__day--plan.month-picker__day--selected .month-picker__ring { border-color: #fff; opacity: 0.9; }
.month-picker__day--rest .month-picker__ring { border-color: #fa8c16; }
/* 月历弹窗图例 */
.month-picker__legend { display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin-top: 8px; padding-top: 8px; border-top: 1px dashed #f0f0f0; }
.month-picker__legend-item { display: inline-flex; align-items: center; gap: 4px; font-size: 10px; color: #999; }
.month-picker__legend-dot { width: 10px; height: 10px; border-radius: 50%; border: 2px solid #52c41a; }
.month-picker__legend-dot--rest { border-color: #fa8c16; }
.cal-week { display: flex; gap: 4px; }
.cal-day { flex: 1; text-align: center; padding: 6px 0; border-radius: 10px; cursor: pointer; background: #f7f8fa; transition: background .2s; }
@@ -57,8 +66,15 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
.cal-day__num { font-size: 14px; font-weight: 700; color: #333; position: relative; z-index: 2; }
.cal-day__ring { position: absolute; inset: 0; border-radius: 50%; border: 2.5px solid #52c41a; z-index: 1; opacity: 0.35; }
.cal-day.active .cal-day__ring { opacity: 1; }
.cal-day--rest .cal-day__ring { border-color: #fa8c16; }
.cal-day.no-plan { opacity: 0.4; }
/* 日历图例 */
.cal-legend { display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin-top: 6px; padding-top: 6px; border-top: 1px dashed #f0f0f0; }
.cal-legend__item { display: inline-flex; align-items: center; gap: 4px; font-size: 10px; color: #999; }
.cal-legend__dot { width: 10px; height: 10px; border-radius: 50%; border: 2px solid #52c41a; }
.cal-legend__dot--rest { border-color: #fa8c16; }
/* ===== 运动建议摘要卡片 ===== */
.advice-summary { background: linear-gradient(160deg, #f0fff0, #f6ffed); border-radius: 16px; margin: 10px 12px 0; padding: 14px 16px; border: 1px solid #b7ebc4; }
.advice-summary__header { display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none; }
@@ -194,9 +210,20 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
<span></span><span></span><span></span><span></span><span></span><span></span><span></span>
</div>
<div class="month-picker__grid" id="monthGrid"></div>
<!-- 图例:圈圈颜色区分锻炼日/休息日 -->
<div class="month-picker__legend">
<span class="month-picker__legend-item"><span class="month-picker__legend-dot"></span>锻炼日</span>
<span class="month-picker__legend-item"><span class="month-picker__legend-dot month-picker__legend-dot--rest"></span>休息日</span>
</div>
</div>
<div class="cal-week" id="calWeek"></div>
<!-- 图例:圈圈颜色区分锻炼日/休息日 -->
<div class="cal-legend">
<span class="cal-legend__item"><span class="cal-legend__dot"></span>锻炼日</span>
<span class="cal-legend__item"><span class="cal-legend__dot cal-legend__dot--rest"></span>休息日</span>
</div>
</div>
<!-- ===== 2. 运动建议摘要(可折叠) ===== -->
@@ -368,10 +395,12 @@ function renderWeek() {
var wd = weekDayChars[d.getDay()];
var dayNum = d.getDate();
var isToday = isSameDay(d, today);
var hasPlan = !!weekPlans[dateStr];
var plan = weekPlans[dateStr];
var hasPlan = !!plan;
var isRest = hasPlan && plan.rest;
var dayEl = document.createElement('div');
dayEl.className = 'cal-day' + (isToday ? ' today' : '') + (!hasPlan ? ' no-plan' : '');
dayEl.className = 'cal-day' + (isToday ? ' today' : '') + (isRest ? ' cal-day--rest' : '') + (!hasPlan ? ' no-plan' : '');
dayEl.setAttribute('data-date', dateStr);
dayEl.onclick = function() { selectDay(this); };
@@ -487,12 +516,14 @@ function renderMonthGrid() {
for (var d = 1; d <= daysInMonth; d++) {
var dateStr = pickerYear + '-' + ('0' + (pickerMonth + 1)).slice(-2) + '-' + ('0' + d).slice(-2);
var plan = weekPlans[dateStr];
var el = document.createElement('div');
var cls = 'month-picker__day';
if (dateStr === todayStr) cls += ' month-picker__day--today';
if (dateStr === selectedDate) cls += ' month-picker__day--selected';
if (plan) cls += plan.rest ? ' month-picker__day--rest' : ' month-picker__day--plan';
el.className = cls;
el.textContent = d;
el.innerHTML = (plan ? '<span class="month-picker__ring"></span>' : '') + d;
el.onclick = (function(ds) { return function(e) { e.stopPropagation(); pickDay(ds); }; })(dateStr);
grid.appendChild(el);
}
@@ -239,11 +239,10 @@ tbody tr:hover td:nth-child(2){background:#F8FBFF;}
<th>摄入<br>(千卡)</th>
<th>消耗<br>(千卡)</th>
<th>吃动热量差<br>(千卡)</th>
<th>当日减重<br>排名</th>
<th>减重<br>排名</th>
<th>减重率<br>排名</th>
<th>综合<br>排名</th>
<th>行动分<br>排名</th>
<th>当日减重<br>排名</th>
<th>当日减重<br>排名</th>
<th>当日综合分<br>排名</th>
<th>当日行动<br>排名</th>
</tr>
</thead>
<tbody id="tableBody"></tbody>
@@ -386,10 +385,7 @@ function buildDetailData(emp){
// 吃动热量差 = 摄入 - 消耗
var balance = totalIntake - totalBurn;
// 当日减重排名(1-20之间随机)
var rank = Math.floor(Math.random() * 20) + 1;
// 活动内累计排名(减重量/减重率/综合分/行动分):初始随机,逐日小幅波动模拟名次变化
// 排名(减重量/减重率/综合分/行动分):初始随机,逐日小幅波动模拟名次变化
if(d === 0){
cumWeightLossRank = Math.floor(Math.random() * 20) + 1;
cumWeightLossRateRank = Math.floor(Math.random() * 20) + 1;
@@ -418,7 +414,7 @@ function buildDetailData(emp){
breakfast: breakfast, lunch: lunch, dinner: dinner, snack: snack,
basalMetab: basalMetab, stepBurn: stepBurn, otherBurn: otherBurn,
totalIntake: totalIntake, totalBurn: totalBurn,
balance: balance, rank: rank,
balance: balance,
weightLossRank: cumWeightLossRank, weightLossRateRank: cumWeightLossRateRank,
compositeRank: cumCompositeRank, actionRank: cumActionRank,
latestWeight: latestWeight, latestFat: latestFat, latestWaist: latestWaist
@@ -645,7 +641,7 @@ function renderTable(){
document.getElementById('pageNum').textContent = '第 ' + (currentPage + 1) + '/' + totalPages + ' 页';
if(filtered.length === 0){
tbody.innerHTML = '<tr><td colspan="19" class="td-empty">暂无匹配的每日明细数据</td></tr>';
tbody.innerHTML = '<tr><td colspan="18" class="td-empty">暂无匹配的每日明细数据</td></tr>';
return;
}
@@ -664,14 +660,9 @@ function renderTable(){
var balCls = d.balance > 0 ? 'change-up' : (d.balance < 0 ? 'change-down' : 'change-zero');
var balSign = d.balance > 0 ? '+' : '';
// 排名样式
var rankHtml = '';
if(d.rank === 1) rankHtml = '<span class="rank-num rank-1">1</span>';
else if(d.rank === 2) rankHtml = '<span class="rank-num rank-2">2</span>';
else if(d.rank === 3) rankHtml = '<span class="rank-num rank-3">3</span>';
else rankHtml = '<span class="rank-other">'+d.rank+'</span>';
// 活动内累计排名样式(前三名同样高亮)
function cumRankHtml(v){
// 排名样式
// 当日排名样式(前三名同样高亮)
function cumRankHtml(v){
if(v === 1) return '<span class="rank-num rank-1">1</span>';
if(v === 2) return '<span class="rank-num rank-2">2</span>';
if(v === 3) return '<span class="rank-num rank-3">3</span>';
@@ -696,9 +687,7 @@ function renderTable(){
html += '<td>'+d.totalBurn+'</td>';
// 吃动热量差
html += '<td class="'+balCls+'">'+balSign+d.balance+'</td>';
// 当日减重排名
html += '<td>'+rankHtml+'</td>';
// 活动内累计排名:减重量/减重率/综合分/行动分
// 当日排名:减重量/减重率/综合分/行动分
html += '<td>'+cumRankHtml(d.weightLossRank)+'</td>';
html += '<td>'+cumRankHtml(d.weightLossRateRank)+'</td>';
html += '<td>'+cumRankHtml(d.compositeRank)+'</td>';
+28 -12
View File
@@ -84,7 +84,7 @@
│ ├── 体脂仪(同上结构)
│ ├── 运动器械(同上结构)
│ ├── 员工监测数据
│ │ └── 测量记录(含身体成分分析弹窗)
│ │ └── 测量记录(含测量详情弹窗)
│ ├── 单位数据统计
│ │ └── 内Tab:二级单位/三级单位,数值可点击查看详情
│ └── 员工数据统计
@@ -716,10 +716,10 @@
- 员工信息卡片:姓名、员工编号、性别、年龄、单位、部门、身高
- 日期筛选Tab:全部 / 选时(范围选择)/ 日 / 周 / 月 / 季 / 年
**表格列(单行表头,19列):**
- 序号、日期、身高(cm)、体重(kg)、BMI、体脂(%)、腰围(cm)、体重变化(kg)、BMI变化、体脂变化(%)、腰围变化(cm)、摄入(千卡)、消耗(千卡)、吃动热量差(千卡)、当日减重排名、减重量排名、减重率排名、综合分排名、行动分排名
**表格列(单行表头,18列):**
- 序号、日期、身高(cm)、体重(kg)、BMI、体脂(%)、腰围(cm)、体重变化(kg)、BMI变化、体脂变化(%)、腰围变化(cm)、摄入(千卡)、消耗(千卡)、吃动热量差(千卡)、当日减重量排名、当日减重率排名、当日综合分排名、当日行动分排名
- 日期列左侧固定
- 排名列样式:前三名高亮显示(金银铜牌样式),减重量/减重率/综合分/行动分排名为活动内累计排名
- 排名列样式:前三名高亮显示(金银铜牌样式),减重量/减重率/综合分/行动分排名均为当日排名
**交互说明:**
- 面包屑导航支持返回活动总览
@@ -1256,19 +1256,35 @@
![页面截图](screenshots/employee-data-record.jpg)
**功能说明:** 展示单个员工在所有设备上的历史测量记录详情,含身体成分分析弹窗
**功能说明:** 展示单个员工在所有设备上的历史测量记录详情,含测量详情弹窗(按设备类型区分字段)
**页面布局:**
- 员工信息卡片(姓名、员工编号、性别、年龄、单位/部门、本周/本月/本年/累计测量次数统计)
- 筛选条件:测量设备类型(下拉)、测量日期范围
- 测量记录表格:测量时间、测量设备、设备编码、身高(cm)、体重(kg)、BMI、基础代谢(kcal)、体脂肪量(kg)、体脂肪率(%)、体水分量(kg)、蛋白质量(kg)、操作
**详情弹窗(身体成分分析):**
- 基础指标:身高(cm)、体重(kg)、BMI、基础代谢、体脂肪量(kg)、体脂肪率(%)
- 水分与蛋白质:体水分量(kg)、体水分率(%)、蛋白质量(kg)、蛋白质率(%)
- 肌肉与骨骼:肌肉率(%)、肌肉量(kg)、体骨骼量/骨量(kg)
- 脂肪分析:皮下脂肪率(%)、内脏脂肪等级、去脂体重(kg)
- 其他:无机盐量/矿物质量(kg)、细胞内液(kg)、细胞外液(kg)、健康评分
**详情弹窗(测量详情,按测量设备类型展示对应字段):**
- 体重秤(同体重秤监测数据详情弹窗口径):
- 基础指标:身高(cm)、体重(kg)、BMI、体脂率(%)
- 身体成分:体脂肪(kg)、水分率(%)、水分量(kg)、肌肉率(%)、肌肉量(kg)、骨量(kg)、去脂体重(kg)
- 体态分析:内脏脂肪、体型、理想体重(kg)、超重百分比(%)、体表面积(m²)
- 蓝牙称(同蓝牙称监测数据详情弹窗口径):
- 基础指标:体重(kg)、BMI、体脂率(%)、身体得分、健康评估
- 身体成分:水分率(%)、水分量(kg)、蛋白质率(%)、蛋白质量(kg)、体脂肪(kg)、肌肉量(kg)、肌肉率(%)、骨骼肌量(kg)、骨骼肌率(%)、骨量(kg)
- 脂肪分析:内脏脂肪、皮下脂肪率(%)、皮下脂肪量(kg)
- 体态管理:理想体重(kg)、去脂体重(kg)、身体年龄、身体类型、推测腰臀比
- 体重管控:控制体重(kg)、脂肪控制量(kg)、肌肉控制量(kg)
- 细胞液分析:细胞内水量(kg)、细胞外水量(kg)
- 进阶成分:无机盐量(kg)、身体细胞量(kg)、骨骼肌质量指数(kg/m²)
- 躯干/四肢脂肪:左右臂/左右腿/躯干的脂肪量(kg)与脂肪率(%)
- 躯干/四肢肌肉:左右臂/左右腿/躯干的肌肉量(kg)与肌肉率(%)
- 体脂仪(同体脂仪监测数据详情弹窗口径):
- 基础指标:体重(kg)、BMI、体脂率(%)、InBody评分(分)
- 身体成分:体水分(L)、蛋白质(kg)、无机盐(kg)、体脂肪(kg)、去脂体重(kg)、骨骼肌量(kg)、骨骼肌指数(kg/m²)
- 脂肪分析:内脏脂肪等级、肥胖度(%)
- 节段肌肉量:右上肢(kg)、左上肢(kg)、躯干(kg)、右下肢(kg)、左下肢(kg)
- 节段体脂肪量:右上肢(kg)、左上肢(kg)、躯干(kg)、右下肢(kg)、左下肢(kg)
- 体重管理:目标体重(kg)、体重控制(kg)、脂肪控制(kg)、肌肉控制(kg)、腰臀比
**弹窗截图:**
@@ -1278,7 +1294,7 @@
- 通过URL参数加载指定员工数据
- 表格支持按设备类型和日期范围筛选
- 返回按钮跳转回员工监测数据列表页
- 点击操作列"详情"打开身体成分分析弹窗
- 点击操作列"详情"打开测量详情弹窗
---
Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 57 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 79 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 21 KiB

@@ -186,11 +186,11 @@
<table>
<thead><tr><th>序号</th><th>测量时间</th><th>测量设备</th><th>设备编码</th><th>身高(cm)</th><th>体重(kg)</th><th>BMI</th><th>基础代谢(kcal)</th><th>体脂肪量(kg)</th><th>体脂肪率(%)</th><th>体水分量(kg)</th><th>蛋白质量(kg)</th><th>操作</th></tr></thead>
<tbody>
<tr><td>1</td><td>2024-05-10 08:30</td><td>体重秤</td><td>SC-2024-001</td><td>175</td><td>72.5</td><td>23.7</td><td>1680</td><td>13.2</td><td>18.2</td><td>40.1</td><td>11.6</td><td><a class="link" onclick="openModal(0)">详细信息</a></td></tr>
<tr><td>2</td><td>2024-05-08 07:45</td><td>体脂仪</td><td>FT-2024-002</td><td>175</td><td>72.8</td><td>23.8</td><td>1675</td><td>13.4</td><td>18.4</td><td>39.8</td><td>11.5</td><td><a class="link" onclick="openModal(1)">详细信息</a></td></tr>
<tr><td>3</td><td>2024-05-06 18:20</td><td>蓝牙称</td><td>BT-2024-003</td><td>175</td><td>73.0</td><td>23.8</td><td>1682</td><td>13.5</td><td>18.5</td><td>40.0</td><td>11.6</td><td><a class="link" onclick="openModal(2)">详细信息</a></td></tr>
<tr><td>4</td><td>2024-05-04 08:10</td><td>体重秤</td><td>SC-2024-001</td><td>175</td><td>72.3</td><td>23.6</td><td>1678</td><td>13.1</td><td>18.1</td><td>40.2</td><td>11.7</td><td><a class="link" onclick="openModal(3)">详细信息</a></td></tr>
<tr><td>5</td><td>2024-05-02 09:00</td><td>体脂仪</td><td>FT-2024-002</td><td>175</td><td>73.2</td><td>23.9</td><td>1685</td><td>13.6</td><td>18.6</td><td>39.9</td><td>11.5</td><td><a class="link" onclick="openModal(4)">详细信息</a></td></tr>
<tr><td>1</td><td>2026-05-13 08:30</td><td>体重秤</td><td>SC-2024-001</td><td>175</td><td>72.5</td><td>23.7</td><td>1,680</td><td>15.2</td><td>21.0</td><td>38.6</td><td>8.5</td><td><a class="link" onclick="openModal(0)">详细信息</a></td></tr>
<tr><td>2</td><td>2026-05-11 07:45</td><td>体脂仪</td><td>FT-2024-002</td><td>175</td><td>72.5</td><td>23.7</td><td>1,680</td><td>15.2</td><td>21.0</td><td>38.6</td><td>8.5</td><td><a class="link" onclick="openModal(1)">详细信息</a></td></tr>
<tr><td>3</td><td>2026-05-06 18:20</td><td>蓝牙称</td><td>BT-2024-003</td><td>175</td><td>72.5</td><td>23.7</td><td>1,680</td><td>15.2</td><td>21.0</td><td>40.0</td><td>12.2</td><td><a class="link" onclick="openModal(2)">详细信息</a></td></tr>
<tr><td>4</td><td>2026-05-04 08:10</td><td>体重秤</td><td>SC-2024-001</td><td>175</td><td>72.5</td><td>23.7</td><td>1,680</td><td>15.2</td><td>21.0</td><td>38.6</td><td>8.5</td><td><a class="link" onclick="openModal(3)">详细信息</a></td></tr>
<tr><td>5</td><td>2026-05-02 09:00</td><td>体脂仪</td><td>FT-2024-002</td><td>175</td><td>72.5</td><td>23.7</td><td>1,680</td><td>15.2</td><td>21.0</td><td>38.6</td><td>8.5</td><td><a class="link" onclick="openModal(4)">详细信息</a></td></tr>
</tbody>
</table>
</div>
@@ -218,11 +218,11 @@ function toggleSubgroup(h){var p=h.parentElement;var sidebar=p.closest("aside");
(function(){var a=document.querySelector('.sidebar-item.active');if(!a)return;var sidebar=document.querySelector('aside');if(sidebar)sidebar.querySelectorAll('.sidebar-subgroup.open').forEach(function(g){g.classList.remove('open');});var s=a.closest('.sidebar-subgroup');if(s)s.classList.add('open');})();
var records=[
{device:'体重秤',code:'SC-2024-001',time:'2024-05-10 08:30',data:{"基础指标":{"身高(cm)":"175","体重(kg)":"72.5","BMI":"23.7","基础代谢":"1,680","体脂肪量(kg)":"13.2","体脂肪率(%)":"18.2"},"水分与蛋白质":{"体水分量(kg)":"40.1","水分率(%)":"55.3","蛋白质量(kg)":"11.6","蛋白质率(%)":"16.0"},"肌肉与骨骼":{"肌肉率(%)":"77.0","肌肉量(kg)":"55.8","体骨骼量/骨量(kg)":"2.9"},"脂肪分析":{"皮下脂肪率(%)":"14.9","内脏脂肪等级":"6","去脂体重(kg)":"59.3"},"其他":{"无机盐量/矿物质量(kg)":"3.5","细胞内液(kg)":"25.2","细胞外液(kg)":"14.9","健康评分":"78"}}},
{device:'体脂仪',code:'FT-2024-002',time:'2024-05-08 07:45',data:{"基础指标":{"身高(cm)":"175","体重(kg)":"72.8","BMI":"23.8","基础代谢":"1,675","InBody评分(分)":"65"},"体脂分析":{"体脂肪量(kg)":"13.4","体脂肪率(%)":"18.4","内脏脂肪等级":"6","肥胖度(%)":"112","去脂体重(kg)":"59.4"},"体成分":{"体水分(L)":"43.5","蛋白质(kg)":"11.5","无机盐(kg)":"4.05","骨骼肌量(kg)":"33.2","骨骼肌指数(kg)":"8.6"},"体重管理":{"目标体重(kg)":"70.0","体重控制(kg)":"-2.8","脂肪控制(kg)":"-5.4","肌肉控制(kg)":"2.6","腰臀比(%)":"0.88"},"节段脂肪":{"上肢(kg)":"1.8","左肢(kg)":"3.5","右上肢(kg)":"1.7","右下肢(kg)":"3.6","躯干(kg)":"2.8"},"节段肌肉":{"左上肢(kg)":"3.3","左下肢(kg)":"9.0","右上肢(kg)":"3.4","右下肢(kg)":"9.2","躯干(kg)":"26.5"}}},
{device:'蓝牙称',code:'BT-2024-003',time:'2024-05-06 18:20',data:{"基础指标":{"身高(cm)":"175","体重(kg)":"73.0","BMI":"23.8","基础代谢":"1,682","体脂肪量(kg)":"13.5","体脂肪率(%)":"18.5"},"水分与蛋白质":{"体水分量(kg)":"40.0","体水分率(%)":"54.8","蛋白质量(kg)":"11.6","蛋白质率(%)":"15.9"},"肌肉与骨骼":{"体肌肉量(kg)":"55.6","体肌肉率(%)":"76.2","骨骼量(kg)":"2.9"},"脂肪分析":{"皮下脂肪量(kg)":"11.0","皮下脂肪率(%)":"15.1","脂肪量(kg)":"59.5"},"细胞液":{"细胞外液量(L)":"14.8","细胞外液率(%)":"37.0","细胞内液量(L)":"25.2","细胞内液率(%)":"63.0"},"其他":{"矿物质量(kg)":"3.4"}}},
{device:'体重秤',code:'SC-2024-001',time:'2024-05-04 08:10',data:{"基础指标":{"身高(cm)":"175","体重(kg)":"72.3","BMI":"23.6","基础代谢":"1,678","体脂肪量(kg)":"13.1","体脂肪率(%)":"18.1"},"水分与蛋白质":{"体水分量(kg)":"40.2","水分率(%)":"55.6","蛋白质量(kg)":"11.7","蛋白质率(%)":"16.2"},"肌肉与骨骼":{"肌肉率(%)":"77.3","肌肉量(kg)":"55.9","体骨骼量/骨量(kg)":"3.0"},"脂肪分析":{"皮下脂肪率(%)":"14.7","内脏脂肪等级":"5","去脂体重(kg)":"59.2"},"其他":{"无机盐量/矿物质量(kg)":"3.5","细胞内液(kg)":"25.4","细胞外液(kg)":"14.8","健康评分":"80"}}},
{device:'体脂仪',code:'FT-2024-002',time:'2024-05-02 09:00',data:{"基础指标":{"身高(cm)":"175","体重(kg)":"73.2","BMI":"23.9","基础代谢":"1,685","InBody评分(分)":"63"},"体脂分析":{"体脂肪量(kg)":"13.6","体脂肪率(%)":"18.6","内脏脂肪等级":"6","肥胖度(%)":"114","去脂体重(kg)":"59.6"},"体成分":{"体水分(L)":"43.8","蛋白质(kg)":"11.5","无机盐(kg)":"4.08","骨骼肌量(kg)":"33.4","骨骼肌指数(kg)":"8.7"},"体重管理":{"目标体重(kg)":"70.0","体重控制(kg)":"-3.2","脂肪控制(kg)":"-5.6","肌肉控制(kg)":"2.4","腰臀比(%)":"0.89"},"节段脂肪":{"上肢(kg)":"1.9","左肢(kg)":"3.6","右上肢(kg)":"1.8","右下肢(kg)":"3.7","躯干(kg)":"2.6"},"节段肌肉":{"左上肢(kg)":"3.3","左下肢(kg)":"9.1","右上肢(kg)":"3.5","右下肢(kg)":"9.3","躯干(kg)":"26.8"}}}
{device:'体重秤',code:'SC-2024-001',time:'2026-05-13 08:30',data:{"基础指标":{"身高(cm)":"175","体重(kg)":"72.5","BMI":"23.7","体脂率(%)":"21.0"},"身体成分":{"体脂肪(kg)":"15.2","水分率(%)":"53.2","水分量(kg)":"38.6","肌肉率(%)":"42.6","肌肉量(kg)":"30.9","量(kg)":"3.1","去脂体重(kg)":"57.3"},"体态分析":{"内脏脂肪":"6","体型":"标准型","理想体重(kg)":"70.2","超重百分比(%)":"3.3","体表面积(m²)":"1.88"}}},
{device:'体脂仪',code:'FT-2024-002',time:'2026-05-11 07:45',data:{"基础指标":{"体重(kg)":"72.5","BMI":"23.7","体脂率(%)":"21.0","InBody评分(分)":"82"},"身体成分":{"体水分(L)":"38.6","蛋白质(kg)":"8.5","无机盐(kg)":"4.11","体脂肪(kg)":"15.2","去脂体重(kg)":"57.3","骨骼肌量(kg)":"33.6","骨骼肌指数(kg/m²)":"8.8"},"脂肪分析":{"内脏脂肪等级":"6","肥胖度(%)":"147"},"节段肌肉量":{"右上肢(kg)":"3.50","左上肢(kg)":"3.35","躯干(kg)":"26.9","右下肢(kg)":"9.40","左下肢(kg)":"9.11"},"节段脂肪":{"上肢(kg)":"2.6","左肢(kg)":"2.7","躯干(kg)":"17.5","右下肢(kg)":"4.8","左下肢(kg)":"4.7"},"体重管理":{"目标体重(kg)":"70.2","体重控制(kg)":"-2.3","脂肪控制(kg)":"-3.1","肌肉控制(kg)":"+0.8","腰臀比":"0.88"}}},
{device:'蓝牙称',code:'BT-2024-003',time:'2026-05-06 18:20',data:{"基础指标":{"体重(kg)":"72.5","BMI":"23.7","体脂率(%)":"21.0","身体得分":"76","健康评估":"良好"},"身体成分":{"水分率(%)":"55.2","水分量(kg)":"40.0","蛋白质率(%)":"16.8","蛋白质量(kg)":"12.2","体脂肪(kg)":"15.2","肌肉量(kg)":"52.3","肌肉率(%)":"72.1","骨骼肌量(kg)":"31.6","骨骼肌率(%)":"43.6","骨量(kg)":"3.2"},"脂肪分析":{"内脏脂肪":"6","皮下脂肪率(%)":"18.5","皮下脂肪量(kg)":"13.4"},"体态管理":{"理想体重(kg)":"68.4","去脂体重(kg)":"57.3","身体年龄":"32","身体类型":"标准型","推测腰臀比":"0.85"},"体重管控":{"控制体重(kg)":"4.1","脂肪控制量(kg)":"3.6","肌肉控制量(kg)":"0.5"},"细胞液分析":{"细胞内水量(kg)":"24.6","细胞外水量(kg)":"15.4"},"进阶成分":{"无机盐量(kg)":"4.35","身体细胞量(kg)":"36.8","骨骼肌质量指数(kg/m²)":"10.3"},"躯干/四肢脂肪":{"左臂脂肪量(kg)":"0.9","左臂脂肪率(%)":"21.5","右臂脂肪量(kg)":"0.9","右臂脂肪率(%)":"21.2","左腿脂肪量(kg)":"2.4","左腿脂肪率(%)":"20.8","右腿脂肪量(kg)":"2.4","右腿脂肪率(%)":"20.6","躯干脂肪量(kg)":"8.6","躯干脂肪率(%)":"22.3"},"躯干/四肢肌肉":{"左臂肌肉量(kg)":"2.9","左臂肌肉率(%)":"95.2","右臂肌肉量(kg)":"3.0","右臂肌肉率(%)":"96.1","左腿肌肉量(kg)":"9.8","左腿肌肉率(%)":"98.5","右腿肌肉量(kg)":"9.9","右腿肌肉率(%)":"98.2","躯干肌肉量(kg)":"26.7","躯干肌肉率(%)":"97.4"}}},
{device:'体重秤',code:'SC-2024-001',time:'2026-05-04 08:10',data:{"基础指标":{"身高(cm)":"175","体重(kg)":"72.5","BMI":"23.7","体脂率(%)":"21.0"},"身体成分":{"体脂肪(kg)":"15.2","水分率(%)":"53.2","水分量(kg)":"38.6","肌肉率(%)":"42.6","肌肉量(kg)":"30.9","量(kg)":"3.1","去脂体重(kg)":"57.3"},"体态分析":{"内脏脂肪":"6","体型":"标准型","理想体重(kg)":"70.2","超重百分比(%)":"3.3","体表面积(m²)":"1.88"}}},
{device:'体脂仪',code:'FT-2024-002',time:'2026-05-02 09:00',data:{"基础指标":{"体重(kg)":"72.5","BMI":"23.7","体脂率(%)":"21.0","InBody评分(分)":"82"},"身体成分":{"体水分(L)":"38.6","蛋白质(kg)":"8.5","无机盐(kg)":"4.11","体脂肪(kg)":"15.2","去脂体重(kg)":"57.3","骨骼肌量(kg)":"33.6","骨骼肌指数(kg/m²)":"8.8"},"脂肪分析":{"内脏脂肪等级":"6","肥胖度(%)":"147"},"节段肌肉量":{"右上肢(kg)":"3.50","左上肢(kg)":"3.35","躯干(kg)":"26.9","右下肢(kg)":"9.40","左下肢(kg)":"9.11"},"节段脂肪":{"上肢(kg)":"2.6","左肢(kg)":"2.7","躯干(kg)":"17.5","右下肢(kg)":"4.8","左下肢(kg)":"4.7"},"体重管理":{"目标体重(kg)":"70.2","体重控制(kg)":"-2.3","脂肪控制(kg)":"-3.1","肌肉控制(kg)":"+0.8","腰臀比":"0.88"}}}
];
function openModal(idx){