feat: 体重管理模块页面更新,新增历史人员列表和详情页面

This commit is contained in:
liuyunqin
2026-07-02 15:39:28 +08:00
parent 019922fd8f
commit ac13e0b6f2
14 changed files with 2130 additions and 1013 deletions
@@ -149,9 +149,9 @@ tbody tr:hover td:nth-child(1){background:#F8FBFF;}
<aside class="sidebar">
<div class="sidebar-menu__title">过程管理</div>
<a href="action-record.html" class="sidebar-item">行动记录</a>
<a href="action-overview.html" class="sidebar-item active">活动总览</a>
<a href="detail-data.html" class="sidebar-item">详细数据</a>
<a href="weight-ranking.html" class="sidebar-item">体重排名</a>
<a href="action-overview.html" class="sidebar-item active">活动总览</a>
<a href="activity-statistics.html" class="sidebar-item">活动统计</a>
</aside>
@@ -160,7 +160,7 @@ tbody tr:hover td:nth-child(1){background:#F8FBFF;}
<!-- 页面标题 -->
<div class="page-header">
<div class="page-header__breadcrumb">体重管理 / 过程管理 / <a href="action-overview.html">活动总览</a> / <span>赛况明细</span></div>
<div class="page-header__breadcrumb"><a href="action-overview.html">活动总览</a> / <span>赛况明细</span></div>
</div>
<!-- [交互] 干预计划 + 员工基本信息卡片 -->
@@ -184,9 +184,9 @@ tbody tr:hover td:last-child{background:#F8FBFF;}
<aside class="sidebar">
<div class="sidebar-menu__title">过程管理</div>
<a href="action-record.html" class="sidebar-item">行动记录</a>
<a href="action-overview.html" class="sidebar-item active">活动总览</a>
<a href="detail-data.html" class="sidebar-item">详细数据</a>
<a href="weight-ranking.html" class="sidebar-item">体重排名</a>
<a href="action-overview.html" class="sidebar-item active">活动总览</a>
<a href="activity-statistics.html" class="sidebar-item">活动统计</a>
</aside>
+58 -176
View File
@@ -271,9 +271,9 @@ tbody tr:hover td:nth-child(3){background:#F8FBFF;}
<aside class="sidebar">
<div class="sidebar-menu__title">过程管理</div>
<a href="action-record.html" class="sidebar-item active">行动记录</a>
<a href="action-overview.html" class="sidebar-item">活动总览</a>
<a href="detail-data.html" class="sidebar-item">详细数据</a>
<a href="weight-ranking.html" class="sidebar-item">体重排名</a>
<a href="action-overview.html" class="sidebar-item">活动总览</a>
<a href="activity-statistics.html" class="sidebar-item">活动统计</a>
</aside>
<!-- 主内容 -->
@@ -366,64 +366,8 @@ tbody tr:hover td:nth-child(3){background:#F8FBFF;}
</div>
</div>
<!-- Tab 切换 + 筛选栏(组合为一个视觉卡片) -->
<div class="tab-bar" style="background:#fff;border-radius:var(--radius-md) var(--radius-md) 0 0;box-shadow:var(--shadow-sm);margin-bottom:0;">
<!-- [交互] 点击Tab切换下方数据列表 -->
<div class="tab-item active" data-tab="0" onclick="switchTab(0)">
每日记录
</div>
<div class="tab-item" data-tab="1" onclick="switchTab(1)">
三测记录
</div>
</div>
<!-- 筛选栏 — 每日记录 -->
<div class="filter-bar" id="filterBar0" style="border-radius:0 0 var(--radius-md) var(--radius-md);margin-top:0;">
<!-- [交互] 日期范围选择,默认今日 -->
<div class="filter-item">
<label>日期范围</label>
<input class="filter-date" type="date" id="filterDateFrom">
<span style="font-size:var(--font-xs);color:var(--text-placeholder);"></span>
<input class="filter-date" type="date" id="filterDateTo">
</div>
<!-- [交互] 双列面板:左选单位→右选部门 -->
<div class="filter-item">
<label>单位部门</label>
<div class="org-select-wrap" id="orgWrap">
<div class="org-trigger" id="orgTrigger" onclick="toggleOrg()">全部单位/部门</div>
<div class="org-panel" id="orgPanel">
<div class="org-col" id="orgUnitCol">
<div class="org-col__title">单位</div>
<div class="org-item active" data-unit="" onclick="selectUnit(this,'全部单位/部门','')">全部单位/部门</div>
<div class="org-item" data-unit="第四采油厂" onclick="selectUnit(this,'第四采油厂','第四采油厂')">第四采油厂</div>
<div class="org-item" data-unit="采油一厂" onclick="selectUnit(this,'采油一厂','采油一厂')">采油一厂</div>
<div class="org-item" data-unit="采油二厂" onclick="selectUnit(this,'采油二厂','采油二厂')">采油二厂</div>
<div class="org-item" data-unit="采气一厂" onclick="selectUnit(this,'采气一厂','采气一厂')">采气一厂</div>
</div>
<div class="org-col" id="orgDeptCol">
<div class="org-col__title">部门</div>
<div class="org-item active" data-dept="" onclick="selectDept(this,'全部部门','')">全部部门</div>
</div>
</div>
</div>
</div>
<div class="filter-item">
<label>姓名</label>
<input class="filter-input" id="filterName" placeholder="请输入姓名" style="width:100px;">
</div>
<div class="filter-item">
<label>员工编号</label>
<input class="filter-input" id="filterEmpId" placeholder="请输入编号" style="width:110px;">
</div>
<!-- [交互] 点击查询按钮筛选列表 -->
<button class="btn btn-primary" onclick="applyFilter()">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4.5" stroke="#fff" stroke-width="1.3"/><path d="M9.5 9.5L13 13" stroke="#fff" stroke-width="1.3" stroke-linecap="round"/></svg>查询
</button>
<button class="btn btn-default" onclick="resetFilter()">重置</button>
</div>
<!-- 筛选栏 — 三测记录(默认隐藏) -->
<div class="filter-bar" id="filterBar1" style="display:none;border-radius:0 0 var(--radius-md) var(--radius-md);margin-top:0;">
<!-- 筛选栏 — 三测记录 -->
<div class="filter-bar" style="border-radius:var(--radius-md) var(--radius-md) 0 0;box-shadow:var(--shadow-sm);">
<div class="filter-item">
<label>日期范围</label>
<input class="filter-date" type="date" id="filterDateFrom1">
@@ -464,120 +408,59 @@ tbody tr:hover td:nth-child(3){background:#F8FBFF;}
<button class="btn btn-default" onclick="resetFilter1()">重置</button>
</div>
<!-- [交互] 操作按钮区每日记录 -->
<div class="action-bar" id="actionBar0">
<button class="btn btn-export" onclick="showToast('导出功能开发中')">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 10v2h10v-2M7 2v7M4.5 6.5L7 9l2.5-2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>导出列表数据
</button>
<button class="btn btn-default" onclick="showToast('导出任务列表开发中')">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><rect x="2" y="2" width="10" height="10" rx="1.5" stroke="currentColor" stroke-width="1.4"/><path d="M4 5h6M4 7.5h4" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>查看导出任务
</button>
</div>
<!-- 数据表格 -->
<!-- 数据表格三测记录 -->
<div class="table-card">
<!-- Tab 0: 每日记录 -->
<div class="tab-panel active" id="tab-panel-0">
<div class="table-card__content">
<table>
<thead>
<tr>
<th>干预计划</th>
<th>姓名</th>
<th>员工编号</th>
<th>性别</th>
<th>年龄</th>
<th>单位</th>
<th>部门</th>
<th>身高<br>(cm)</th>
<th>初始<br>体重(kg)</th>
<th>初始<br>BMI</th>
<th>初始<br>体脂(%)</th>
<th>初始<br>腰围(cm)</th>
<th>目标<br>体重(kg)</th>
<th>目标<br>BMI</th>
<th>目标<br>体脂(%)</th>
<th>目标<br>腰围(cm)</th>
<th>现体重<br>(kg)</th>
<th>现BMI</th>
<th>现体脂<br>(%)</th>
<th>现腰围<br>(cm)</th>
<th>体重变化<br>(kg)</th>
<th>BMI变化</th>
<th>体脂变化<br>(%)</th>
<th>腰围变化<br>(cm)</th>
<th>日期</th>
<th>饮食记录</th>
<th>运动记录</th>
<th>体重记录</th>
</tr>
</thead>
<tbody id="tableBody0"></tbody>
</table>
</div>
<div class="pagination">
<span id="pageInfo0">显示 0 条记录</span>
<button class="page-btn" onclick="goPage(-1)"></button>
<span id="pageNum0" style="font-size:var(--font-sm);color:var(--text-secondary);">第 1 页</span>
<button class="page-btn" onclick="goPage(1)"></button>
<!-- [交互] 子分类切换:体重/饮食/运动 -->
<div class="sub-tab-bar">
<div class="sub-tab-group">
<div class="sub-tab-item active" data-sub="weight" onclick="switchSubTab('weight')">体重</div>
<div class="sub-tab-item" data-sub="diet" onclick="switchSubTab('diet')">饮食</div>
<div class="sub-tab-item" data-sub="exercise" onclick="switchSubTab('exercise')">运动</div>
</div>
</div>
<!-- Tab 1: 三测记录 -->
<div class="tab-panel" id="tab-panel-1">
<!-- [交互] 子分类切换:体重/饮食/运动 -->
<div class="sub-tab-bar">
<div class="sub-tab-group">
<div class="sub-tab-item active" data-sub="weight" onclick="switchSubTab('weight')">体重</div>
<div class="sub-tab-item" data-sub="diet" onclick="switchSubTab('diet')">饮食</div>
<div class="sub-tab-item" data-sub="exercise" onclick="switchSubTab('exercise')">运动</div>
</div>
<!-- [交互] 记录状态(左)+ 操作按钮(右)同行 -->
<div class="status-action-row">
<div class="sub-tab-status">
<span>记录状态</span>
<div class="sub-tab-item active" data-status="all" onclick="switchRecordStatus('all')">全部</div>
<div class="sub-tab-item" data-status="yes" onclick="switchRecordStatus('yes')">已记录</div>
<div class="sub-tab-item" data-status="no" onclick="switchRecordStatus('no')">未记录</div>
</div>
<!-- [交互] 记录状态(左)+ 操作按钮(右)同行 -->
<div class="status-action-row">
<div class="sub-tab-status">
<span>记录状态</span>
<div class="sub-tab-item active" data-status="all" onclick="switchRecordStatus('all')">全部</div>
<div class="sub-tab-item" data-status="yes" onclick="switchRecordStatus('yes')">已记录</div>
<div class="sub-tab-item" data-status="no" onclick="switchRecordStatus('no')">未记录</div>
</div>
<div style="display:flex;gap:8px;">
<button class="btn btn-export" onclick="showToast('导出功能开发中')">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 10v2h10v-2M7 2v7M4.5 6.5L7 9l2.5-2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>导出列表数据
</button>
<button class="btn btn-default" onclick="showToast('导出任务列表开发中')">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><rect x="2" y="2" width="10" height="10" rx="1.5" stroke="currentColor" stroke-width="1.4"/><path d="M4 5h6M4 7.5h4" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>查看导出任务
</button>
</div>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<th>干预计划</th>
<th>姓名</th>
<th>员工编号</th>
<th>性别</th>
<th>年龄</th>
<th>单位</th>
<th>部门</th>
<!-- [交互] 点击表头切换升降序排序 -->
<th class="th-sortable" id="sortCount" onclick="toggleSort()">打卡次数 <span class="sort-arrow"></span></th>
<th>首次记录日期</th>
<th>末次记录日期</th>
</tr>
</thead>
<tbody id="tableBody1"></tbody>
</table>
</div>
<div class="pagination">
<span id="pageInfo1">显示 0 条记录</span>
<button class="page-btn" onclick="goPage(-1)"></button>
<span id="pageNum1" style="font-size:var(--font-sm);color:var(--text-secondary);">第 1 页</span>
<button class="page-btn" onclick="goPage(1)"></button>
<div style="display:flex;gap:8px;">
<button class="btn btn-export" onclick="showToast('导出功能开发中')">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 10v2h10v-2M7 2v7M4.5 6.5L7 9l2.5-2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>导出列表数据
</button>
<button class="btn btn-default" onclick="showToast('导出任务列表开发中')">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><rect x="2" y="2" width="10" height="10" rx="1.5" stroke="currentColor" stroke-width="1.4"/><path d="M4 5h6M4 7.5h4" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>查看导出任务
</button>
</div>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<th>干预计划</th>
<th>姓名</th>
<th>员工编号</th>
<th>性别</th>
<th>年龄</th>
<th>单位</th>
<th>部门</th>
<!-- [交互] 点击表头切换升降序排序 -->
<th class="th-sortable" id="sortCount" onclick="toggleSort()">打卡次数 <span class="sort-arrow"></span></th>
<th>首次记录日期</th>
<th>末次记录日期</th>
</tr>
</thead>
<tbody id="tableBody1"></tbody>
</table>
</div>
<div class="pagination">
<span id="pageInfo1">显示 0 条记录</span>
<button class="page-btn" onclick="goPage(-1)"></button>
<span id="pageNum1" style="font-size:var(--font-sm);color:var(--text-secondary);">第 1 页</span>
<button class="page-btn" onclick="goPage(1)"></button>
</div>
</div>
</main>
@@ -1226,8 +1109,11 @@ function buildMeasureData(){
var monthAgo = new Date(); monthAgo.setMonth(monthAgo.getMonth()-3);
var yesterday = new Date(); yesterday.setDate(yesterday.getDate()-1);
baseEmployees.forEach(function(e,i){
var planIdx = i % plans.length;
var p = plans[planIdx];
// 部分员工未参加干预计划
var noPlan = i % 6 === 0;
var p = noPlan ? null : plans[i % plans.length];
var planIdVal = p ? p.id : null;
var planNameVal = p ? p.name : '-';
var daysSinceStart = Math.floor(Math.random()*80)+10;
types.forEach(function(t){
var hasRecord = i % 5 !== 4;
@@ -1237,7 +1123,7 @@ function buildMeasureData(){
var fd = firstDay.getFullYear()+'-'+('0'+(firstDay.getMonth()+1)).slice(-2)+'-'+('0'+firstDay.getDate()).slice(-2);
var ld = lastDay ? lastDay.getFullYear()+'-'+('0'+(lastDay.getMonth()+1)).slice(-2)+'-'+('0'+lastDay.getDate()).slice(-2) : '-';
data[t].push({
planId: p.id, planName: p.name, org: e.org, dept: e.dept,
planId: planIdVal, planName: planNameVal, org: e.org, dept: e.dept,
name: e.name, empId: e.empId, gender: e.gender, age: e.age,
measureType: t, checkinCount: count, firstDate: fd, lastDate: ld, hasRecord: hasRecord
});
@@ -2747,19 +2633,15 @@ document.addEventListener('click',function(e){
});
document.getElementById('planPanel').innerHTML = html;
// 每日记录日期默认值为今天
var today = new Date();
var todayStr = today.getFullYear()+'-'+('0'+(today.getMonth()+1)).slice(-2)+'-'+('0'+today.getDate()).slice(-2);
document.getElementById('filterDateFrom').value = todayStr;
document.getElementById('filterDateTo').value = todayStr;
// 三测记录日期默认值为本周(周一到周日)
var today = new Date();
var day = today.getDay(); day = day === 0 ? 7 : day;
var mon = new Date(today); mon.setDate(today.getDate() - day + 1);
var sun = new Date(today); sun.setDate(today.getDate() - day + 7);
document.getElementById('filterDateFrom1').value = mon.getFullYear()+'-'+('0'+(mon.getMonth()+1)).slice(-2)+'-'+('0'+mon.getDate()).slice(-2);
document.getElementById('filterDateTo1').value = sun.getFullYear()+'-'+('0'+(sun.getMonth()+1)).slice(-2)+'-'+('0'+sun.getDate()).slice(-2);
applyFilter();
applyFilter1();
updateStatCards();
})();
</script>
@@ -172,9 +172,9 @@ tbody tr:hover td:nth-child(2){background:#F8FBFF;}
<aside class="sidebar">
<div class="sidebar-menu__title">过程管理</div>
<a href="action-record.html" class="sidebar-item">行动记录</a>
<a href="action-overview.html" class="sidebar-item">活动总览</a>
<a href="detail-data.html" class="sidebar-item">详细数据</a>
<a href="weight-ranking.html" class="sidebar-item">体重排名</a>
<a href="action-overview.html" class="sidebar-item">活动总览</a>
<a href="activity-statistics.html" class="sidebar-item active">活动统计</a>
</aside>
@@ -5,18 +5,17 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>个人体重数据 | 体重管理</title>
<style>
/* 设计令牌 */
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;min-width:1280px;}
:root{
--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;
--text-primary:#333;--text-secondary:#666;--text-placeholder:#999;--border:#E8E8E8;--background:#F5F7FA;
--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--font-xl:20px;--font-xxl:24px;
--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;
--radius-sm:4px;--radius-md:8px;--radius-lg:12px;
--shadow-sm:0 1px 4px rgba(0,0,0,0.08);--shadow-md:0 4px 12px rgba(0,0,0,0.12);
--shadow-sm:0 1px 4px rgba(0,0,0,0.08);--shadow-md:0 4px 12px rgba(0,0,0,0.10);
}
/* 通用布局 */
/* 顶部导航栏 */
.top-bar{display:flex;align-items:center;height:56px;background:#001529;padding:0 24px;position:fixed;top:0;left:0;right:0;z-index:100;}
.top-bar__logo{display:flex;align-items:center;gap:8px;color:#fff;font-size:var(--font-lg);font-weight:600;white-space:nowrap;width:240px;flex-shrink:0;}
.top-bar__logo svg{width:28px;height:28px;}
@@ -25,101 +24,109 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
.top-bar__nav a:hover{color:#fff;background:rgba(255,255,255,0.08);}
.top-bar__nav a.active{color:#fff;background:var(--primary);}
.top-bar__right{display:flex;align-items:center;gap:16px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);}
.top-bar__right .btn-back{color:rgba(255,255,255,0.65);cursor:pointer;display:flex;align-items:center;gap:4px;text-decoration:none;}
.top-bar__right .btn-back:hover{color:#fff;}
.btn-back{color:rgba(255,255,255,0.65);cursor:pointer;display:flex;align-items:center;gap:4px;text-decoration:none;}
.btn-back:hover{color:#fff;}
.avatar{width:32px;height:32px;border-radius:50%;background:#1890FF;display:flex;align-items:center;justify-content:center;color:#fff;font-size:var(--font-sm);cursor:pointer;}
/* 侧边栏 */
.sidebar{position:fixed;top:56px;left:0;bottom:0;width:240px;background:#001529;overflow-y:auto;z-index:90;padding-top:8px;}
.sidebar-menu__title{color:rgba(255,255,255,0.35);font-size:var(--font-xs);padding:16px 24px 8px;text-transform:uppercase;letter-spacing:.5px;}
.sidebar-menu__title{color:rgba(255,255,255,0.35);font-size:var(--font-xs);padding:16px 24px 8px;letter-spacing:.5px;}
.sidebar-item{display:flex;align-items:center;gap:8px;padding:10px 24px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);cursor:pointer;transition:all .15s;text-decoration:none;}
.sidebar-item:hover{color:#fff;background:rgba(255,255,255,0.06);}
.sidebar-item.active{color:#fff;background:var(--primary);}
/* 主内容区 */
.main{margin-left:240px;margin-top:56px;padding:24px;min-height:calc(100vh - 56px);}
/* 页面标题 */
.page-header{margin-bottom:16px;}
.page-header__breadcrumb{font-size:var(--font-sm);color:var(--text-placeholder);}
.page-header__breadcrumb span{color:var(--text-primary);}
/* 筛选栏 */
.filter-bar{background:#fff;border-radius:var(--radius-md);padding:20px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:flex;align-items:center;gap:16px;flex-wrap:wrap;}
.filter-bar{background:#fff;padding:16px 24px;display:flex;align-items:center;gap:16px;flex-wrap:wrap;border-radius:var(--radius-md) var(--radius-md) 0 0;box-shadow:var(--shadow-sm);}
.filter-item{display:flex;align-items:center;gap:8px;}
.filter-item label{font-size:var(--font-sm);color:var(--text-secondary);white-space:nowrap;}
.filter-input{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;min-width:180px;}
.filter-item label{font-size:var(--font-xs);color:var(--text-secondary);white-space:nowrap;}
.filter-select{height:32px;min-width:140px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 10px;font-size:var(--font-xs);color:var(--text-primary);background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 8px center;cursor:pointer;outline:none;appearance:none;-webkit-appearance:none;}
/* 筛选输入框 */
.filter-input{height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 10px;font-size:var(--font-xs);color:var(--text-primary);outline:none;transition:border-color .2s;box-sizing:border-box;min-width:110px;}
.filter-input:focus{border-color:var(--primary);}
.filter-select{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 10px center;appearance:none;cursor:pointer;min-width:120px;}
.btn{height:36px;padding:0 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;}
/* 日期筛选 */
.filter-date{height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 10px;font-size:var(--font-xs);outline:none;transition:border-color .2s;box-sizing:border-box;min-width:130px;color:var(--text-primary);}
.filter-date:focus{border-color:var(--primary);}
/* 按钮 */
.btn{height:32px;padding:0 16px;border-radius:var(--radius-sm);font-size:var(--font-xs);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;white-space:nowrap;}
.btn-primary{background:var(--primary);color:#fff;}.btn-primary:hover{background:#40a9ff;}
.btn-default{background:#fff;color:var(--text-primary);border:1px solid var(--border);}.btn-default:hover{color:var(--primary);border-color:var(--primary);}
/* 统计卡片 */
.stats-row{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:16px;}
.stat-card{background:#fff;border-radius:var(--radius-md);padding:20px 24px;box-shadow:var(--shadow-sm);display:flex;align-items:center;gap:16px;}
.stat-card__icon{width:48px;height:48px;border-radius:var(--radius-md);display:flex;align-items:center;justify-content:center;font-size:24px;}
.stat-card__icon.blue{background:var(--primary-light);}
.stat-card__icon.green{background:#F6FFED;}
.stat-card__icon.orange{background:#FFF7E6;}
.stat-card__info{display:flex;flex-direction:column;gap:4px;}
.stat-card__value{font-size:var(--font-xl);font-weight:700;color:var(--text-primary);}
.stat-card__label{font-size:var(--font-sm);color:var(--text-secondary);}
.btn-export{background:#fff;color:var(--text-primary);border:1px solid var(--border);}.btn-export:hover{color:var(--primary);border-color:var(--primary);}
/* 操作栏 */
.action-bar{display:flex;align-items:center;gap:8px;margin-bottom:16px;}
.action-bar{display:flex;align-items:center;gap:8px;padding:16px 24px;background:#fff;border-top:1px solid var(--border);}
/* 表格 */
.table-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);overflow:hidden;}
.table-card__header{display:flex;align-items:center;justify-content:space-between;padding:16px 24px;border-bottom:1px solid var(--border);}
.table-card__title{font-size:var(--font-base);font-weight:600;}
/* 表格卡片 */
.table-card{background:#fff;border-radius:0 0 var(--radius-md) var(--radius-md);box-shadow:var(--shadow-sm);overflow:hidden;}
.table-card__content{overflow-x:auto;-webkit-overflow-scrolling:touch;}
table{width:100%;border-collapse:separate;border-spacing:0;white-space:nowrap;}
thead th{background:#FAFAFA;padding:10px 12px;text-align:center;font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);white-space:nowrap;}
tbody td{padding:12px 12px;text-align:center;font-size:var(--font-sm);color:var(--text-primary);border-bottom:1px solid var(--border);white-space:nowrap;}
table{width:100%;border-collapse:separate;border-spacing:0;min-width:2200px;}
/* 表头 */
thead th{background:#FAFAFA;padding:8px 7px;text-align:center;font-size:var(--font-xs);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);white-space:nowrap;}
/* 表体 */
tbody td{padding:10px 7px;text-align:center;font-size:var(--font-sm);color:var(--text-primary);border-bottom:1px solid #F0F0F0;white-space:nowrap;}
tbody tr:last-child td{border-bottom:none;}
tbody tr:hover td{background:#F8FBFF;}
/* 左侧固定列:序号、姓名、员工编号 */
thead th:nth-child(1),tbody td:nth-child(1){position:sticky;left:0;z-index:2;background:#fff;width:54px;min-width:54px;}
thead th:nth-child(1){background:#FAFAFA;z-index:4;}
thead th:nth-child(2),tbody td:nth-child(2){position:sticky;left:54px;z-index:2;background:#fff;width:72px;min-width:72px;}
thead th:nth-child(2){background:#FAFAFA;z-index:4;}
thead th:nth-child(3),tbody td:nth-child(3){position:sticky;left:126px;z-index:2;background:#fff;width:90px;min-width:90px;}
thead th:nth-child(3){background:#FAFAFA;z-index:4;}
/* 右侧固定列:详细数据 */
thead th:last-child,tbody td:last-child{position:sticky;right:0;z-index:2;background:#fff;width:90px;min-width:90px;}
thead th:last-child{background:#FAFAFA;z-index:4;}
/* 左侧固定列分隔阴影 */
thead th:nth-child(3),tbody td:nth-child(3){box-shadow:2px 0 8px rgba(0,0,0,0.06);}
/* 右侧固定列分隔阴影 */
thead th:last-child,tbody td:last-child{box-shadow:-2px 0 8px rgba(0,0,0,0.06);}
/* hover时固定列保持hover背景 */
tbody tr:hover td:nth-child(1),
tbody tr:hover td:nth-child(2),
tbody tr:hover td:nth-child(3),
tbody tr:hover{background:#F8FBFF;}
/* 第一列(姓名)固定左侧 — 仅第一行表头(避免rowspan第二行误匹配) */
thead tr:first-child th:nth-child(1),tbody td:nth-child(1){position:sticky;left:0;z-index:5;background:#fff;min-width:80px;max-width:80px;box-shadow:2px 0 6px rgba(0,0,0,0.08);}
thead tr:first-child th:nth-child(1){z-index:8;background:#FAFAFA;}
tbody tr:hover td:nth-child(1){background:#F8FBFF;}
/* 最后一列(详细数据)固定右侧 — 仅第一行表头(避免rowspan第二行误匹配到"变化"列) */
thead tr:first-child th:last-child,tbody td:last-child{position:sticky;right:0;z-index:5;background:#fff;min-width:80px;max-width:80px;box-shadow:-2px 0 6px rgba(0,0,0,0.08);}
thead tr:first-child th:last-child{z-index:8;background:#FAFAFA;}
tbody tr:hover td:last-child{background:#F8FBFF;}
.tag{display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:var(--font-xs);}
.tag-green{background:#F6FFED;color:var(--success);}
.tag-orange{background:#FFF7E6;color:var(--warning);}
.tag-red{background:#FFF1F0;color:var(--danger);}
.td-empty{text-align:center;padding:48px 0;color:var(--text-placeholder);font-size:var(--font-sm);}
/* 详细数据链接 */
.link{color:var(--primary);cursor:pointer;font-size:var(--font-sm);text-decoration:none;}.link:hover{color:#40a9ff;}
/* 排序列 */
.sortable{cursor:pointer;user-select:none;position:relative;padding-right:24px !important;}
.sortable:hover{background:#F0F5FF;}
.sort-icon{position:absolute;right:6px;top:50%;transform:translateY(-50%);display:flex;flex-direction:column;gap:1px;}
.sort-icon .arrow-up,.sort-icon .arrow-down{width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent;}
.sort-icon .arrow-up{border-bottom:5px solid #ccc;}
.sort-icon .arrow-down{border-top:5px solid #ccc;}
.sortable.asc .sort-icon .arrow-up{border-bottom-color:var(--primary);}
.sortable.desc .sort-icon .arrow-down{border-top-color:var(--primary);}
/* 变化值颜色 */
.change-down{color:var(--success);}
.change-up{color:var(--danger);}
.change-zero{color:var(--text-placeholder);}
/* 分页 */
.pagination{display:flex;align-items:center;justify-content:flex-end;padding:16px 24px;gap:8px;border-top:1px solid var(--border);}
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;}
.page-btn:hover,.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
/* Toast */
.toast{position:fixed;top:80px;left:50%;transform:translateX(-50%);background:#333;color:#fff;padding:10px 24px;border-radius:var(--radius-sm);font-size:var(--font-sm);z-index:9999;opacity:0;transition:opacity .2s;pointer-events:none;}
.toast.show{opacity:1;}
/* 单位部门级联面板 */
.org-wrap{position:relative;display:inline-block;}
.org-trigger{height:32px;min-width:160px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 10px;font-size:var(--font-xs);color:var(--text-primary);background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 8px center;cursor:pointer;display:flex;align-items:center;user-select:none;white-space:nowrap;}
.org-trigger.open,.org-trigger:hover{border-color:var(--primary);}
.org-panel{display:none;position:absolute;top:36px;left:0;z-index:310;background:#fff;border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:var(--shadow-md);width:380px;}
.org-panel.open{display:flex;}
.org-col{flex:1;overflow-y:auto;max-height:200px;border-right:1px solid var(--border);}
.org-col:last-child{border-right:none;}
.org-col__title{padding:6px 12px;font-size:var(--font-xs);color:var(--text-placeholder);background:#FAFAFA;border-bottom:1px solid var(--border);font-weight:500;}
.org-item{padding:8px 12px;font-size:var(--font-sm);color:var(--text-primary);cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:4px;}
.org-item:hover{background:#F0F8FF;color:var(--primary);}
.org-item.active{background:var(--primary-light);color:var(--primary);font-weight:500;}
</style>
</head>
<body>
<!-- 顶部导航 -->
<header class="top-bar">
<div class="top-bar__logo">
<svg viewBox="0 0 28 28" fill="none"><rect width="28" height="28" rx="6" fill="#1890FF"/><path d="M7 14h14M14 7v14" stroke="#fff" stroke-width="2.5" stroke-linecap="round"/></svg>
体重管理
</div>
<!-- 顶部导航栏 -->
<div class="top-bar">
<div class="top-bar__logo"><svg viewBox="0 0 28 28" fill="none"><rect width="28" height="28" rx="6" fill="#1890FF"/><path d="M7 14h14M14 7v14" stroke="#fff" stroke-width="2.5" stroke-linecap="round"/></svg> 体重管理</div>
<nav class="top-bar__nav">
<a href="archive-personal-weight-data.html" class="active">档案</a>
<a href="plan-list.html">计划管理</a>
@@ -133,180 +140,348 @@ tbody tr:hover td:last-child{background:#F8FBFF;}
<div class="top-bar__right">
<a class="btn-back" href="../../index.html"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg> 返回首页</a>
<div class="avatar"></div>
<span>系统管理员 ▾</span>
<span style="color:rgba(255,255,255,0.65);">系统管理员 ▾</span>
</div>
</header>
</div>
<!-- 侧边栏 -->
<aside class="sidebar">
<div class="sidebar-menu__title">档案</div>
<a class="sidebar-item active" href="archive-personal-weight-data.html">个人体重数据</a>
<a class="sidebar-item" href="archive-unit-report.html">单位报表数据</a>
<a class="sidebar-item" href="archive-algorithm-model.html">算法模型</a>
<a href="archive-personal-weight-data.html" class="sidebar-item active">个人体重数据</a>
<a href="archive-unit-report.html" class="sidebar-item">单位报表数据</a>
<a href="archive-algorithm-model.html" class="sidebar-item">算法模型</a>
</aside>
<!-- 主内容 -->
<div class="main">
<!-- 主内容 -->
<main class="main">
<!-- 页面标题 -->
<div class="page-header">
<div class="page-header__breadcrumb">体重管理 / 档案 / <span>个人体重数据</span></div>
</div>
<!-- 筛选栏 -->
<!-- [交互] 筛选栏 — 姓名 + 员工编号 + 单位部门 + 日期范围 -->
<div class="filter-bar">
<div class="filter-item">
<label>姓名/员工编号</label>
<input class="filter-input" type="text" placeholder="请输入姓名或工号">
<label>姓名</label>
<input class="filter-input" id="filterName" placeholder="请输入姓名" style="width:110px;">
</div>
<div class="filter-item">
<label>员工编号</label>
<input class="filter-input" id="filterEmpId" placeholder="请输入编号" style="width:120px;">
</div>
<div class="filter-item">
<label>单位部门</label>
<select class="filter-select">
<option>全部</option>
<option>CQ能源总部</option>
<option>采油一厂</option>
<option>采油二厂</option>
<option>采气一厂</option>
</select>
<div class="org-wrap" id="orgWrap">
<div class="org-trigger" id="orgTrigger" onclick="toggleOrg()">全部单位/部门</div>
<div class="org-panel" id="orgPanel">
<div class="org-col" id="unitCol">
<div class="org-col__title">单位</div>
<div class="org-item active" data-unit="" onclick="selectUnit(this,'全部单位/部门','')">全部单位/部门</div>
<div class="org-item" data-unit="第四采油厂" onclick="selectUnit(this,'第四采油厂','第四采油厂')">第四采油厂</div>
<div class="org-item" data-unit="采油一厂" onclick="selectUnit(this,'采油一厂','采油一厂')">采油一厂</div>
<div class="org-item" data-unit="采油二厂" onclick="selectUnit(this,'采油二厂','采油二厂')">采油二厂</div>
<div class="org-item" data-unit="采气一厂" onclick="selectUnit(this,'采气一厂','采气一厂')">采气一厂</div>
</div>
<div class="org-col" id="deptCol">
<div class="org-col__title">部门</div>
<div class="org-item active" data-dept="" onclick="selectDept(this,'全部部门','')">全部部门</div>
</div>
</div>
</div>
</div>
<div class="filter-item">
<label>年份</label>
<select class="filter-select">
<option selected>2026年</option>
<option>2025年</option>
<option>2024年</option>
</select>
<label>日期范围</label>
<input class="filter-date" type="date" id="filterDateFrom">
<span style="font-size:var(--font-xs);color:var(--text-placeholder);"></span>
<input class="filter-date" type="date" id="filterDateTo">
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
<!-- [交互] 点击查询按钮筛选列表 -->
<button class="btn btn-primary" onclick="applyFilter()">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4.5" stroke="#fff" stroke-width="1.3"/><path d="M9.5 9.5L13 13" stroke="#fff" stroke-width="1.3" stroke-linecap="round"/></svg>查询
</button>
<button class="btn btn-default" onclick="resetFilter()">重置</button>
</div>
<!-- 操作栏 -->
<!-- [交互] 操作按钮区 -->
<div class="action-bar">
<button class="btn btn-primary"><svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 10v2h10v-2M7 2v7M4.5 6.5L7 9l2.5-2.5" stroke="#fff" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>导出列表数据</button>
<button class="btn btn-default"><svg width="14" height="14" viewBox="0 0 14 14" fill="none"><rect x="2" y="2" width="10" height="10" rx="1.5" stroke="currentColor" stroke-width="1.4"/><path d="M4 5h6M4 7.5h4" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>查看导出任务</button>
<button class="btn btn-export" onclick="showToast('导出列表数据功能开发中')">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 10v2h10v-2M7 2v7M4.5 6.5L7 9l2.5-2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>导出列表数据
</button>
<button class="btn btn-default" onclick="showToast('导出任务列表开发中')">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><rect x="2" y="2" width="10" height="10" rx="1.5" stroke="currentColor" stroke-width="1.4"/><path d="M4 5h6M4 7.5h4" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>查看导出任务
</button>
</div>
<!-- 数据表格 -->
<div class="table-card">
<div class="table-card__header">
<div class="table-card__title">个人体重数据</div>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>员工编号</th>
<th>性别</th>
<th>年龄</th>
<th>单位</th>
<th>部门</th>
<th>初始体重(kg)</th>
<th>初始BMI</th>
<th>初始体脂(%)</th>
<th>初始腰围(cm)</th>
<th>最终体重(kg)</th>
<th>最终BMI</th>
<th>最终体脂(%)</th>
<th>最终腰围(cm)</th>
<th>体重变化(kg)</th>
<th>BMI变化</th>
<th>体脂变化(%)</th>
<th>腰围变化(cm)</th>
<th>饮食记录次数</th>
<th>运动记录次数</th>
<th>体重记录次数</th>
<th>详细数据</th>
<th rowspan="2">姓名</th>
<th rowspan="2">员工编号</th>
<th rowspan="2">性别</th>
<th rowspan="2">年龄</th>
<th rowspan="2">单位</th>
<th rowspan="2">部门</th>
<th colspan="3">体重(kg)</th>
<th colspan="3">BMI</th>
<th colspan="3">体脂(%)</th>
<th colspan="3">腰围(cm)</th>
<th rowspan="2">饮食记录<br>次数</th>
<th rowspan="2">运动记录<br>次数</th>
<th rowspan="2">体重记录<br>次数</th>
<th rowspan="2">详细数据</th>
</tr>
<tr>
<th>初始</th><th>最终</th><th>变化</th>
<th>初始</th><th>最终</th><th>变化</th>
<th>初始</th><th>最终</th><th>变化</th>
<th>初始</th><th>最终</th><th>变化</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td><td>李凯明</td><td>424234</td><td></td><td>23</td>
<td>第四采油厂</td><td>岭南作业区</td>
<td>95</td><td>30</td><td>30</td><td>90</td><td>80</td><td>28</td><td>28</td><td>80</td><td>-15</td><td>-2</td><td>-2</td><td>-10</td>
<td>345</td><td>123</td><td>132</td>
<td><a class="link" href="archive-personal-weight-detail.html?id=424234">查看</a></td>
</tr>
<tr>
<td>2</td><td>张文胜</td><td>234223</td><td></td><td>45</td>
<td>第四采油厂</td><td>虎狼山作业区</td>
<td>95</td><td>30</td><td>30</td><td>90</td><td>80</td><td>28</td><td>28</td><td>80</td><td>-15</td><td>-2</td><td>-2</td><td>-10</td>
<td>342</td><td>231</td><td>123</td>
<td><a class="link" href="archive-personal-weight-detail.html?id=234223">查看</a></td>
</tr>
<tr>
<td>3</td><td>王丽华</td><td>318756</td><td></td><td>32</td>
<td>采油一厂</td><td>设备维护站</td>
<td>72</td><td>26</td><td>28</td><td>82</td><td>66</td><td>23</td><td>25</td><td>76</td><td>-6</td><td>-3</td><td>-3</td><td>-6</td>
<td>280</td><td>156</td><td>98</td>
<td><a class="link" href="archive-personal-weight-detail.html?id=318756">查看</a></td>
</tr>
<tr>
<td>4</td><td>刘建国</td><td>567890</td><td></td><td>38</td>
<td>采气一厂</td><td>生产运行部</td>
<td>88</td><td>29</td><td>32</td><td>95</td><td>82</td><td>27</td><td>29</td><td>89</td><td>-6</td><td>-2</td><td>-3</td><td>-6</td>
<td>210</td><td>189</td><td>87</td>
<td><a class="link" href="archive-personal-weight-detail.html?id=567890">查看</a></td>
</tr>
<tr>
<td>5</td><td>陈思雨</td><td>192847</td><td></td><td>28</td>
<td>CQ能源总部</td><td>人力资源部</td>
<td>65</td><td>24</td><td>26</td><td>75</td><td>60</td><td>22</td><td>23</td><td>70</td><td>-5</td><td>-2</td><td>-3</td><td>-5</td>
<td>356</td><td>200</td><td>145</td>
<td><a class="link" href="archive-personal-weight-detail.html?id=192847">查看</a></td>
</tr>
<tr>
<td>6</td><td>杨志强</td><td>445612</td><td></td><td>41</td>
<td>采油二厂</td><td>后勤保障部</td>
<td>92</td><td>31</td><td>33</td><td>98</td><td>86</td><td>28</td><td>30</td><td>92</td><td>-6</td><td>-3</td><td>-3</td><td>-6</td>
<td>198</td><td>142</td><td>76</td>
<td><a class="link" href="archive-personal-weight-detail.html?id=445612">查看</a></td>
</tr>
<tr>
<td>7</td><td>赵晓峰</td><td>678901</td><td></td><td>35</td>
<td>采油一厂</td><td>技术研发部</td>
<td>78</td><td>27</td><td>27</td><td>86</td><td>74</td><td>25</td><td>24</td><td>82</td><td>-4</td><td>-2</td><td>-3</td><td>-4</td>
<td>267</td><td>178</td><td>110</td>
<td><a class="link" href="archive-personal-weight-detail.html?id=678901">查看</a></td>
</tr>
</tbody>
<tbody id="tableBody"></tbody>
</table>
</div>
<!-- 分页 -->
<div class="pagination">
<span>显示 7 条,共 1,280 条</span>
<button class="page-btn"></button>
<button class="page-btn active">1</button>
<button class="page-btn">2</button>
<button class="page-btn">3</button>
<button class="page-btn">...</button>
<button class="page-btn">256</button>
<button class="page-btn"></button>
<span id="pageInfo">显示 0 条记录</span>
<button class="page-btn" onclick="goPage(-1)"></button>
<span id="pageNum" style="font-size:var(--font-sm);color:var(--text-secondary);">第 1 页</span>
<button class="page-btn" onclick="goPage(1)"></button>
</div>
</div>
</div>
</main>
<!-- Toast -->
<div class="toast" id="toast"></div>
<script>
// 侧边栏菜单项点击高亮
document.querySelectorAll('.sidebar-item').forEach(function(item) {
item.addEventListener('click', function() {
document.querySelectorAll('.sidebar-item').forEach(function(i) { i.classList.remove('active'); });
this.classList.add('active');
/* ===== 侧边栏当前页高亮 ===== */
(function(){
var current = location.pathname.split('/').pop();
document.querySelectorAll('.sidebar-item').forEach(function(item){
var href = item.getAttribute('href');
item.classList.toggle('active', href === current);
});
});
// 排序列点击切换
document.querySelectorAll('.sortable').forEach(function(th) {
th.addEventListener('click', function() {
var isAsc = this.classList.contains('asc');
var isDesc = this.classList.contains('desc');
// 清除其他排序状态
document.querySelectorAll('.sortable').forEach(function(t) { t.classList.remove('asc','desc'); });
if (isAsc) {
this.classList.add('desc');
} else {
this.classList.add('asc');
}
})();
/* ===== Mock 数据:个人体重数据列表 ===== */
var personnelData = [
{name:'张建国',empId:'CQ100235',gender:'男',age:42,unit:'第四采油厂',dept:'健康管理部',weightInit:86.0,weightFinal:81.8,weightChange:-4.2,bmiInit:29.5,bmiFinal:28.1,bmiChange:-1.4,fatInit:28.8,fatFinal:25.6,fatChange:-3.2,waistInit:99.0,waistFinal:93.9,waistChange:-5.1,dietCount:98,sportCount:72,weightCount:45},
{name:'李明辉',empId:'CQ100458',gender:'男',age:38,unit:'第四采油厂',dept:'安全环保科',weightInit:82.5,weightFinal:79.0,weightChange:-3.5,bmiInit:28.0,bmiFinal:26.9,bmiChange:-1.1,fatInit:26.5,fatFinal:23.7,fatChange:-2.8,waistInit:95.0,waistFinal:90.7,waistChange:-4.3,dietCount:85,sportCount:64,weightCount:38},
{name:'王秀兰',empId:'CQ100672',gender:'女',age:35,unit:'第四采油厂',dept:'工会办公室',weightInit:68.0,weightFinal:65.7,weightChange:-2.3,bmiInit:25.8,bmiFinal:25.0,bmiChange:-0.8,fatInit:33.0,fatFinal:31.1,fatChange:-1.9,waistInit:83.0,waistFinal:79.8,waistChange:-3.2,dietCount:72,sportCount:55,weightCount:32},
{name:'赵铁柱',empId:'CQ100891',gender:'男',age:45,unit:'第四采油厂',dept:'生产技术部',weightInit:93.0,weightFinal:87.9,weightChange:-5.1,bmiInit:32.0,bmiFinal:30.3,bmiChange:-1.7,fatInit:32.5,fatFinal:28.4,fatChange:-4.1,waistInit:106.0,waistFinal:99.5,waistChange:-6.5,dietCount:105,sportCount:80,weightCount:50},
{name:'陈小燕',empId:'CQ101023',gender:'女',age:29,unit:'第四采油厂',dept:'财务部',weightInit:62.5,weightFinal:60.7,weightChange:-1.8,bmiInit:23.8,bmiFinal:23.2,bmiChange:-0.6,fatInit:30.5,fatFinal:29.1,fatChange:-1.4,waistInit:78.5,waistFinal:76.0,waistChange:-2.5,dietCount:65,sportCount:48,weightCount:28},
{name:'刘大军',empId:'CQ101145',gender:'男',age:50,unit:'第四采油厂',dept:'信息中心',weightInit:89.0,weightFinal:86.0,weightChange:-3.0,bmiInit:30.5,bmiFinal:29.5,bmiChange:-1.0,fatInit:31.0,fatFinal:28.5,fatChange:-2.5,waistInit:101.0,waistFinal:97.2,waistChange:-3.8,dietCount:78,sportCount:42,weightCount:35},
{name:'周红梅',empId:'CQ101267',gender:'女',age:40,unit:'第四采油厂',dept:'健康管理部',weightInit:72.5,weightFinal:69.9,weightChange:-2.6,bmiInit:27.3,bmiFinal:26.4,bmiChange:-0.9,fatInit:34.5,fatFinal:32.4,fatChange:-2.1,waistInit:86.5,waistFinal:83.0,waistChange:-3.5,dietCount:82,sportCount:60,weightCount:40},
{name:'吴国强',empId:'CQ101389',gender:'男',age:33,unit:'第四采油厂',dept:'安全环保科',weightInit:78.0,weightFinal:78.8,weightChange:+0.8,bmiInit:26.5,bmiFinal:26.8,bmiChange:+0.3,fatInit:24.8,fatFinal:25.4,fatChange:+0.6,waistInit:89.5,waistFinal:90.7,waistChange:+1.2,dietCount:30,sportCount:18,weightCount:12},
{name:'郑晓明',empId:'CQ101501',gender:'男',age:36,unit:'采油一厂',dept:'安全环保科',weightInit:84.0,weightFinal:80.2,weightChange:-3.8,bmiInit:28.8,bmiFinal:27.5,bmiChange:-1.3,fatInit:27.5,fatFinal:24.5,fatChange:-3.0,waistInit:96.5,waistFinal:91.9,waistChange:-4.6,dietCount:90,sportCount:68,weightCount:42},
{name:'黄丽华',empId:'CQ101623',gender:'女',age:31,unit:'采油一厂',dept:'健康管理部',weightInit:65.0,weightFinal:62.9,weightChange:-2.1,bmiInit:24.8,bmiFinal:24.1,bmiChange:-0.7,fatInit:31.5,fatFinal:29.9,fatChange:-1.6,waistInit:80.5,waistFinal:77.7,waistChange:-2.8,dietCount:68,sportCount:52,weightCount:30},
{name:'杨志强',empId:'CQ101745',gender:'男',age:44,unit:'采油一厂',dept:'生产技术部',weightInit:91.5,weightFinal:87.0,weightChange:-4.5,bmiInit:31.2,bmiFinal:29.7,bmiChange:-1.5,fatInit:31.5,fatFinal:28.0,fatChange:-3.5,waistInit:104.5,waistFinal:98.7,waistChange:-5.8,dietCount:102,sportCount:76,weightCount:48},
{name:'孙美玲',empId:'CQ101867',gender:'女',age:27,unit:'采油一厂',dept:'工会办公室',weightInit:59.0,weightFinal:57.5,weightChange:-1.5,bmiInit:22.5,bmiFinal:22.0,bmiChange:-0.5,fatInit:29.0,fatFinal:27.9,fatChange:-1.1,waistInit:76.0,waistFinal:74.0,waistChange:-2.0,dietCount:55,sportCount:40,weightCount:22},
{name:'林海峰',empId:'CQ101989',gender:'男',age:48,unit:'采油一厂',dept:'安全环保科',weightInit:87.0,weightFinal:84.2,weightChange:-2.8,bmiInit:29.8,bmiFinal:28.9,bmiChange:-0.9,fatInit:30.0,fatFinal:27.8,fatChange:-2.2,waistInit:99.5,waistFinal:96.1,waistChange:-3.4,dietCount:76,sportCount:45,weightCount:33},
{name:'何秀英',empId:'CQ102101',gender:'女',age:39,unit:'采油一厂',dept:'财务部',weightInit:71.0,weightFinal:67.8,weightChange:-3.2,bmiInit:26.8,bmiFinal:25.7,bmiChange:-1.1,fatInit:33.5,fatFinal:30.9,fatChange:-2.6,waistInit:85.0,waistFinal:81.0,waistChange:-4.0,dietCount:88,sportCount:62,weightCount:39},
{name:'马文博',empId:'CQ102223',gender:'男',age:32,unit:'采油一厂',dept:'生产技术部',weightInit:76.5,weightFinal:77.7,weightChange:+1.2,bmiInit:26.0,bmiFinal:26.4,bmiChange:+0.4,fatInit:24.0,fatFinal:24.9,fatChange:+0.9,waistInit:88.0,waistFinal:89.5,waistChange:+1.5,dietCount:28,sportCount:15,weightCount:10},
{name:'张翠花',empId:'CQ102345',gender:'女',age:43,unit:'采油二厂',dept:'工会办公室',weightInit:75.0,weightFinal:71.0,weightChange:-4.0,bmiInit:28.5,bmiFinal:27.2,bmiChange:-1.3,fatInit:35.5,fatFinal:32.2,fatChange:-3.3,waistInit:89.0,waistFinal:83.8,waistChange:-5.2,dietCount:95,sportCount:70,weightCount:44},
{name:'李伟强',empId:'CQ102467',gender:'男',age:37,unit:'采油二厂',dept:'安全环保科',weightInit:83.0,weightFinal:79.9,weightChange:-3.1,bmiInit:28.2,bmiFinal:27.2,bmiChange:-1.0,fatInit:27.0,fatFinal:24.6,fatChange:-2.4,waistInit:95.5,waistFinal:91.6,waistChange:-3.9,dietCount:80,sportCount:58,weightCount:36},
{name:'王雪琴',empId:'CQ102589',gender:'女',age:34,unit:'采油二厂',dept:'健康管理部',weightInit:67.5,weightFinal:65.0,weightChange:-2.5,bmiInit:25.5,bmiFinal:24.7,bmiChange:-0.8,fatInit:32.0,fatFinal:30.1,fatChange:-1.9,waistInit:82.0,waistFinal:78.9,waistChange:-3.1,dietCount:70,sportCount:50,weightCount:31},
{name:'赵勇刚',empId:'CQ102701',gender:'男',age:46,unit:'采油二厂',dept:'生产技术部',weightInit:94.5,weightFinal:89.2,weightChange:-5.3,bmiInit:32.5,bmiFinal:30.7,bmiChange:-1.8,fatInit:33.0,fatFinal:28.7,fatChange:-4.3,waistInit:107.5,waistFinal:100.8,waistChange:-6.7,dietCount:110,sportCount:82,weightCount:52},
{name:'陈晓峰',empId:'CQ102823',gender:'男',age:28,unit:'采油二厂',dept:'信息中心',weightInit:79.0,weightFinal:76.8,weightChange:-2.2,bmiInit:27.0,bmiFinal:26.3,bmiChange:-0.7,fatInit:25.5,fatFinal:23.8,fatChange:-1.7,waistInit:91.0,waistFinal:88.4,waistChange:-2.6,dietCount:62,sportCount:46,weightCount:26},
{name:'刘芳菲',empId:'CQ102945',gender:'女',age:30,unit:'采油二厂',dept:'工会办公室',weightInit:63.5,weightFinal:61.9,weightChange:-1.6,bmiInit:24.0,bmiFinal:23.5,bmiChange:-0.5,fatInit:30.0,fatFinal:28.8,fatChange:-1.2,waistInit:79.0,waistFinal:77.2,waistChange:-1.8,dietCount:52,sportCount:38,weightCount:20},
{name:'周建国',empId:'CQ103067',gender:'男',age:41,unit:'采油二厂',dept:'健康管理部',weightInit:85.0,weightFinal:81.4,weightChange:-3.6,bmiInit:29.0,bmiFinal:27.8,bmiChange:-1.2,fatInit:28.0,fatFinal:25.1,fatChange:-2.9,waistInit:98.0,waistFinal:93.5,waistChange:-4.5,dietCount:86,sportCount:65,weightCount:41},
{name:'吴明辉',empId:'CQ103189',gender:'男',age:35,unit:'采气一厂',dept:'生产技术部',weightInit:83.5,weightFinal:79.4,weightChange:-4.1,bmiInit:28.5,bmiFinal:27.1,bmiChange:-1.4,fatInit:27.2,fatFinal:24.1,fatChange:-3.1,waistInit:96.0,waistFinal:91.1,waistChange:-4.9,dietCount:92,sportCount:71,weightCount:43},
{name:'郑丽娟',empId:'CQ103301',gender:'女',age:33,unit:'采气一厂',dept:'信息中心',weightInit:66.5,weightFinal:64.5,weightChange:-2.0,bmiInit:25.2,bmiFinal:24.5,bmiChange:-0.7,fatInit:31.8,fatFinal:30.3,fatChange:-1.5,waistInit:81.5,waistFinal:79.1,waistChange:-2.4,dietCount:66,sportCount:49,weightCount:29},
{name:'黄志远',empId:'CQ103423',gender:'男',age:49,unit:'采气一厂',dept:'生产技术部',weightInit:92.0,weightFinal:87.2,weightChange:-4.8,bmiInit:31.8,bmiFinal:30.2,bmiChange:-1.6,fatInit:32.0,fatFinal:28.2,fatChange:-3.8,waistInit:105.5,waistFinal:99.5,waistChange:-6.0,dietCount:104,sportCount:78,weightCount:49},
{name:'杨小红',empId:'CQ103545',gender:'女',age:26,unit:'采气一厂',dept:'信息中心',weightInit:58.0,weightFinal:56.7,weightChange:-1.3,bmiInit:22.0,bmiFinal:21.6,bmiChange:-0.4,fatInit:28.5,fatFinal:27.5,fatChange:-1.0,waistInit:75.0,waistFinal:73.5,waistChange:-1.5,dietCount:48,sportCount:35,weightCount:18},
{name:'孙大伟',empId:'CQ103667',gender:'男',age:39,unit:'采气一厂',dept:'生产技术部',weightInit:84.5,weightFinal:81.2,weightChange:-3.3,bmiInit:28.8,bmiFinal:27.7,bmiChange:-1.1,fatInit:27.8,fatFinal:25.1,fatChange:-2.7,waistInit:97.0,waistFinal:92.8,waistChange:-4.2,dietCount:84,sportCount:62,weightCount:37},
{name:'林翠萍',empId:'CQ103789',gender:'女',age:44,unit:'采气一厂',dept:'信息中心',weightInit:73.5,weightFinal:69.8,weightChange:-3.7,bmiInit:27.8,bmiFinal:26.6,bmiChange:-1.2,fatInit:34.8,fatFinal:31.9,fatChange:-2.9,waistInit:87.5,waistFinal:82.8,waistChange:-4.7,dietCount:89,sportCount:67,weightCount:42},
{name:'何俊杰',empId:'CQ103901',gender:'男',age:31,unit:'采气一厂',dept:'生产技术部',weightInit:77.0,weightFinal:77.5,weightChange:+0.5,bmiInit:26.2,bmiFinal:26.4,bmiChange:+0.2,fatInit:24.2,fatFinal:24.6,fatChange:+0.4,waistInit:88.5,waistFinal:89.3,waistChange:+0.8,dietCount:35,sportCount:22,weightCount:14},
{name:'马兰花',empId:'CQ104023',gender:'女',age:37,unit:'采气一厂',dept:'信息中心',weightInit:70.0,weightFinal:67.1,weightChange:-2.9,bmiInit:26.5,bmiFinal:25.5,bmiChange:-1.0,fatInit:33.0,fatFinal:30.7,fatChange:-2.3,waistInit:84.0,waistFinal:80.4,waistChange:-3.6,dietCount:78,sportCount:56,weightCount:34},
{name:'张永强',empId:'CQ104145',gender:'男',age:43,unit:'第四采油厂',dept:'生产技术部',weightInit:90.5,weightFinal:85.5,weightChange:-5.0,bmiInit:31.0,bmiFinal:29.3,bmiChange:-1.7,fatInit:31.0,fatFinal:27.0,fatChange:-4.0,waistInit:104.0,waistFinal:97.7,waistChange:-6.3,dietCount:108,sportCount:79,weightCount:51},
{name:'李春梅',empId:'CQ104267',gender:'女',age:36,unit:'第四采油厂',dept:'工会办公室',weightInit:69.0,weightFinal:66.3,weightChange:-2.7,bmiInit:26.0,bmiFinal:25.1,bmiChange:-0.9,fatInit:32.5,fatFinal:30.4,fatChange:-2.1,waistInit:83.5,waistFinal:80.1,waistChange:-3.4,dietCount:74,sportCount:54,weightCount:31},
{name:'王海涛',empId:'CQ104389',gender:'男',age:29,unit:'第四采油厂',dept:'信息中心',weightInit:77.5,weightFinal:75.6,weightChange:-1.9,bmiInit:26.5,bmiFinal:25.9,bmiChange:-0.6,fatInit:25.0,fatFinal:23.5,fatChange:-1.5,waistInit:90.0,waistFinal:87.7,waistChange:-2.3,dietCount:60,sportCount:44,weightCount:25},
{name:'赵玉兰',empId:'CQ104501',gender:'女',age:41,unit:'采油一厂',dept:'健康管理部',weightInit:73.0,weightFinal:69.6,weightChange:-3.4,bmiInit:27.5,bmiFinal:26.4,bmiChange:-1.1,fatInit:34.0,fatFinal:31.3,fatChange:-2.7,waistInit:86.0,waistFinal:81.6,waistChange:-4.4,dietCount:84,sportCount:63,weightCount:38},
{name:'陈国强',empId:'CQ104623',gender:'男',age:34,unit:'采油一厂',dept:'工会办公室',weightInit:80.0,weightFinal:77.6,weightChange:-2.4,bmiInit:27.2,bmiFinal:26.4,bmiChange:-0.8,fatInit:26.0,fatFinal:24.1,fatChange:-1.9,waistInit:93.0,waistFinal:90.0,waistChange:-3.0,dietCount:69,sportCount:51,weightCount:30},
{name:'刘志强',empId:'CQ104745',gender:'男',age:47,unit:'采油二厂',dept:'健康管理部',weightInit:91.0,weightFinal:86.4,weightChange:-4.6,bmiInit:31.2,bmiFinal:29.7,bmiChange:-1.5,fatInit:31.5,fatFinal:27.8,fatChange:-3.7,waistInit:104.5,waistFinal:98.9,waistChange:-5.6,dietCount:100,sportCount:74,weightCount:47},
{name:'周秀芳',empId:'CQ104867',gender:'女',age:28,unit:'采油二厂',dept:'安全环保科',weightInit:60.0,weightFinal:58.6,weightChange:-1.4,bmiInit:22.8,bmiFinal:22.3,bmiChange:-0.5,fatInit:29.5,fatFinal:28.4,fatChange:-1.1,waistInit:77.0,waistFinal:75.3,waistChange:-1.7,dietCount:50,sportCount:36,weightCount:19},
{name:'吴建国',empId:'CQ104989',gender:'男',age:40,unit:'采油二厂',dept:'生产技术部',weightInit:84.0,weightFinal:80.1,weightChange:-3.9,bmiInit:28.5,bmiFinal:27.2,bmiChange:-1.3,fatInit:27.5,fatFinal:24.4,fatChange:-3.1,waistInit:96.5,waistFinal:91.7,waistChange:-4.8,dietCount:91,sportCount:69,weightCount:43},
{name:'郑志明',empId:'CQ105101',gender:'男',age:33,unit:'采气一厂',dept:'生产技术部',weightInit:82.0,weightFinal:79.4,weightChange:-2.6,bmiInit:27.8,bmiFinal:26.9,bmiChange:-0.9,fatInit:26.5,fatFinal:24.5,fatChange:-2.0,waistInit:94.0,waistFinal:90.8,waistChange:-3.2,dietCount:72,sportCount:53,weightCount:32},
{name:'黄美琴',empId:'CQ105223',gender:'女',age:38,unit:'采气一厂',dept:'信息中心',weightInit:71.5,weightFinal:68.4,weightChange:-3.1,bmiInit:27.0,bmiFinal:26.0,bmiChange:-1.0,fatInit:33.2,fatFinal:30.7,fatChange:-2.5,waistInit:85.5,waistFinal:81.6,waistChange:-3.9,dietCount:81,sportCount:59,weightCount:36}
];
var pageSize = 10;
var currentPage = 0;
var filteredData = personnelData.slice();
/* ===== 单位部门级联 ===== */
var deptMap = {
'第四采油厂':['健康管理部','安全环保科','工会办公室','生产技术部','财务部','信息中心'],
'采油一厂':['健康管理部','安全环保科','工会办公室','生产技术部'],
'采油二厂':['健康管理部','安全环保科','生产技术部','信息中心'],
'采气一厂':['生产技术部','信息中心']
};
var selUnitName = '';
var selUnitCode = '';
var selDeptName = '';
var selDeptCode = '';
function toggleOrg(){
var panel = document.getElementById('orgPanel');
var trigger = document.getElementById('orgTrigger');
panel.classList.toggle('open');
trigger.classList.toggle('open');
}
function selectUnit(elem, unitName, unitCode){
document.querySelectorAll('#unitCol .org-item').forEach(function(item){item.classList.remove('active');});
elem.classList.add('active');
selUnitName = unitName;
selUnitCode = unitCode;
var depts = deptMap[unitCode] || [];
var html = '<div class="org-col__title">部门</div>';
html += '<div class="org-item active" data-dept="" onclick="selectDept(this,\'全部部门\',\'\')">全部部门</div>';
depts.forEach(function(d){
html += '<div class="org-item" data-dept="'+d+'" onclick="selectDept(this,\''+d+'\',\''+d+'\')">'+d+'</div>';
});
document.getElementById('deptCol').innerHTML = html;
selDeptName = '';
selDeptCode = '';
}
function selectDept(elem, deptName, deptCode){
document.querySelectorAll('#deptCol .org-item').forEach(function(item){item.classList.remove('active');});
elem.classList.add('active');
selDeptName = deptName;
selDeptCode = deptCode;
var label = selUnitCode ? selUnitName : '全部单位';
label += selDeptCode ? ' / ' + deptName : ' / 全部部门';
document.getElementById('orgTrigger').textContent = label;
}
/* ===== 筛选 ===== */
function applyFilter(){
var name = document.getElementById('filterName').value.trim().toLowerCase();
var empId = document.getElementById('filterEmpId').value.trim().toLowerCase();
var unit = selUnitCode;
var dept = selDeptCode;
var dateFrom = document.getElementById('filterDateFrom').value;
var dateTo = document.getElementById('filterDateTo').value;
var data = personnelData.slice();
if(name){ data = data.filter(function(d){return d.name.toLowerCase().indexOf(name) !== -1;}); }
if(empId){ data = data.filter(function(d){return d.empId.toLowerCase().indexOf(empId) !== -1;}); }
if(unit){ data = data.filter(function(d){return d.unit === unit;}); }
if(dept){ data = data.filter(function(d){return d.dept === dept;}); }
// 日期范围筛选 — 基于记录日期(Mock 数据中没有日期字段,保留筛选逻辑用于后续对接真实数据)
if(dateFrom || dateTo){
// 当前 Mock 数据不含日期字段,日期筛选不影响结果
// 对接真实接口后启用:
// if(dateFrom){ data = data.filter(function(d){return d.recordDate >= dateFrom;}); }
// if(dateTo){ data = data.filter(function(d){return d.recordDate <= dateTo;}); }
}
filteredData = data;
currentPage = 0;
renderTable();
}
function resetFilter(){
document.getElementById('filterName').value = '';
document.getElementById('filterEmpId').value = '';
selUnitName = ''; selUnitCode = '';
selDeptName = ''; selDeptCode = '';
document.getElementById('orgTrigger').textContent = '全部单位/部门';
document.querySelectorAll('#unitCol .org-item').forEach(function(item){item.classList.remove('active');});
var firstUnit = document.querySelector('#unitCol .org-item');
if(firstUnit) firstUnit.classList.add('active');
document.getElementById('deptCol').innerHTML = '<div class="org-col__title">部门</div><div class="org-item active" data-dept="" onclick="selectDept(this,\'全部部门\',\'\')">全部部门</div>';
var now = new Date();
document.getElementById('filterDateFrom').value = now.getFullYear() + '-01-01';
document.getElementById('filterDateTo').value = now.getFullYear() + '-' + String(now.getMonth()+1).padStart(2,'0') + '-' + String(now.getDate()).padStart(2,'0');
applyFilter();
}
/* ===== 渲染表格 ===== */
function renderTable(){
var tbody = document.getElementById('tableBody');
var start = currentPage * pageSize;
var pageData = filteredData.slice(start, start + pageSize);
var totalPages = Math.ceil(filteredData.length / pageSize) || 1;
document.getElementById('pageInfo').textContent = '显示 ' + pageData.length + ' 条,共 ' + filteredData.length + ' 条记录';
document.getElementById('pageNum').textContent = '第 ' + (currentPage + 1) + '/' + totalPages + ' 页';
if(filteredData.length === 0){
tbody.innerHTML = '<tr><td colspan="22" class="td-empty">暂无匹配数据</td></tr>';
return;
}
var html = '';
pageData.forEach(function(d){
var wCls = d.weightChange < 0 ? 'change-down' : (d.weightChange > 0 ? 'change-up' : 'change-zero');
var bCls = d.bmiChange < 0 ? 'change-down' : (d.bmiChange > 0 ? 'change-up' : 'change-zero');
var fCls = d.fatChange < 0 ? 'change-down' : (d.fatChange > 0 ? 'change-up' : 'change-zero');
var waCls = d.waistChange < 0 ? 'change-down' : (d.waistChange > 0 ? 'change-up' : 'change-zero');
html += '<tr>';
html += '<td>'+esc(d.name)+'</td>';
html += '<td>'+esc(d.empId)+'</td>';
html += '<td>'+d.gender+'</td>';
html += '<td>'+d.age+'</td>';
html += '<td>'+esc(d.unit)+'</td>';
html += '<td>'+esc(d.dept)+'</td>';
html += '<td>'+d.weightInit.toFixed(1)+'</td>';
html += '<td>'+d.weightFinal.toFixed(1)+'</td>';
html += '<td class="'+wCls+'">'+(d.weightChange < 0 ? d.weightChange.toFixed(1) : (d.weightChange > 0 ? '+'+d.weightChange.toFixed(1) : '0'))+'</td>';
html += '<td>'+d.bmiInit.toFixed(1)+'</td>';
html += '<td>'+d.bmiFinal.toFixed(1)+'</td>';
html += '<td class="'+bCls+'">'+(d.bmiChange < 0 ? d.bmiChange.toFixed(1) : (d.bmiChange > 0 ? '+'+d.bmiChange.toFixed(1) : '0'))+'</td>';
html += '<td>'+d.fatInit.toFixed(1)+'</td>';
html += '<td>'+d.fatFinal.toFixed(1)+'</td>';
html += '<td class="'+fCls+'">'+(d.fatChange < 0 ? d.fatChange.toFixed(1) : (d.fatChange > 0 ? '+'+d.fatChange.toFixed(1) : '0'))+'</td>';
html += '<td>'+d.waistInit.toFixed(1)+'</td>';
html += '<td>'+d.waistFinal.toFixed(1)+'</td>';
html += '<td class="'+waCls+'">'+(d.waistChange < 0 ? d.waistChange.toFixed(1) : (d.waistChange > 0 ? '+'+d.waistChange.toFixed(1) : '0'))+'</td>';
html += '<td>'+d.dietCount+'</td>';
html += '<td>'+d.sportCount+'</td>';
html += '<td>'+d.weightCount+'</td>';
html += '<td><a class="link" href="archive-personal-weight-detail.html?id='+esc(d.empId)+'&year='+encodeURIComponent(document.getElementById('filterDateFrom').value.substring(0,4))+'">查看</a></td>';
html += '</tr>';
});
tbody.innerHTML = html;
}
/* ===== 翻页 ===== */
function goPage(delta){
var totalPages = Math.ceil(filteredData.length / pageSize);
var newPage = currentPage + delta;
if(newPage < 0 || newPage >= totalPages) return;
currentPage = newPage;
renderTable();
}
/* 点击外部关闭单位部门面板 */
document.addEventListener('click', function(e){
var ow = document.getElementById('orgWrap');
if(ow && !ow.contains(e.target)){
document.getElementById('orgPanel').classList.remove('open');
document.getElementById('orgTrigger').classList.remove('open');
}
});
/* ===== 工具函数 ===== */
function esc(s){return String(s||'').replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;').replace(/>/g,'&gt;');}
function showToast(msg){
var t=document.getElementById('toast');t.textContent=msg;t.classList.add('show');
setTimeout(function(){t.classList.remove('show');},2000);
}
/* ===== 初始化 ===== */
(function init(){
var now = new Date();
var yearStart = now.getFullYear() + '-01-01';
var today = now.getFullYear() + '-' + String(now.getMonth()+1).padStart(2,'0') + '-' + String(now.getDate()).padStart(2,'0');
document.getElementById('filterDateFrom').value = yearStart;
document.getElementById('filterDateTo').value = today;
renderTable();
})();
</script>
</body>
</html>
@@ -14,6 +14,8 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
--radius-sm:4px;--radius-md:8px;--radius-lg:12px;
--shadow-sm:0 1px 4px rgba(0,0,0,0.08);--shadow-md:0 4px 12px rgba(0,0,0,0.12);
}
/* 顶部导航栏 */
.top-bar{display:flex;align-items:center;height:56px;background:#001529;padding:0 24px;position:fixed;top:0;left:0;right:0;z-index:100;}
.top-bar__logo{display:flex;align-items:center;gap:8px;color:#fff;font-size:var(--font-lg);font-weight:600;white-space:nowrap;width:240px;flex-shrink:0;}
.top-bar__logo svg{width:28px;height:28px;}
@@ -22,33 +24,52 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
.top-bar__nav a:hover{color:#fff;background:rgba(255,255,255,0.08);}
.top-bar__nav a.active{color:#fff;background:var(--primary);}
.top-bar__right{display:flex;align-items:center;gap:16px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);}
.top-bar__right .btn-back{color:rgba(255,255,255,0.65);cursor:pointer;display:flex;align-items:center;gap:4px;text-decoration:none;}
.top-bar__right .btn-back:hover{color:#fff;}
.btn-back{color:rgba(255,255,255,0.65);cursor:pointer;display:flex;align-items:center;gap:4px;text-decoration:none;}
.btn-back:hover{color:#fff;}
.avatar{width:32px;height:32px;border-radius:50%;background:#1890FF;display:flex;align-items:center;justify-content:center;color:#fff;font-size:var(--font-sm);cursor:pointer;}
/* 侧边栏 */
.sidebar{position:fixed;top:56px;left:0;bottom:0;width:240px;background:#001529;overflow-y:auto;z-index:90;padding-top:8px;}
.sidebar-menu__title{color:rgba(255,255,255,0.35);font-size:var(--font-xs);padding:16px 24px 8px;text-transform:uppercase;letter-spacing:.5px;}
.sidebar-menu__title{color:rgba(255,255,255,0.35);font-size:var(--font-xs);padding:16px 24px 8px;letter-spacing:.5px;}
.sidebar-item{display:flex;align-items:center;gap:8px;padding:10px 24px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);cursor:pointer;transition:all .15s;text-decoration:none;}
.sidebar-item:hover{color:#fff;background:rgba(255,255,255,0.06);}
.sidebar-item.active{color:#fff;background:var(--primary);}
/* 主内容区 */
.main{margin-left:240px;margin-top:56px;padding:24px;min-height:calc(100vh - 56px);}
/* 面包屑 */
.breadcrumb{display:flex;align-items:center;gap:8px;margin-bottom:16px;font-size:var(--font-sm);color:var(--text-secondary);}
.breadcrumb a{color:var(--primary);text-decoration:none;}.breadcrumb a:hover{color:#40a9ff;}
/* 员工信息卡片 */
.info-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:24px;margin-bottom:16px;display:flex;align-items:center;gap:32px;}
.info-card__avatar{width:56px;height:56px;border-radius:50%;background:var(--primary);color:#fff;display:flex;align-items:center;justify-content:center;font-size:20px;font-weight:600;flex-shrink:0;}
.info-card__detail{display:flex;flex-direction:column;gap:6px;}
.info-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:20px 24px;margin-bottom:16px;display:flex;align-items:center;gap:24px;}
.info-card__left{display:flex;align-items:center;gap:20px;flex:1;min-width:0;}
.info-card__avatar{width:52px;height:52px;border-radius:50%;background:var(--primary);color:#fff;display:flex;align-items:center;justify-content:center;font-size:20px;font-weight:600;flex-shrink:0;}
.info-card__detail{display:flex;flex-direction:column;gap:4px;}
.info-card__name{font-size:var(--font-lg);font-weight:600;color:var(--text-primary);}
.info-card__meta{display:flex;gap:24px;font-size:var(--font-sm);color:var(--text-secondary);}
/* 通用 */
.btn{height:36px;padding:0 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;}
.btn-primary{background:var(--primary);color:#fff;}.btn-primary:hover{background:#40a9ff;}
.btn-default{background:#fff;color:var(--text-primary);border:1px solid var(--border);}.btn-default:hover{color:var(--primary);border-color:var(--primary);}
.filter-item{display:flex;align-items:center;gap:8px;}
.filter-item label{font-size:var(--font-sm);color:var(--text-secondary);white-space:nowrap;}
.filter-input{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);outline:none;background:#fff;min-width:140px;}
.filter-input:focus{border-color:var(--primary);}
.filter-select{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 10px center;appearance:none;cursor:pointer;min-width:140px;}
.info-card__meta{display:flex;gap:20px;font-size:var(--font-sm);color:var(--text-secondary);flex-wrap:wrap;}
.info-card__right{flex-shrink:0;margin-left:auto;}
.info-card__date-filter{display:flex;align-items:center;gap:8px;}
.info-card__date-filter label{font-size:var(--font-xs);color:var(--text-secondary);white-space:nowrap;}
/* 指标卡片 */
.metrics-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:20px 24px;margin-bottom:16px;}
.metrics-card__title{font-size:var(--font-base);font-weight:600;color:var(--text-primary);margin-bottom:16px;}
.metrics-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;}
.metric-group{background:#FAFAFA;border-radius:var(--radius-sm);padding:14px 16px;text-align:center;}
.metric-group__label{font-size:var(--font-xs);color:var(--text-secondary);margin-bottom:8px;}
.metric-row{display:flex;justify-content:center;align-items:center;gap:0;font-size:var(--font-xs);color:var(--text-primary);}
.metric-row__item{flex:1;display:flex;flex-direction:column;align-items:center;gap:2px;}
.metric-row__val{font-size:var(--font-base);font-weight:600;color:var(--text-primary);}
.metric-row__sub{font-size:var(--font-xs);color:var(--text-placeholder);}
.metric-arrow{font-size:var(--font-sm);color:var(--text-placeholder);margin:0 4px;}
/* 变化值颜色 */
.change-down{color:var(--success);}
.change-up{color:var(--danger);}
.change-zero{color:var(--text-placeholder);}
/* Tab */
.tab-bar{display:flex;border-bottom:1px solid var(--border);margin-bottom:0;background:#fff;border-radius:var(--radius-md) var(--radius-md) 0 0;padding:0 24px;}
.tab-item{padding:12px 20px;font-size:var(--font-sm);cursor:pointer;color:var(--text-secondary);border-bottom:2px solid transparent;margin-bottom:-1px;transition:all .2s;font-weight:500;}
@@ -56,48 +77,41 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
.tab-item.active{color:var(--primary);border-bottom-color:var(--primary);font-weight:600;}
.tab-panel{display:none;}
.tab-panel.active{display:block;}
.table-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);overflow:hidden;}
.table-card--tab{border-radius:0 0 var(--radius-md) var(--radius-md);}
.table-card--tab .tab-panel:first-child .table-card__content{border-radius:0;}
/* 表格 */
.table-card{background:#fff;border-radius:0 0 var(--radius-md) var(--radius-md);box-shadow:var(--shadow-sm);overflow:hidden;}
.table-card__content{overflow-x:auto;-webkit-overflow-scrolling:touch;}
table{width:100%;border-collapse:collapse;white-space:nowrap;}
thead th{background:#FAFAFA;padding:10px 12px;text-align:center;font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);}
tbody td{padding:12px 12px;text-align:center;font-size:var(--font-sm);color:var(--text-primary);border-bottom:1px solid var(--border);}
tbody tr:last-child td{border-bottom:none;}
tbody tr:hover{background:#F8FBFF;}
/* 标签 */
.tag{display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:var(--font-xs);}
.tag-blue{background:var(--primary-light);color:var(--primary);}
.tag-green{background:#F6FFED;color:var(--success);}
.tag-gray{background:#F5F5F5;color:#999;}
.tag-blue{background:var(--primary-light);color:var(--primary);}
.link{color:var(--primary);cursor:pointer;font-size:var(--font-sm);text-decoration:none;}.link:hover{color:#40a9ff;}
.tag-orange{background:#FFF7E6;color:#FA8C16;}
/* 分页 */
.pagination{display:flex;align-items:center;justify-content:flex-end;padding:16px 24px;gap:8px;border-top:1px solid var(--border);}
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;}
.page-btn:hover,.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
/* 弹窗 */
.modal-mask{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.45);z-index:500;display:flex;align-items:center;justify-content:center;opacity:0;pointer-events:none;transition:opacity .15s;}
.modal-mask.show{opacity:1;pointer-events:auto;}
.modal{background:#fff;border-radius:var(--radius-lg);width:680px;max-height:85vh;overflow-y:auto;box-shadow:0 8px 40px rgba(0,0,0,0.18);}
.modal__header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px 16px;border-bottom:1px solid var(--border);}
.modal__header h3{font-size:var(--font-lg);font-weight:600;}
.modal__close{width:32px;height:32px;border:none;background:none;cursor:pointer;font-size:20px;color:var(--text-secondary);border-radius:var(--radius-sm);display:flex;align-items:center;justify-content:center;}
.modal__close:hover{background:#f5f5f5;color:var(--text-primary);}
.modal__body{padding:24px;}
.detail-section{margin-bottom:20px;}.detail-section:last-child{margin-bottom:0;}
.detail-section__title{font-size:var(--font-sm);font-weight:600;color:var(--text-primary);margin-bottom:12px;padding-left:8px;border-left:3px solid var(--primary);}
.detail-grid{display:grid;grid-template-columns:1fr 1fr 1fr;gap:0;}
.detail-item{display:flex;justify-content:space-between;align-items:center;padding:10px 12px;border:1px solid #f0f0f0;margin:-0.5px;}
.detail-item__label{font-size:var(--font-xs);color:var(--text-secondary);}
.detail-item__value{font-size:var(--font-xs);color:var(--text-primary);font-weight:500;}
/* Toast */
.toast{position:fixed;top:80px;left:50%;transform:translateX(-50%);background:#333;color:#fff;padding:10px 24px;border-radius:var(--radius-sm);font-size:var(--font-sm);z-index:9999;opacity:0;transition:opacity .2s;pointer-events:none;}
.toast.show{opacity:1;}
/* 年份选择 */
.filter-select{height:32px;min-width:110px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 10px;font-size:var(--font-xs);color:var(--text-primary);background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 8px center;cursor:pointer;outline:none;appearance:none;-webkit-appearance:none;}
</style>
</head>
<body>
<!-- 顶部导航 -->
<header class="top-bar">
<div class="top-bar__logo">
<svg viewBox="0 0 28 28" fill="none"><rect width="28" height="28" rx="6" fill="#1890FF"/><path d="M7 14h14M14 7v14" stroke="#fff" stroke-width="2.5" stroke-linecap="round"/></svg>
体重管理
</div>
<!-- 顶部导航 -->
<div class="top-bar">
<div class="top-bar__logo"><svg viewBox="0 0 28 28" fill="none"><rect width="28" height="28" rx="6" fill="#1890FF"/><path d="M7 14h14M14 7v14" stroke="#fff" stroke-width="2.5" stroke-linecap="round"/></svg> 体重管理</div>
<nav class="top-bar__nav">
<a href="archive-personal-weight-data.html" class="active">档案</a>
<a href="plan-list.html">计划管理</a>
@@ -111,19 +125,22 @@ tbody tr:hover{background:#F8FBFF;}
<div class="top-bar__right">
<a class="btn-back" href="../../index.html"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg> 返回首页</a>
<div class="avatar"></div>
<span>系统管理员 ▾</span>
<span style="color:rgba(255,255,255,0.65);">系统管理员 ▾</span>
</div>
</header>
</div>
<!-- 侧边栏 -->
<aside class="sidebar">
<div class="sidebar-menu__title">档案</div>
<a class="sidebar-item active" href="archive-personal-weight-data.html">个人体重数据</a>
<a class="sidebar-item" href="archive-unit-report.html">单位报表数据</a>
<a class="sidebar-item" href="archive-algorithm-model.html">算法模型</a>
<a href="archive-personal-weight-data.html" class="sidebar-item active">个人体重数据</a>
<a href="archive-unit-report.html" class="sidebar-item">单位报表数据</a>
<a href="archive-algorithm-model.html" class="sidebar-item">算法模型</a>
</aside>
<!-- 主内容区 -->
<div class="main">
<!-- 返回+面包屑 -->
<!-- 主内容 -->
<main class="main">
<!-- 返回 + 面包屑 -->
<div style="margin-bottom:12px;">
<a href="archive-personal-weight-data.html" style="display:inline-flex;align-items:center;gap:6px;color:var(--primary);text-decoration:none;font-size:var(--font-sm);">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
@@ -133,198 +150,372 @@ tbody tr:hover{background:#F8FBFF;}
<div class="breadcrumb">
<a href="archive-personal-weight-data.html">个人体重数据</a>
<span style="color:var(--text-placeholder);">/</span>
<span>详细信息</span>
<span id="breadcrumbName">详细数据</span>
</div>
<!-- 员工信息卡片 -->
<div class="info-card">
<div class="info-card__avatar" id="empAvatar"></div>
<div class="info-card__detail">
<div class="info-card__name" id="empName">张伟</div>
<div class="info-card__meta">
<span id="empCode">员工编号:EMP001</span>
<span id="empUnit">CQ能源总部</span>
<span id="empDept">研发部</span>
<div class="info-card__left">
<div class="info-card__avatar" id="empAvatar"></div>
<div class="info-card__detail">
<div class="info-card__name" id="empName">--</div>
<div class="info-card__meta">
<span id="empCode">员工编号:--</span>
<span id="empGender">性别:--</span>
<span id="empAge">年龄:--</span>
<span id="empUnit">单位:--</span>
<span id="empDept">部门:--</span>
</div>
</div>
</div>
<div class="info-card__right">
<div class="info-card__date-filter">
<label>年份</label>
<select class="filter-select" id="filterYear" onchange="onYearChange()">
<option value="2026">2026年</option>
<option value="2025">2025年</option>
<option value="2024">2024年</option>
</select>
</div>
</div>
</div>
<!-- Tab导航 + 内容区 -->
<div class="table-card" style="margin-top:16px;">
<!-- Tab导航栏 -->
<!-- 指标汇总卡片 -->
<div class="metrics-card">
<div class="metrics-card__title">体重管理指标变化</div>
<div class="metrics-grid" id="metricsGrid"></div>
</div>
<!-- Tab + 列表 -->
<div class="table-card" style="margin-top:0;">
<div class="tab-bar">
<div class="tab-item active" onclick="switchTab(0)">饮食记录</div>
<div class="tab-item" onclick="switchTab(1)">运动记录</div>
<div class="tab-item" onclick="switchTab(2)">体重记录</div>
</div>
<!-- Tab面板:饮食记录 -->
<!-- 饮食记录 -->
<div class="tab-panel active" id="tab-panel-0">
<div class="table-card__content">
<table>
<thead>
<tr><th>时间</th><th>餐次</th><th>摄入热量(千卡)</th><th>来源</th></tr>
</thead>
<tbody>
<tr><td>2026-05-10 07:30</td><td><span class="tag tag-blue">早餐</span></td><td>356</td><td><span class="tag tag-green">智记</span></td></tr>
<tr><td>2026-05-10 12:15</td><td><span class="tag tag-green">午餐</span></td><td>520</td><td><span class="tag tag-gray">自记</span></td></tr>
<tr><td>2026-05-10 15:30</td><td><span class="tag tag-gray">加餐</span></td><td>185</td><td><span class="tag tag-green">智记</span></td></tr>
<tr><td>2026-05-10 18:45</td><td><span class="tag tag-green">晚餐</span></td><td>410</td><td><span class="tag tag-gray">自记</span></td></tr>
<tr><td>2026-05-09 08:00</td><td><span class="tag tag-blue">早餐</span></td><td>345</td><td><span class="tag tag-green">智记</span></td></tr>
<tr><td>2026-05-09 12:00</td><td><span class="tag tag-green">午餐</span></td><td>580</td><td><span class="tag tag-gray">自记</span></td></tr>
<tr><td>2026-05-09 19:00</td><td><span class="tag tag-green">晚餐</span></td><td>395</td><td><span class="tag tag-green">智记</span></td></tr>
</tbody>
<tbody id="dietBody"></tbody>
</table>
</div>
<div class="pagination"><span>共 345 条</span><button class="page-btn"></button><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">...</button><button class="page-btn">50</button><button class="page-btn"></button></div>
<div class="pagination">
<span id="dietPageInfo">共 0 条</span>
<button class="page-btn" onclick="dietGoPage(-1)"></button>
<span id="dietPageNum">第 1 页</span>
<button class="page-btn" onclick="dietGoPage(1)"></button>
</div>
</div>
<!-- Tab面板:运动记录 -->
<!-- 运动记录 -->
<div class="tab-panel" id="tab-panel-1">
<div class="table-card__content">
<table>
<thead>
<tr><th>时间</th><th>运动类型</th><th>运动时长/运动数据</th><th>消耗热量(千卡)</th><th>来源</th></tr>
<tr><th>时间</th><th>运动类型</th><th>运动时长/数据</th><th>消耗热量(千卡)</th><th>来源</th></tr>
</thead>
<tbody>
<tr><td>2026-05-10 06:30</td><td>跑步</td><td>45min</td><td>420</td><td><span class="tag tag-blue">穿戴</span></td></tr>
<tr><td>2026-05-10 08:00</td><td>步行</td><td>12,500步</td><td>320</td><td><span class="tag tag-green">微信</span></td></tr>
<tr><td>2026-05-09 12:00</td><td>器械推胸</td><td>60min</td><td>380</td><td><span class="tag tag-gray">自己</span></td></tr>
<tr><td>2026-05-08 18:00</td><td>游泳</td><td>40min</td><td>350</td><td><span class="tag tag-orange">器械</span></td></tr>
<tr><td>2026-05-07 08:00</td><td>瑜伽</td><td>50min</td><td>180</td><td><span class="tag tag-gray">自己</span></td></tr>
<tr><td>2026-05-07 18:30</td><td>步行</td><td>8,200步</td><td>210</td><td><span class="tag tag-green">微信</span></td></tr>
<tr><td>2026-05-06 16:00</td><td>骑行</td><td>90min</td><td>560</td><td><span class="tag tag-blue">穿戴</span></td></tr>
<tr><td>2026-05-05 10:00</td><td>深蹲</td><td>55min</td><td>410</td><td><span class="tag tag-orange">器械</span></td></tr>
</tbody>
<tbody id="sportBody"></tbody>
</table>
</div>
<div class="pagination"><span>共 128 条</span><button class="page-btn"></button><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">...</button><button class="page-btn">21</button><button class="page-btn"></button></div>
<div class="pagination">
<span id="sportPageInfo">共 0 条</span>
<button class="page-btn" onclick="sportGoPage(-1)"></button>
<span id="sportPageNum">第 1 页</span>
<button class="page-btn" onclick="sportGoPage(1)"></button>
</div>
</div>
<!-- Tab面板:体重记录 -->
<!-- 体重记录 -->
<div class="tab-panel" id="tab-panel-2">
<div class="table-card__content">
<table>
<thead>
<tr><th>时间</th><th>体重(kg)</th><th>BMI</th><th>体脂率(%)</th><th>腰围(cm)</th><th>来源</th></tr>
</thead>
<tbody>
<tr><td>2026-05-10 08:30</td><td>72.5</td><td>23.7</td><td>18.2</td><td>82</td><td><span class="tag tag-blue">身高秤</span></td></tr>
<tr><td>2026-05-08 07:45</td><td>72.8</td><td>23.8</td><td>18.4</td><td>83</td><td><span class="tag tag-orange">体脂仪</span></td></tr>
<tr><td>2026-05-06 18:20</td><td>73.0</td><td>23.8</td><td>18.5</td><td>82</td><td><span class="tag tag-green">蓝牙称</span></td></tr>
<tr><td>2026-05-04 08:10</td><td>72.3</td><td>23.6</td><td>18.1</td><td>81</td><td><span class="tag tag-blue">身高秤</span></td></tr>
<tr><td>2026-05-03 20:00</td><td>73.2</td><td>23.9</td><td>18.6</td><td>84</td><td><span class="tag tag-gray">自记</span></td></tr>
<tr><td>2026-05-02 09:00</td><td>73.2</td><td>23.9</td><td>18.6</td><td>84</td><td><span class="tag tag-orange">体脂仪</span></td></tr>
</tbody>
<tbody id="weightBody"></tbody>
</table>
</div>
<div class="pagination"><span>共 142 条</span><button class="page-btn"></button><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">...</button><button class="page-btn">15</button><button class="page-btn"></button></div>
<div class="pagination">
<span id="weightPageInfo">共 0 条</span>
<button class="page-btn" onclick="weightGoPage(-1)"></button>
<span id="weightPageNum">第 1 页</span>
<button class="page-btn" onclick="weightGoPage(1)"></button>
</div>
</div>
</div>
</div>
<!-- 体重详情弹窗 -->
<div class="modal-mask" id="weightModal">
<div class="modal">
<div class="modal__header"><h3 id="weightModalTitle">测量详情</h3><button class="modal__close" onclick="closeWeightModal()">×</button></div>
<div class="modal__body" id="weightModalBody"></div>
</div>
</div>
<!-- 饮食详情弹窗 -->
<div class="modal-mask" id="dietModal">
<div class="modal">
<div class="modal__header"><h3 id="dietModalTitle">饮食详情</h3><button class="modal__close" onclick="closeDietModal()">×</button></div>
<div class="modal__body" id="dietModalBody"></div>
</div>
</div>
<!-- 运动详情弹窗 -->
<div class="modal-mask" id="sportModal">
<div class="modal">
<div class="modal__header"><h3 id="sportModalTitle">运动详情</h3><button class="modal__close" onclick="closeSportModal()">×</button></div>
<div class="modal__body" id="sportModalBody"></div>
</div>
</div>
</main>
<!-- Toast -->
<div class="toast" id="toast"></div>
<script>
// 侧边栏菜单项点击高亮
document.querySelectorAll('.sidebar-item').forEach(function(item) {
item.addEventListener('click', function() {
document.querySelectorAll('.sidebar-item').forEach(function(i) { i.classList.remove('active'); });
this.classList.add('active');
});
});
// Tab切换
function switchTab(idx) {
document.querySelectorAll('.tab-item').forEach(function(el, i) {
el.classList.toggle('active', i === idx);
});
document.querySelectorAll('.tab-panel').forEach(function(el, i) {
el.classList.toggle('active', i === idx);
});
}
// 体重详情弹窗
var weightRecords=[
{device:'体重秤',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"}}},
{device:'体脂仪',data:{"基础指标":{"身高(cm)":"175","体重(kg)":"72.8","BMI":"23.8","基础代谢":"1,675","InBody评分(分)":"65"},"体脂分析":{"体脂肪量(kg)":"13.4","体脂肪率(%)":"18.4","内脏脂肪等级":"6","去脂体重(kg)":"59.4"},"体成分":{"体水分(L)":"43.5","蛋白质(kg)":"11.5","无机盐(kg)":"4.05","骨骼肌量(kg)":"33.2"}}},
{device:'蓝牙称',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"}}},
{device:'体重秤',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"}}},
{device:'体脂仪',data:{"基础指标":{"身高(cm)":"175","体重(kg)":"73.2","BMI":"23.9","基础代谢":"1,685","InBody评分(分)":"63"},"体脂分析":{"体脂肪量(kg)":"13.6","体脂肪率(%)":"18.6","内脏脂肪等级":"6","去脂体重(kg)":"59.6"},"体成分":{"体水分(L)":"43.8","蛋白质(kg)":"11.5","无机盐(kg)":"4.08","骨骼肌量(kg)":"33.4"}}}
];
function openWeightModal(idx){
var r=weightRecords[idx];document.getElementById('weightModalTitle').textContent='测量详情 - '+r.device;
var html='';for(var section in r.data){html+='<div class="detail-section"><div class="detail-section__title">'+section+'</div><div class="detail-grid">';var items=r.data[section];for(var k in items){html+='<div class="detail-item"><span class="detail-item__label">'+k+'</span><span class="detail-item__value">'+items[k]+'</span></div>';}html+='</div></div>';}
document.getElementById('weightModalBody').innerHTML=html;document.getElementById('weightModal').classList.add('show');
}
function closeWeightModal(){document.getElementById('weightModal').classList.remove('show');}
document.getElementById('weightModal').addEventListener('click',function(e){if(e.target===this)closeWeightModal();});
// 饮食详情弹窗
var dietRecords=[
{meal:'早餐',food:'鸡蛋 + 全麦面包 + 牛奶',detail:{"重量(g)":"280","热量(kcal)":"356","蛋白质(g)":"22.5","脂肪(g)":"12.8","碳水化合物(g)":"38.2","膳食纤维(g)":"5.6","钠(mg)":"320","钙(mg)":"180"}},
{meal:'午餐',food:'鸡胸肉 + 西兰花 + 糙米饭',detail:{"重量(g)":"450","热量(kcal)":"520","蛋白质(g)":"42.0","脂肪(g)":"14.5","碳水化合物(g)":"55.3","膳食纤维(g)":"8.2","钠(mg)":"450","钙(mg)":"120"}},
{meal:'加餐',food:'苹果 + 酸奶',detail:{"重量(g)":"250","热量(kcal)":"185","蛋白质(g)":"5.8","脂肪(g)":"3.2","碳水化合物(g)":"35.6","膳食纤维(g)":"4.5","钠(mg)":"85","钙(mg)":"200"}},
{meal:'晚餐',food:'清蒸鱼 + 凉拌黄瓜 + 小米粥',detail:{"重量(g)":"380","热量(kcal)":"410","蛋白质(g)":"35.2","脂肪(g)":"10.5","碳水化合物(g)":"42.8","膳食纤维(g)":"3.8","钠(mg)":"280","钙(mg)":"90"}},
{meal:'早餐',food:'燕麦粥 + 鸡蛋',detail:{"重量(g)":"320","热量(kcal)":"345","蛋白质(g)":"18.6","脂肪(g)":"10.2","碳水化合物(g)":"48.5","膳食纤维(g)":"6.0","钠(mg)":"220","钙(mg)":"160"}},
{meal:'午餐',food:'牛肉面 + 蔬菜沙拉',detail:{"重量(g)":"500","热量(kcal)":"580","蛋白质(g)":"32.5","脂肪(g)":"18.0","碳水化合物(g)":"68.3","膳食纤维(g)":"5.2","钠(mg)":"680","钙(mg)":"85"}},
{meal:'晚餐',food:'豆腐汤 + 杂粮饭 + 炒青菜',detail:{"重量(g)":"400","热量(kcal)":"395","蛋白质(g)":"20.0","脂肪(g)":"8.5","碳水化合物(g)":"58.2","膳食纤维(g)":"7.5","钠(mg)":"350","钙(mg)":"220"}}
];
function openDietModal(idx){
var r=dietRecords[idx];document.getElementById('dietModalTitle').textContent='饮食详情 - '+r.meal+' · '+r.food;
var html='';html+='<div class="detail-section"><div class="detail-section__title">营养成分</div><div class="detail-grid">';var items=r.detail;for(var k in items){html+='<div class="detail-item"><span class="detail-item__label">'+k+'</span><span class="detail-item__value">'+items[k]+'</span></div>';}html+='</div></div>';
document.getElementById('dietModalBody').innerHTML=html;document.getElementById('dietModal').classList.add('show');
}
function closeDietModal(){document.getElementById('dietModal').classList.remove('show');}
document.getElementById('dietModal').addEventListener('click',function(e){if(e.target===this)closeDietModal();});
// 运动详情弹窗
var sportRecords=[
{type:'有氧运动',name:'户外跑步',detail:{"运动类型":"有氧运动","运动名称":"户外跑步","时长(min)":"45","消耗热量(kcal)":"420","距离(km)":"6.5","平均配速":"6'55\"","平均心率":"142","最大心率":"168","步频":"175"}},
{type:'力量训练',name:'器械推胸 + 哑铃弯举',detail:{"运动类型":"力量训练","运动名称":"器械推胸 + 哑铃弯举","时长(min)":"60","消耗热量(kcal)":"380","组数":"12","器械推胸(kg)":"50","哑铃弯举(kg)":"12","平均心率":"125","最大心率":"148"}},
{type:'有氧运动',name:'游泳',detail:{"运动类型":"有氧运动","运动名称":"游泳","时长(min)":"40","消耗热量(kcal)":"350","距离(km)":"1.2","泳姿":"自由泳","平均心率":"135","最大心率":"158","划水频率":"28"}},
{type:'柔韧性',name:'瑜伽',detail:{"运动类型":"柔韧性","运动名称":"瑜伽","时长(min)":"50","消耗热量(kcal)":"180","体式数":"24","平均心率":"95","最大心率":"115","拉伸等级":"中级"}},
{type:'有氧运动',name:'骑行',detail:{"运动类型":"有氧运动","运动名称":"骑行","时长(min)":"90","消耗热量(kcal)":"560","距离(km)":"25.0","平均速度(km/h)":"16.7","平均心率":"138","最大心率":"162","爬升(m)":"180"}},
{type:'力量训练',name:'深蹲 + 硬拉 + 卧推',detail:{"运动类型":"力量训练","运动名称":"深蹲 + 硬拉 + 卧推","时长(min)":"55","消耗热量(kcal)":"410","组数":"15","深蹲(kg)":"80","硬拉(kg)":"90","卧推(kg)":"60","平均心率":"130","最大心率":"155"}}
];
function openSportModal(idx){
var r=sportRecords[idx];document.getElementById('sportModalTitle').textContent='运动详情 - '+r.name;
var html='';html+='<div class="detail-section"><div class="detail-section__title">运动数据</div><div class="detail-grid">';var items=r.detail;for(var k in items){html+='<div class="detail-item"><span class="detail-item__label">'+k+'</span><span class="detail-item__value">'+items[k]+'</span></div>';}html+='</div></div>';
document.getElementById('sportModalBody').innerHTML=html;document.getElementById('sportModal').classList.add('show');
}
function closeSportModal(){document.getElementById('sportModal').classList.remove('show');}
document.getElementById('sportModal').addEventListener('click',function(e){if(e.target===this)closeSportModal();});
// URL参数回显员工信息
/* ===== 侧边栏高亮 ===== */
(function(){
var params=new URLSearchParams(location.search);
var id=params.get('id');
var empData={EMP001:{name:'张伟',unit:'CQ能源总部',dept:'研发部'},EMP002:{name:'李娜',unit:'CQ能源总部',dept:'市场部'},EMP005:{name:'陈刚',unit:'CQ能源总部',dept:'人事部'},EMP003:{name:'王磊',unit:'采油一厂',dept:'运营部'},EMP004:{name:'赵敏',unit:'采油二厂',dept:'财务部'},'424234':{name:'李凯明',unit:'第四采油厂',dept:'岭南作业区'},'234223':{name:'张文胜',unit:'第四采油厂',dept:'虎狼山作业区'},'318756':{name:'王丽华',unit:'采油一厂',dept:'设备维护站'},'567890':{name:'刘建国',unit:'采气一厂',dept:'生产运行部'},'192847':{name:'陈思雨',unit:'CQ能源总部',dept:'人力资源部'},'445612':{name:'杨志强',unit:'采油二厂',dept:'后勤保障部'},'678901':{name:'赵晓峰',unit:'采油一厂',dept:'技术研发部'}};
var emp=empData[id]||empData.EMP001;
document.getElementById('empAvatar').textContent=emp.name.charAt(0);
document.getElementById('empName').textContent=emp.name;
document.getElementById('empCode').textContent='员工编号:'+(id||'EMP001');
document.getElementById('empUnit').textContent=emp.unit;
document.getElementById('empDept').textContent=emp.dept;
var current = location.pathname.split('/').pop();
document.querySelectorAll('.sidebar-item').forEach(function(item){
var href = item.getAttribute('href');
item.classList.toggle('active', href === current);
});
})();
/* ===== Mock 人员数据(与列表页共享) ===== */
var personnelData = [
{name:'张建国',empId:'CQ100235',gender:'男',age:42,unit:'第四采油厂',dept:'健康管理部',weightInit:86.0,weightFinal:81.8,weightChange:-4.2,bmiInit:29.5,bmiFinal:28.1,bmiChange:-1.4,fatInit:28.8,fatFinal:25.6,fatChange:-3.2,waistInit:99.0,waistFinal:93.9,waistChange:-5.1,dietCount:98,sportCount:72,weightCount:45},
{name:'李明辉',empId:'CQ100458',gender:'男',age:38,unit:'第四采油厂',dept:'安全环保科',weightInit:82.5,weightFinal:79.0,weightChange:-3.5,bmiInit:28.0,bmiFinal:26.9,bmiChange:-1.1,fatInit:26.5,fatFinal:23.7,fatChange:-2.8,waistInit:95.0,waistFinal:90.7,waistChange:-4.3,dietCount:85,sportCount:64,weightCount:38},
{name:'王秀兰',empId:'CQ100672',gender:'女',age:35,unit:'第四采油厂',dept:'工会办公室',weightInit:68.0,weightFinal:65.7,weightChange:-2.3,bmiInit:25.8,bmiFinal:25.0,bmiChange:-0.8,fatInit:33.0,fatFinal:31.1,fatChange:-1.9,waistInit:83.0,waistFinal:79.8,waistChange:-3.2,dietCount:72,sportCount:55,weightCount:32},
{name:'赵铁柱',empId:'CQ100891',gender:'男',age:45,unit:'第四采油厂',dept:'生产技术部',weightInit:93.0,weightFinal:87.9,weightChange:-5.1,bmiInit:32.0,bmiFinal:30.3,bmiChange:-1.7,fatInit:32.5,fatFinal:28.4,fatChange:-4.1,waistInit:106.0,waistFinal:99.5,waistChange:-6.5,dietCount:105,sportCount:80,weightCount:50},
{name:'陈小燕',empId:'CQ101023',gender:'女',age:29,unit:'第四采油厂',dept:'财务部',weightInit:62.5,weightFinal:60.7,weightChange:-1.8,bmiInit:23.8,bmiFinal:23.2,bmiChange:-0.6,fatInit:30.5,fatFinal:29.1,fatChange:-1.4,waistInit:78.5,waistFinal:76.0,waistChange:-2.5,dietCount:65,sportCount:48,weightCount:28},
{name:'刘大军',empId:'CQ101145',gender:'男',age:50,unit:'第四采油厂',dept:'信息中心',weightInit:89.0,weightFinal:86.0,weightChange:-3.0,bmiInit:30.5,bmiFinal:29.5,bmiChange:-1.0,fatInit:31.0,fatFinal:28.5,fatChange:-2.5,waistInit:101.0,waistFinal:97.2,waistChange:-3.8,dietCount:78,sportCount:42,weightCount:35},
{name:'周红梅',empId:'CQ101267',gender:'女',age:40,unit:'第四采油厂',dept:'健康管理部',weightInit:72.5,weightFinal:69.9,weightChange:-2.6,bmiInit:27.3,bmiFinal:26.4,bmiChange:-0.9,fatInit:34.5,fatFinal:32.4,fatChange:-2.1,waistInit:86.5,waistFinal:83.0,waistChange:-3.5,dietCount:82,sportCount:60,weightCount:40},
{name:'吴国强',empId:'CQ101389',gender:'男',age:33,unit:'第四采油厂',dept:'安全环保科',weightInit:78.0,weightFinal:78.8,weightChange:+0.8,bmiInit:26.5,bmiFinal:26.8,bmiChange:+0.3,fatInit:24.8,fatFinal:25.4,fatChange:+0.6,waistInit:89.5,waistFinal:90.7,waistChange:+1.2,dietCount:30,sportCount:18,weightCount:12}
];
/* ===== Mock 记录数据 ===== */
/* 饮食记录 */
var dietRecords = [
{time:'2026-07-01 07:30',meal:'早餐',calories:356,source:'智记'},
{time:'2026-07-01 12:15',meal:'午餐',calories:520,source:'自记'},
{time:'2026-07-01 18:45',meal:'晚餐',calories:410,source:'智记'},
{time:'2026-06-30 08:00',meal:'早餐',calories:345,source:'智记'},
{time:'2026-06-30 12:00',meal:'午餐',calories:580,source:'自记'},
{time:'2026-06-30 19:00',meal:'晚餐',calories:395,source:'智记'},
{time:'2026-06-29 07:45',meal:'早餐',calories:320,source:'自记'},
{time:'2026-06-29 12:30',meal:'午餐',calories:510,source:'智记'},
{time:'2026-06-29 15:30',meal:'加餐',calories:185,source:'智记'},
{time:'2026-06-29 18:30',meal:'晚餐',calories:440,source:'自记'},
{time:'2026-06-28 08:10',meal:'早餐',calories:360,source:'自记'},
{time:'2026-06-28 12:20',meal:'午餐',calories:495,source:'智记'},
{time:'2026-06-28 19:15',meal:'晚餐',calories:420,source:'智记'},
{time:'2026-06-27 07:30',meal:'早餐',calories:338,source:'智记'},
{time:'2026-06-27 12:00',meal:'午餐',calories:550,source:'自记'},
{time:'2026-06-27 18:00',meal:'晚餐',calories:385,source:'自记'},
{time:'2026-06-26 08:00',meal:'早餐',calories:350,source:'智记'},
{time:'2026-06-26 12:30',meal:'午餐',calories:505,source:'智记'},
{time:'2026-06-26 16:00',meal:'加餐',calories:150,source:'自记'},
{time:'2026-06-26 19:00',meal:'晚餐',calories:430,source:'智记'}
];
/* 运动记录 */
var sportRecords = [
{time:'2026-07-01 06:30',type:'跑步',data:'45min',calories:420,source:'穿戴'},
{time:'2026-07-01 08:00',type:'步行',data:'12,500步',calories:320,source:'微信'},
{time:'2026-06-30 12:00',type:'器械推胸',data:'60min',calories:380,source:'自记'},
{time:'2026-06-29 18:00',type:'游泳',data:'40min',calories:350,source:'器械'},
{time:'2026-06-28 08:00',type:'瑜伽',data:'50min',calories:180,source:'自记'},
{time:'2026-06-28 18:30',type:'步行',data:'8,200步',calories:210,source:'微信'},
{time:'2026-06-27 16:00',type:'骑行',data:'90min',calories:560,source:'穿戴'},
{time:'2026-06-26 10:00',type:'深蹲',data:'55min',calories:410,source:'器械'},
{time:'2026-06-25 07:00',type:'跑步',data:'30min',calories:280,source:'穿戴'},
{time:'2026-06-25 17:30',type:'步行',data:'10,200步',calories:260,source:'微信'},
{time:'2026-06-24 11:00',type:'哑铃弯举',data:'40min',calories:310,source:'自记'},
{time:'2026-06-23 08:30',type:'跳绳',data:'25min',calories:350,source:'穿戴'},
{time:'2026-06-22 19:00',type:'游泳',data:'60min',calories:480,source:'器械'},
{time:'2026-06-21 06:00',type:'跑步',data:'50min',calories:460,source:'穿戴'},
{time:'2026-06-20 12:30',type:'步行',data:'9,800步',calories:250,source:'微信'}
];
/* 体重记录 */
var weightRecords = [
{time:'2026-07-01 08:30',weight:81.8,bmi:28.1,fatRate:25.6,waist:93.9,source:'身高秤'},
{time:'2026-06-28 07:45',weight:82.1,bmi:28.2,fatRate:25.8,waist:94.2,source:'体脂仪'},
{time:'2026-06-25 18:20',weight:82.5,bmi:28.4,fatRate:26.1,waist:94.8,source:'蓝牙称'},
{time:'2026-06-22 08:10',weight:82.9,bmi:28.5,fatRate:26.3,waist:95.1,source:'身高秤'},
{time:'2026-06-19 20:00',weight:83.2,bmi:28.6,fatRate:26.6,waist:95.5,source:'自记'},
{time:'2026-06-16 09:00',weight:83.7,bmi:28.8,fatRate:26.9,waist:96.0,source:'体脂仪'},
{time:'2026-06-13 07:30',weight:84.1,bmi:28.9,fatRate:27.2,waist:96.4,source:'蓝牙称'},
{time:'2026-06-10 18:00',weight:84.5,bmi:29.1,fatRate:27.5,waist:96.7,source:'身高秤'},
{time:'2026-06-07 08:45',weight:84.9,bmi:29.2,fatRate:27.8,waist:97.2,source:'体脂仪'},
{time:'2026-06-04 19:30',weight:85.2,bmi:29.3,fatRate:28.1,waist:97.6,source:'自记'},
{time:'2026-06-01 08:00',weight:85.6,bmi:29.4,fatRate:28.4,waist:98.2,source:'蓝牙称'},
{time:'2026-05-28 07:15',weight:85.9,bmi:29.5,fatRate:28.7,waist:98.7,source:'身高秤'}
];
var pageSize = 10;
var dietPage = 0, sportPage = 0, weightPage = 0;
var currentYear = '2026';
/* ===== Tab 切换 ===== */
function switchTab(idx){
document.querySelectorAll('.tab-item').forEach(function(el,i){el.classList.toggle('active',i===idx);});
document.querySelectorAll('.tab-panel').forEach(function(el,i){el.classList.toggle('active',i===idx);});
}
/* ===== 年份切换 ===== */
function onYearChange(){
currentYear = document.getElementById('filterYear').value;
dietPage = 0; sportPage = 0; weightPage = 0;
renderDiet();
renderSport();
renderWeight();
}
/* ===== 按年份过滤 ===== */
function filterByYear(records){
if(!currentYear) return records;
return records.filter(function(r){
return r.time.indexOf(currentYear) === 0;
});
}
/* ===== 指标变化渲染 ===== */
function renderMetrics(emp){
var metrics = [
{label:'体重(kg)',init:emp.weightInit,final:emp.weightFinal,change:emp.weightChange},
{label:'BMI',init:emp.bmiInit,final:emp.bmiFinal,change:emp.bmiChange,decimals:1},
{label:'体脂(%)',init:emp.fatInit,final:emp.fatFinal,change:emp.fatChange},
{label:'腰围(cm)',init:emp.waistInit,final:emp.waistFinal,change:emp.waistChange}
];
var html = '';
metrics.forEach(function(m){
var cls = m.change < 0 ? 'change-down' : (m.change > 0 ? 'change-up' : 'change-zero');
var sign = m.change > 0 ? '+' : '';
html += '<div class="metric-group">';
html += '<div class="metric-group__label">'+m.label+'</div>';
html += '<div class="metric-row">';
html += '<div class="metric-row__item"><span class="metric-row__sub">初始</span><span class="metric-row__val">'+m.init.toFixed(1)+'</span></div>';
html += '<span class="metric-arrow">→</span>';
html += '<div class="metric-row__item"><span class="metric-row__sub">最终</span><span class="metric-row__val">'+m.final.toFixed(1)+'</span></div>';
html += '<span class="metric-arrow" style="margin-left:8px;"></span>';
html += '<div class="metric-row__item"><span class="metric-row__sub">变化</span><span class="metric-row__val '+cls+'">'+sign+m.change.toFixed(1)+'</span></div>';
html += '</div></div>';
});
document.getElementById('metricsGrid').innerHTML = html;
}
/* ===== 饮食记录渲染 ===== */
function renderDiet(){
var tbody = document.getElementById('dietBody');
var filtered = filterByYear(dietRecords);
var start = dietPage * pageSize;
var pageData = filtered.slice(start, start + pageSize);
var totalPages = Math.ceil(filtered.length / pageSize) || 1;
document.getElementById('dietPageInfo').textContent = '共 ' + filtered.length + ' 条';
document.getElementById('dietPageNum').textContent = '第 ' + (dietPage + 1) + '/' + totalPages + ' 页';
var srcTag = {智记:'tag-green',自记:'tag-gray'};
var html = '';
pageData.forEach(function(d){
html += '<tr>';
html += '<td>'+d.time+'</td>';
html += '<td>'+d.meal+'</td>';
html += '<td>'+d.calories+'</td>';
html += '<td><span class="tag '+ (srcTag[d.source]||'tag-gray') +'">'+d.source+'</span></td>';
html += '</tr>';
});
tbody.innerHTML = html || '<tr><td colspan="4" style="text-align:center;padding:48px 0;color:#999;">暂无饮食记录</td></tr>';
}
function dietGoPage(delta){
var filtered = filterByYear(dietRecords);
var totalPages = Math.ceil(filtered.length / pageSize);
var np = dietPage + delta;
if(np < 0 || np >= totalPages) return;
dietPage = np;
renderDiet();
}
/* ===== 运动记录渲染 ===== */
function renderSport(){
var tbody = document.getElementById('sportBody');
var filtered = filterByYear(sportRecords);
var start = sportPage * pageSize;
var pageData = filtered.slice(start, start + pageSize);
var totalPages = Math.ceil(filtered.length / pageSize) || 1;
document.getElementById('sportPageInfo').textContent = '共 ' + filtered.length + ' 条';
document.getElementById('sportPageNum').textContent = '第 ' + (sportPage + 1) + '/' + totalPages + ' 页';
var srcTag = {穿戴:'tag-blue',微信:'tag-green',自记:'tag-gray',器械:'tag-orange'};
var html = '';
pageData.forEach(function(d){
html += '<tr>';
html += '<td>'+d.time+'</td>';
html += '<td>'+d.type+'</td>';
html += '<td>'+d.data+'</td>';
html += '<td>'+d.calories+'</td>';
html += '<td><span class="tag '+ (srcTag[d.source]||'tag-gray') +'">'+d.source+'</span></td>';
html += '</tr>';
});
tbody.innerHTML = html || '<tr><td colspan="5" style="text-align:center;padding:48px 0;color:#999;">暂无运动记录</td></tr>';
}
function sportGoPage(delta){
var filtered = filterByYear(sportRecords);
var totalPages = Math.ceil(filtered.length / pageSize);
var np = sportPage + delta;
if(np < 0 || np >= totalPages) return;
sportPage = np;
renderSport();
}
/* ===== 体重记录渲染 ===== */
function renderWeight(){
var tbody = document.getElementById('weightBody');
var filtered = filterByYear(weightRecords);
var start = weightPage * pageSize;
var pageData = filtered.slice(start, start + pageSize);
var totalPages = Math.ceil(filtered.length / pageSize) || 1;
document.getElementById('weightPageInfo').textContent = '共 ' + filtered.length + ' 条';
document.getElementById('weightPageNum').textContent = '第 ' + (weightPage + 1) + '/' + totalPages + ' 页';
var srcTag = {身高秤:'tag-blue',体脂仪:'tag-orange',蓝牙称:'tag-green',自记:'tag-gray'};
var html = '';
pageData.forEach(function(d){
html += '<tr>';
html += '<td>'+d.time+'</td>';
html += '<td>'+d.weight.toFixed(1)+'</td>';
html += '<td>'+d.bmi.toFixed(1)+'</td>';
html += '<td>'+d.fatRate.toFixed(1)+'</td>';
html += '<td>'+d.waist.toFixed(1)+'</td>';
html += '<td><span class="tag '+ (srcTag[d.source]||'tag-gray') +'">'+d.source+'</span></td>';
html += '</tr>';
});
tbody.innerHTML = html || '<tr><td colspan="6" style="text-align:center;padding:48px 0;color:#999;">暂无体重记录</td></tr>';
}
function weightGoPage(delta){
var filtered = filterByYear(weightRecords);
var totalPages = Math.ceil(filtered.length / pageSize);
var np = weightPage + delta;
if(np < 0 || np >= totalPages) return;
weightPage = np;
renderWeight();
}
/* ===== 初始化 ===== */
(function init(){
var params = new URLSearchParams(location.search);
var empId = params.get('id') || 'CQ100235';
var year = params.get('year') || '2026';
// 年份默认值
currentYear = year;
document.getElementById('filterYear').value = year;
var emp = personnelData.find(function(p){return p.empId === empId;}) || personnelData[0];
// 面包屑
document.getElementById('breadcrumbName').textContent = emp.name;
// 员工信息
document.getElementById('empAvatar').textContent = emp.name.charAt(0);
document.getElementById('empName').textContent = emp.name;
document.getElementById('empCode').textContent = '员工编号:'+emp.empId;
document.getElementById('empGender').textContent = '性别:'+emp.gender;
document.getElementById('empAge').textContent = '年龄:'+emp.age;
document.getElementById('empUnit').textContent = '单位:'+emp.unit;
document.getElementById('empDept').textContent = '部门:'+emp.dept;
// 指标
renderMetrics(emp);
// 三个tab表格
renderDiet();
renderSport();
renderWeight();
})();
</script>
</body>
+24 -53
View File
@@ -107,7 +107,7 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
/* 表格卡片 */
.table-card{background:#fff;border-radius:0 0 var(--radius-md) var(--radius-md);box-shadow:var(--shadow-sm);overflow:hidden;}
.table-card__content{overflow-x:auto;-webkit-overflow-scrolling:touch;}
.table-card__content table{min-width:4800px;white-space:nowrap;}
.table-card__content table{min-width:1600px;white-space:nowrap;}
table{width:100%;border-collapse:collapse;}
/* 表头 - 两行结构 */
@@ -225,9 +225,9 @@ tbody tr:hover td:last-child{background:#F8FBFF;}
<aside class="sidebar">
<div class="sidebar-menu__title">过程管理</div>
<a href="action-record.html" class="sidebar-item">行动记录</a>
<a href="action-overview.html" class="sidebar-item">活动总览</a>
<a href="detail-data.html" class="sidebar-item active">详细数据</a>
<a href="weight-ranking.html" class="sidebar-item">体重排名</a>
<a href="action-overview.html" class="sidebar-item">活动总览</a>
<a href="activity-statistics.html" class="sidebar-item">活动统计</a>
</aside>
@@ -351,25 +351,9 @@ tbody tr:hover td:last-child{background:#F8FBFF;}
<th rowspan="2">部门</th>
<th rowspan="2">日期</th>
<th rowspan="2">身高<br>(cm)</th>
<th rowspan="2">初始<br>体重(kg)</th>
<th rowspan="2">初始<br>BMI</th>
<th rowspan="2">初始<br>体脂(%)</th>
<th rowspan="2">初始<br>腰围(cm)</th>
<th rowspan="2">目标<br>体重(kg)</th>
<th rowspan="2">目标<br>BMI</th>
<th rowspan="2">目标<br>体脂(%)</th>
<th rowspan="2">目标<br>腰围(cm)</th>
<th rowspan="2">现体重<br>(kg)</th>
<th rowspan="2">现BMI</th>
<th rowspan="2">现体脂<br>(%)</th>
<th rowspan="2">现腰围<br>(cm)</th>
<th rowspan="2">体重变化<br>(kg)</th>
<th rowspan="2">BMI变化</th>
<th rowspan="2">体脂变化<br>(%)</th>
<th rowspan="2">腰围变化<br>(cm)</th>
<th class="th-parent" colspan="4">饮食摄入(千卡)</th>
<th class="th-parent" colspan="1">运动消耗(千卡)</th>
<th class="th-parent" colspan="1">体重(kg)</th>
<th class="th-parent" colspan="2">运动消耗(千卡)</th>
<th class="th-parent" colspan="3">体重记录</th>
<th rowspan="2">体重报告</th>
</tr>
<!-- [交互] 表头第二行:饮食摄入、运动消耗、体重的子列 -->
@@ -378,8 +362,11 @@ tbody tr:hover td:last-child{background:#F8FBFF;}
<th>午餐</th>
<th>晚餐</th>
<th class="col-diet-last">加餐</th>
<th class="col-exercise-last">当日消耗</th>
<th class="col-weight-last">当日体重</th>
<th>基础消耗</th>
<th class="col-exercise-last">其他消耗</th>
<th>体重</th>
<th>体脂</th>
<th class="col-weight-last">腰围</th>
</tr>
</thead>
<tbody id="tableBody"></tbody>
@@ -539,8 +526,12 @@ function buildDailyData(){
var snack = Math.floor(Math.random() * 150);
// 运动消耗
var exercise = Math.floor(Math.random() * 300) + 150;
// 最新体重(略高于现体重,带微小波动)
var baseExercise = Math.floor(exercise * 0.6);
var otherExercise = exercise - baseExercise;
// 最新体重指标
var latestWeight = +(curWeight + (Math.random() - 0.3) * 0.5).toFixed(1);
var latestFat = +(curFat + (Math.random() - 0.5) * 0.4).toFixed(1);
var latestWaist = Math.round(curWaist + (Math.random() - 0.5) * 1);
data.push({
planId: p.id, planName: p.name,
org: e.org, dept: e.dept,
@@ -553,7 +544,8 @@ function buildDailyData(){
curWeight: curWeight, curBmi: curBmi, curFat: curFat, curWaist: curWaist,
weightChange: weightChange, bmiChange: bmiChange, fatChange: fatChange, waistChange: waistChange,
breakfast: breakfast, lunch: lunch, dinner: dinner, snack: snack,
exercise: exercise, latestWeight: latestWeight
exercise: exercise, baseExercise: baseExercise, otherExercise: otherExercise,
latestWeight: latestWeight, latestFat: latestFat, latestWaist: latestWaist
});
});
});
@@ -721,19 +713,11 @@ function renderTable(){
document.getElementById('pageInfo').textContent = '显示 ' + pageData.length + ' 条,共 ' + filteredData.length + ' 条记录';
document.getElementById('pageNum').textContent = '第 ' + (currentPage + 1) + '/' + totalPages + ' 页';
if(filteredData.length === 0){
tbody.innerHTML = '<tr><td colspan="29" class="td-empty">暂无匹配数据,请选择干预计划后查看</td></tr>';
tbody.innerHTML = '<tr><td colspan="19" class="td-empty">暂无匹配数据,请选择干预计划后查看</td></tr>';
return;
}
var html = '';
pageData.forEach(function(d){
var wcCls = d.weightChange < 0 ? 'change-down' : (d.weightChange > 0 ? 'change-up' : 'change-zero');
var bcCls = d.bmiChange < 0 ? 'change-down' : (d.bmiChange > 0 ? 'change-up' : 'change-zero');
var fcCls = d.fatChange < 0 ? 'change-down' : (d.fatChange > 0 ? 'change-up' : 'change-zero');
var wacCls = d.waistChange < 0 ? 'change-down' : (d.waistChange > 0 ? 'change-up' : 'change-zero');
var wcSign = d.weightChange > 0 ? '+' : '';
var bcSign = d.bmiChange > 0 ? '+' : '';
var fcSign = d.fatChange > 0 ? '+' : '';
var wacSign = d.waistChange > 0 ? '+' : '';
html += '<tr>';
html += '<td>'+esc(d.planName)+'</td>';
html += '<td>'+esc(d.name)+'</td>';
@@ -744,31 +728,18 @@ function renderTable(){
html += '<td>'+esc(d.dept)+'</td>';
html += '<td>'+d.date+'</td>';
html += '<td>'+d.height+'</td>';
html += '<td>'+d.initWeight+'</td>';
html += '<td>'+d.initBmi.toFixed(1)+'</td>';
html += '<td>'+d.initFat.toFixed(1)+'</td>';
html += '<td>'+d.initWaist+'</td>';
html += '<td>'+d.targetWeight+'</td>';
html += '<td>'+d.targetBmi+'</td>';
html += '<td>'+d.targetFat+'</td>';
html += '<td>'+d.targetWaist+'</td>';
html += '<td>'+d.curWeight+'</td>';
html += '<td>'+d.curBmi.toFixed(1)+'</td>';
html += '<td>'+d.curFat.toFixed(1)+'</td>';
html += '<td>'+d.curWaist+'</td>';
html += '<td class="'+wcCls+'">'+wcSign+d.weightChange+'</td>';
html += '<td class="'+bcCls+'">'+bcSign+d.bmiChange+'</td>';
html += '<td class="'+fcCls+'">'+fcSign+d.fatChange+'</td>';
html += '<td class="'+wacCls+'">'+wacSign+d.waistChange+'</td>';
// 饮食摄入(千卡):早餐、午餐、晚餐、加餐
html += '<td>'+d.breakfast+'</td>';
html += '<td>'+d.lunch+'</td>';
html += '<td>'+d.dinner+'</td>';
html += '<td class="col-diet-last">'+d.snack+'</td>';
// 运动消耗(千卡):今日消耗
html += '<td class="col-exercise-last">'+d.exercise+'</td>';
// 体重:最新体重
html += '<td class="col-weight-last">'+d.latestWeight+'</td>';
// 运动消耗(千卡):基础消耗、其他消耗
html += '<td>'+d.baseExercise+'</td>';
html += '<td class="col-exercise-last">'+d.otherExercise+'</td>';
// 体重记录:体重、体脂、腰围
html += '<td>'+d.latestWeight+'</td>';
html += '<td>'+d.latestFat.toFixed(1)+'</td>';
html += '<td class="col-weight-last">'+d.latestWaist+'</td>';
// 体重报告
html += '<td><a class="link" href="javascript:void(0)" onclick="viewWeightReport(\''+esc(d.empId)+'\',\''+esc(d.name)+'\',\''+d.date+'\')">查看</a></td>';
html += '</tr>';
@@ -0,0 +1,496 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>人员详情 | 历史干预 | 体重管理</title>
<style>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;min-width:1280px;}
:root{
--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;
--text-primary:#333;--text-secondary:#666;--text-placeholder:#999;--border:#E8E8E8;--background:#F5F7FA;
--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--font-xl:20px;
--radius-sm:4px;--radius-md:8px;--radius-lg:12px;
--shadow-sm:0 1px 4px rgba(0,0,0,0.08);--shadow-md:0 4px 12px rgba(0,0,0,0.12);
}
/* 顶部导航栏 */
.top-bar{display:flex;align-items:center;height:56px;background:#001529;padding:0 24px;position:fixed;top:0;left:0;right:0;z-index:100;}
.top-bar__logo{display:flex;align-items:center;gap:8px;color:#fff;font-size:var(--font-lg);font-weight:600;white-space:nowrap;width:240px;flex-shrink:0;}
.top-bar__logo svg{width:28px;height:28px;}
.top-bar__nav{display:flex;align-items:center;gap:4px;flex:1;}
.top-bar__nav a{color:rgba(255,255,255,0.65);text-decoration:none;padding:6px 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);transition:all .2s;}
.top-bar__nav a:hover{color:#fff;background:rgba(255,255,255,0.08);}
.top-bar__nav a.active{color:#fff;background:var(--primary);}
.top-bar__right{display:flex;align-items:center;gap:16px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);}
.btn-back{color:rgba(255,255,255,0.65);cursor:pointer;display:flex;align-items:center;gap:4px;text-decoration:none;}
.btn-back:hover{color:#fff;}
.avatar{width:32px;height:32px;border-radius:50%;background:#1890FF;display:flex;align-items:center;justify-content:center;color:#fff;font-size:var(--font-sm);cursor:pointer;}
/* 侧边栏 */
.sidebar{position:fixed;top:56px;left:0;bottom:0;width:240px;background:#001529;overflow-y:auto;z-index:90;padding-top:8px;}
.sidebar-menu__title{color:rgba(255,255,255,0.35);font-size:var(--font-xs);padding:16px 24px 8px;letter-spacing:.5px;}
.sidebar-item{display:flex;align-items:center;gap:8px;padding:10px 24px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);cursor:pointer;transition:all .15s;text-decoration:none;}
.sidebar-item:hover{color:#fff;background:rgba(255,255,255,0.06);}
.sidebar-item.active{color:#fff;background:var(--primary);}
/* 主内容区 */
.main{margin-left:240px;margin-top:56px;padding:24px;min-height:calc(100vh - 56px);}
/* 面包屑 */
.breadcrumb{display:flex;align-items:center;gap:8px;margin-bottom:16px;font-size:var(--font-sm);color:var(--text-secondary);}
.breadcrumb a{color:var(--primary);text-decoration:none;}.breadcrumb a:hover{color:#40a9ff;}
/* 员工信息卡片 */
.info-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:20px 24px;margin-bottom:16px;display:flex;align-items:center;gap:24px;}
.info-card__left{display:flex;align-items:center;gap:20px;flex:1;min-width:0;}
.info-card__avatar{width:52px;height:52px;border-radius:50%;background:var(--primary);color:#fff;display:flex;align-items:center;justify-content:center;font-size:20px;font-weight:600;flex-shrink:0;}
.info-card__detail{display:flex;flex-direction:column;gap:4px;}
.info-card__name{font-size:var(--font-lg);font-weight:600;color:var(--text-primary);}
.info-card__meta{display:flex;gap:20px;font-size:var(--font-sm);color:var(--text-secondary);flex-wrap:wrap;}
.info-card__right{flex-shrink:0;margin-left:auto;}
.info-card__date-filter{display:flex;align-items:center;gap:8px;}
.info-card__date-filter label{font-size:var(--font-xs);color:var(--text-secondary);white-space:nowrap;}
/* 指标卡片 */
.metrics-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:20px 24px;margin-bottom:16px;}
.metrics-card__title{font-size:var(--font-base);font-weight:600;color:var(--text-primary);margin-bottom:16px;}
.metrics-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;}
.metric-group{background:#FAFAFA;border-radius:var(--radius-sm);padding:14px 16px;text-align:center;}
.metric-group__label{font-size:var(--font-xs);color:var(--text-secondary);margin-bottom:8px;}
.metric-row{display:flex;justify-content:center;align-items:center;gap:0;font-size:var(--font-xs);color:var(--text-primary);}
.metric-row__item{flex:1;display:flex;flex-direction:column;align-items:center;gap:2px;}
.metric-row__val{font-size:var(--font-base);font-weight:600;color:var(--text-primary);}
.metric-row__sub{font-size:var(--font-xs);color:var(--text-placeholder);}
.metric-arrow{font-size:var(--font-sm);color:var(--text-placeholder);margin:0 4px;}
/* 变化值颜色 */
.change-down{color:var(--success);}
.change-up{color:var(--danger);}
.change-zero{color:var(--text-placeholder);}
/* Tab */
.tab-bar{display:flex;border-bottom:1px solid var(--border);margin-bottom:0;background:#fff;border-radius:var(--radius-md) var(--radius-md) 0 0;padding:0 24px;}
.tab-item{padding:12px 20px;font-size:var(--font-sm);cursor:pointer;color:var(--text-secondary);border-bottom:2px solid transparent;margin-bottom:-1px;transition:all .2s;font-weight:500;}
.tab-item:hover{color:var(--primary);}
.tab-item.active{color:var(--primary);border-bottom-color:var(--primary);font-weight:600;}
.tab-panel{display:none;}
.tab-panel.active{display:block;}
/* 表格 */
.table-card{background:#fff;border-radius:0 0 var(--radius-md) var(--radius-md);box-shadow:var(--shadow-sm);overflow:hidden;}
.table-card__content{overflow-x:auto;-webkit-overflow-scrolling:touch;}
table{width:100%;border-collapse:collapse;white-space:nowrap;}
thead th{background:#FAFAFA;padding:10px 12px;text-align:center;font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);}
tbody td{padding:12px 12px;text-align:center;font-size:var(--font-sm);color:var(--text-primary);border-bottom:1px solid var(--border);}
tbody tr:last-child td{border-bottom:none;}
tbody tr:hover{background:#F8FBFF;}
/* 标签 */
.tag{display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:var(--font-xs);}
.tag-blue{background:var(--primary-light);color:var(--primary);}
.tag-green{background:#F6FFED;color:var(--success);}
.tag-gray{background:#F5F5F5;color:#999;}
.tag-orange{background:#FFF7E6;color:#FA8C16;}
/* 分页 */
.pagination{display:flex;align-items:center;justify-content:flex-end;padding:16px 24px;gap:8px;border-top:1px solid var(--border);}
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;}
.page-btn:hover,.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
/* Toast */
.toast{position:fixed;top:80px;left:50%;transform:translateX(-50%);background:#333;color:#fff;padding:10px 24px;border-radius:var(--radius-sm);font-size:var(--font-sm);z-index:9999;opacity:0;transition:opacity .2s;pointer-events:none;}
.toast.show{opacity:1;}
/* 日期控件 */
.filter-date{height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 10px;font-size:var(--font-xs);outline:none;transition:border-color .2s;box-sizing:border-box;min-width:130px;color:var(--text-primary);}
.filter-date:focus{border-color:var(--primary);}
</style>
</head>
<body>
<!-- 顶部导航栏 -->
<div class="top-bar">
<div class="top-bar__logo"><svg viewBox="0 0 28 28" fill="none"><rect width="28" height="28" rx="6" fill="#1890FF"/><path d="M7 14h14M14 7v14" stroke="#fff" stroke-width="2.5" stroke-linecap="round"/></svg> 体重管理</div>
<nav class="top-bar__nav">
<a href="archive-personal-weight-data.html">档案</a>
<a href="plan-list.html">计划管理</a>
<a href="registration-tracking.html">报名管理</a>
<a href="action-record.html">过程管理</a>
<a href="history-plan-list.html" class="active">历史干预</a>
<a href="personal-target-data.html">个人体重管理</a>
<a href="scale-device.html">设备管理</a>
<a href="exception-system-dirty.html">异常事件</a>
</nav>
<div class="top-bar__right">
<a class="btn-back" href="../../index.html"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg> 返回首页</a>
<div class="avatar"></div>
<span style="color:rgba(255,255,255,0.65);">系统管理员 ▾</span>
</div>
</div>
<!-- 侧边栏 -->
<aside class="sidebar">
<div class="sidebar-menu__title">历史干预</div>
<a href="history-plan-list.html" class="sidebar-item">计划列表</a>
<a href="history-personnel-list.html" class="sidebar-item active">人员列表</a>
</aside>
<!-- 主内容 -->
<main class="main">
<!-- 返回 + 面包屑 -->
<div style="margin-bottom:12px;">
<a href="history-personnel-list.html" style="display:inline-flex;align-items:center;gap:6px;color:var(--primary);text-decoration:none;font-size:var(--font-sm);">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
返回列表
</a>
</div>
<div class="breadcrumb">
<a href="history-personnel-list.html">人员列表</a>
<span style="color:var(--text-placeholder);">/</span>
<span id="breadcrumbName">详细数据</span>
</div>
<!-- 员工信息卡片 -->
<div class="info-card">
<div class="info-card__left">
<div class="info-card__avatar" id="empAvatar"></div>
<div class="info-card__detail">
<div class="info-card__name" id="empName">--</div>
<div class="info-card__meta">
<span id="empCode">员工编号:--</span>
<span id="empGender">性别:--</span>
<span id="empAge">年龄:--</span>
<span id="empUnit">单位:--</span>
<span id="empDept">部门:--</span>
</div>
</div>
</div>
<div class="info-card__right">
<div class="info-card__date-filter">
<label>日期范围</label>
<input class="filter-date" type="date" id="filterDateFrom">
<span style="font-size:var(--font-xs);color:var(--text-placeholder);"></span>
<input class="filter-date" type="date" id="filterDateTo">
</div>
</div>
</div>
<!-- 指标汇总卡片 -->
<div class="metrics-card">
<div class="metrics-card__title">体重管理指标变化</div>
<div class="metrics-grid" id="metricsGrid"></div>
</div>
<!-- Tab + 列表 -->
<div class="table-card" style="margin-top:0;">
<div class="tab-bar">
<div class="tab-item active" onclick="switchTab(0)">饮食记录</div>
<div class="tab-item" onclick="switchTab(1)">运动记录</div>
<div class="tab-item" onclick="switchTab(2)">体重记录</div>
</div>
<!-- 饮食记录 -->
<div class="tab-panel active" id="tab-panel-0">
<div class="table-card__content">
<table>
<thead>
<tr><th>时间</th><th>餐次</th><th>摄入热量(千卡)</th><th>来源</th></tr>
</thead>
<tbody id="dietBody"></tbody>
</table>
</div>
<div class="pagination">
<span id="dietPageInfo">共 0 条</span>
<button class="page-btn" onclick="dietGoPage(-1)"></button>
<span id="dietPageNum">第 1 页</span>
<button class="page-btn" onclick="dietGoPage(1)"></button>
</div>
</div>
<!-- 运动记录 -->
<div class="tab-panel" id="tab-panel-1">
<div class="table-card__content">
<table>
<thead>
<tr><th>时间</th><th>运动类型</th><th>运动时长/数据</th><th>消耗热量(千卡)</th><th>来源</th></tr>
</thead>
<tbody id="sportBody"></tbody>
</table>
</div>
<div class="pagination">
<span id="sportPageInfo">共 0 条</span>
<button class="page-btn" onclick="sportGoPage(-1)"></button>
<span id="sportPageNum">第 1 页</span>
<button class="page-btn" onclick="sportGoPage(1)"></button>
</div>
</div>
<!-- 体重记录 -->
<div class="tab-panel" id="tab-panel-2">
<div class="table-card__content">
<table>
<thead>
<tr><th>时间</th><th>体重(kg)</th><th>BMI</th><th>体脂率(%)</th><th>腰围(cm)</th><th>来源</th></tr>
</thead>
<tbody id="weightBody"></tbody>
</table>
</div>
<div class="pagination">
<span id="weightPageInfo">共 0 条</span>
<button class="page-btn" onclick="weightGoPage(-1)"></button>
<span id="weightPageNum">第 1 页</span>
<button class="page-btn" onclick="weightGoPage(1)"></button>
</div>
</div>
</div>
</main>
<!-- Toast -->
<div class="toast" id="toast"></div>
<script>
/* ===== 侧边栏高亮 ===== */
(function(){
var current = location.pathname.split('/').pop();
document.querySelectorAll('.sidebar-item').forEach(function(item){
var href = item.getAttribute('href');
item.classList.toggle('active', href === current);
});
})();
/* ===== Mock 人员数据(与列表页共享) ===== */
var personnelData = [
{name:'张建国',empId:'CQ100235',gender:'男',age:42,unit:'第四采油厂',dept:'健康管理部',weightInit:86.0,weightFinal:81.8,weightChange:-4.2,bmiInit:29.5,bmiFinal:28.1,bmiChange:-1.4,fatInit:28.8,fatFinal:25.6,fatChange:-3.2,waistInit:99.0,waistFinal:93.9,waistChange:-5.1,dietCount:98,sportCount:72,weightCount:45},
{name:'李明辉',empId:'CQ100458',gender:'男',age:38,unit:'第四采油厂',dept:'安全环保科',weightInit:82.5,weightFinal:79.0,weightChange:-3.5,bmiInit:28.0,bmiFinal:26.9,bmiChange:-1.1,fatInit:26.5,fatFinal:23.7,fatChange:-2.8,waistInit:95.0,waistFinal:90.7,waistChange:-4.3,dietCount:85,sportCount:64,weightCount:38},
{name:'王秀兰',empId:'CQ100672',gender:'女',age:35,unit:'第四采油厂',dept:'工会办公室',weightInit:68.0,weightFinal:65.7,weightChange:-2.3,bmiInit:25.8,bmiFinal:25.0,bmiChange:-0.8,fatInit:33.0,fatFinal:31.1,fatChange:-1.9,waistInit:83.0,waistFinal:79.8,waistChange:-3.2,dietCount:72,sportCount:55,weightCount:32},
{name:'赵铁柱',empId:'CQ100891',gender:'男',age:45,unit:'第四采油厂',dept:'生产技术部',weightInit:93.0,weightFinal:87.9,weightChange:-5.1,bmiInit:32.0,bmiFinal:30.3,bmiChange:-1.7,fatInit:32.5,fatFinal:28.4,fatChange:-4.1,waistInit:106.0,waistFinal:99.5,waistChange:-6.5,dietCount:105,sportCount:80,weightCount:50},
{name:'陈小燕',empId:'CQ101023',gender:'女',age:29,unit:'第四采油厂',dept:'财务部',weightInit:62.5,weightFinal:60.7,weightChange:-1.8,bmiInit:23.8,bmiFinal:23.2,bmiChange:-0.6,fatInit:30.5,fatFinal:29.1,fatChange:-1.4,waistInit:78.5,waistFinal:76.0,waistChange:-2.5,dietCount:65,sportCount:48,weightCount:28},
{name:'刘大军',empId:'CQ101145',gender:'男',age:50,unit:'第四采油厂',dept:'信息中心',weightInit:89.0,weightFinal:86.0,weightChange:-3.0,bmiInit:30.5,bmiFinal:29.5,bmiChange:-1.0,fatInit:31.0,fatFinal:28.5,fatChange:-2.5,waistInit:101.0,waistFinal:97.2,waistChange:-3.8,dietCount:78,sportCount:42,weightCount:35},
{name:'周红梅',empId:'CQ101267',gender:'女',age:40,unit:'第四采油厂',dept:'健康管理部',weightInit:72.5,weightFinal:69.9,weightChange:-2.6,bmiInit:27.3,bmiFinal:26.4,bmiChange:-0.9,fatInit:34.5,fatFinal:32.4,fatChange:-2.1,waistInit:86.5,waistFinal:83.0,waistChange:-3.5,dietCount:82,sportCount:60,weightCount:40},
{name:'吴国强',empId:'CQ101389',gender:'男',age:33,unit:'第四采油厂',dept:'安全环保科',weightInit:78.0,weightFinal:78.8,weightChange:+0.8,bmiInit:26.5,bmiFinal:26.8,bmiChange:+0.3,fatInit:24.8,fatFinal:25.4,fatChange:+0.6,waistInit:89.5,waistFinal:90.7,waistChange:+1.2,dietCount:30,sportCount:18,weightCount:12}
];
/* ===== Mock 记录数据 ===== */
/* 饮食记录 */
var dietRecords = [
{time:'2026-07-01 07:30',meal:'早餐',calories:356,source:'智记'},
{time:'2026-07-01 12:15',meal:'午餐',calories:520,source:'自记'},
{time:'2026-07-01 18:45',meal:'晚餐',calories:410,source:'智记'},
{time:'2026-06-30 08:00',meal:'早餐',calories:345,source:'智记'},
{time:'2026-06-30 12:00',meal:'午餐',calories:580,source:'自记'},
{time:'2026-06-30 19:00',meal:'晚餐',calories:395,source:'智记'},
{time:'2026-06-29 07:45',meal:'早餐',calories:320,source:'自记'},
{time:'2026-06-29 12:30',meal:'午餐',calories:510,source:'智记'},
{time:'2026-06-29 15:30',meal:'加餐',calories:185,source:'智记'},
{time:'2026-06-29 18:30',meal:'晚餐',calories:440,source:'自记'},
{time:'2026-06-28 08:10',meal:'早餐',calories:360,source:'自记'},
{time:'2026-06-28 12:20',meal:'午餐',calories:495,source:'智记'},
{time:'2026-06-28 19:15',meal:'晚餐',calories:420,source:'智记'},
{time:'2026-06-27 07:30',meal:'早餐',calories:338,source:'智记'},
{time:'2026-06-27 12:00',meal:'午餐',calories:550,source:'自记'},
{time:'2026-06-27 18:00',meal:'晚餐',calories:385,source:'自记'},
{time:'2026-06-26 08:00',meal:'早餐',calories:350,source:'智记'},
{time:'2026-06-26 12:30',meal:'午餐',calories:505,source:'智记'},
{time:'2026-06-26 16:00',meal:'加餐',calories:150,source:'自记'},
{time:'2026-06-26 19:00',meal:'晚餐',calories:430,source:'智记'}
];
/* 运动记录 */
var sportRecords = [
{time:'2026-07-01 06:30',type:'跑步',data:'45min',calories:420,source:'穿戴'},
{time:'2026-07-01 08:00',type:'步行',data:'12,500步',calories:320,source:'微信'},
{time:'2026-06-30 12:00',type:'器械推胸',data:'60min',calories:380,source:'自记'},
{time:'2026-06-29 18:00',type:'游泳',data:'40min',calories:350,source:'器械'},
{time:'2026-06-28 08:00',type:'瑜伽',data:'50min',calories:180,source:'自记'},
{time:'2026-06-28 18:30',type:'步行',data:'8,200步',calories:210,source:'微信'},
{time:'2026-06-27 16:00',type:'骑行',data:'90min',calories:560,source:'穿戴'},
{time:'2026-06-26 10:00',type:'深蹲',data:'55min',calories:410,source:'器械'},
{time:'2026-06-25 07:00',type:'跑步',data:'30min',calories:280,source:'穿戴'},
{time:'2026-06-25 17:30',type:'步行',data:'10,200步',calories:260,source:'微信'},
{time:'2026-06-24 11:00',type:'哑铃弯举',data:'40min',calories:310,source:'自记'},
{time:'2026-06-23 08:30',type:'跳绳',data:'25min',calories:350,source:'穿戴'},
{time:'2026-06-22 19:00',type:'游泳',data:'60min',calories:480,source:'器械'},
{time:'2026-06-21 06:00',type:'跑步',data:'50min',calories:460,source:'穿戴'},
{time:'2026-06-20 12:30',type:'步行',data:'9,800步',calories:250,source:'微信'}
];
/* 体重记录 */
var weightRecords = [
{time:'2026-07-01 08:30',weight:81.8,bmi:28.1,fatRate:25.6,waist:93.9,source:'身高秤'},
{time:'2026-06-28 07:45',weight:82.1,bmi:28.2,fatRate:25.8,waist:94.2,source:'体脂仪'},
{time:'2026-06-25 18:20',weight:82.5,bmi:28.4,fatRate:26.1,waist:94.8,source:'蓝牙称'},
{time:'2026-06-22 08:10',weight:82.9,bmi:28.5,fatRate:26.3,waist:95.1,source:'身高秤'},
{time:'2026-06-19 20:00',weight:83.2,bmi:28.6,fatRate:26.6,waist:95.5,source:'自记'},
{time:'2026-06-16 09:00',weight:83.7,bmi:28.8,fatRate:26.9,waist:96.0,source:'体脂仪'},
{time:'2026-06-13 07:30',weight:84.1,bmi:28.9,fatRate:27.2,waist:96.4,source:'蓝牙称'},
{time:'2026-06-10 18:00',weight:84.5,bmi:29.1,fatRate:27.5,waist:96.7,source:'身高秤'},
{time:'2026-06-07 08:45',weight:84.9,bmi:29.2,fatRate:27.8,waist:97.2,source:'体脂仪'},
{time:'2026-06-04 19:30',weight:85.2,bmi:29.3,fatRate:28.1,waist:97.6,source:'自记'},
{time:'2026-06-01 08:00',weight:85.6,bmi:29.4,fatRate:28.4,waist:98.2,source:'蓝牙称'},
{time:'2026-05-28 07:15',weight:85.9,bmi:29.5,fatRate:28.7,waist:98.7,source:'身高秤'}
];
var pageSize = 10;
var dietPage = 0, sportPage = 0, weightPage = 0;
/* ===== Tab 切换 ===== */
function switchTab(idx){
document.querySelectorAll('.tab-item').forEach(function(el,i){el.classList.toggle('active',i===idx);});
document.querySelectorAll('.tab-panel').forEach(function(el,i){el.classList.toggle('active',i===idx);});
}
/* ===== 指标变化渲染 ===== */
function renderMetrics(emp){
var metrics = [
{label:'体重(kg)',init:emp.weightInit,final:emp.weightFinal,change:emp.weightChange},
{label:'BMI',init:emp.bmiInit,final:emp.bmiFinal,change:emp.bmiChange,decimals:1},
{label:'体脂(%)',init:emp.fatInit,final:emp.fatFinal,change:emp.fatChange},
{label:'腰围(cm)',init:emp.waistInit,final:emp.waistFinal,change:emp.waistChange}
];
var html = '';
metrics.forEach(function(m){
var cls = m.change < 0 ? 'change-down' : (m.change > 0 ? 'change-up' : 'change-zero');
var sign = m.change > 0 ? '+' : '';
html += '<div class="metric-group">';
html += '<div class="metric-group__label">'+m.label+'</div>';
html += '<div class="metric-row">';
html += '<div class="metric-row__item"><span class="metric-row__sub">初始</span><span class="metric-row__val">'+m.init.toFixed(1)+'</span></div>';
html += '<span class="metric-arrow">→</span>';
html += '<div class="metric-row__item"><span class="metric-row__sub">最终</span><span class="metric-row__val">'+m.final.toFixed(1)+'</span></div>';
html += '<span class="metric-arrow" style="margin-left:8px;"></span>';
html += '<div class="metric-row__item"><span class="metric-row__sub">变化</span><span class="metric-row__val '+cls+'">'+sign+m.change.toFixed(1)+'</span></div>';
html += '</div></div>';
});
document.getElementById('metricsGrid').innerHTML = html;
}
/* ===== 饮食记录渲染 ===== */
function renderDiet(){
var tbody = document.getElementById('dietBody');
var start = dietPage * pageSize;
var pageData = dietRecords.slice(start, start + pageSize);
var totalPages = Math.ceil(dietRecords.length / pageSize) || 1;
document.getElementById('dietPageInfo').textContent = '共 ' + dietRecords.length + ' 条';
document.getElementById('dietPageNum').textContent = '第 ' + (dietPage + 1) + '/' + totalPages + ' 页';
var srcTag = {智记:'tag-green',自记:'tag-gray'};
var html = '';
pageData.forEach(function(d){
html += '<tr>';
html += '<td>'+d.time+'</td>';
html += '<td>'+d.meal+'</td>';
html += '<td>'+d.calories+'</td>';
html += '<td><span class="tag '+ (srcTag[d.source]||'tag-gray') +'">'+d.source+'</span></td>';
html += '</tr>';
});
tbody.innerHTML = html || '<tr><td colspan="4" style="text-align:center;padding:48px 0;color:#999;">暂无饮食记录</td></tr>';
}
function dietGoPage(delta){
var totalPages = Math.ceil(dietRecords.length / pageSize);
var np = dietPage + delta;
if(np < 0 || np >= totalPages) return;
dietPage = np;
renderDiet();
}
/* ===== 运动记录渲染 ===== */
function renderSport(){
var tbody = document.getElementById('sportBody');
var start = sportPage * pageSize;
var pageData = sportRecords.slice(start, start + pageSize);
var totalPages = Math.ceil(sportRecords.length / pageSize) || 1;
document.getElementById('sportPageInfo').textContent = '共 ' + sportRecords.length + ' 条';
document.getElementById('sportPageNum').textContent = '第 ' + (sportPage + 1) + '/' + totalPages + ' 页';
var srcTag = {穿戴:'tag-blue',微信:'tag-green',自记:'tag-gray',器械:'tag-orange'};
var html = '';
pageData.forEach(function(d){
html += '<tr>';
html += '<td>'+d.time+'</td>';
html += '<td>'+d.type+'</td>';
html += '<td>'+d.data+'</td>';
html += '<td>'+d.calories+'</td>';
html += '<td><span class="tag '+ (srcTag[d.source]||'tag-gray') +'">'+d.source+'</span></td>';
html += '</tr>';
});
tbody.innerHTML = html || '<tr><td colspan="5" style="text-align:center;padding:48px 0;color:#999;">暂无运动记录</td></tr>';
}
function sportGoPage(delta){
var totalPages = Math.ceil(sportRecords.length / pageSize);
var np = sportPage + delta;
if(np < 0 || np >= totalPages) return;
sportPage = np;
renderSport();
}
/* ===== 体重记录渲染 ===== */
function renderWeight(){
var tbody = document.getElementById('weightBody');
var start = weightPage * pageSize;
var pageData = weightRecords.slice(start, start + pageSize);
var totalPages = Math.ceil(weightRecords.length / pageSize) || 1;
document.getElementById('weightPageInfo').textContent = '共 ' + weightRecords.length + ' 条';
document.getElementById('weightPageNum').textContent = '第 ' + (weightPage + 1) + '/' + totalPages + ' 页';
var srcTag = {身高秤:'tag-blue',体脂仪:'tag-orange',蓝牙称:'tag-green',自记:'tag-gray'};
var html = '';
pageData.forEach(function(d){
html += '<tr>';
html += '<td>'+d.time+'</td>';
html += '<td>'+d.weight.toFixed(1)+'</td>';
html += '<td>'+d.bmi.toFixed(1)+'</td>';
html += '<td>'+d.fatRate.toFixed(1)+'</td>';
html += '<td>'+d.waist.toFixed(1)+'</td>';
html += '<td><span class="tag '+ (srcTag[d.source]||'tag-gray') +'">'+d.source+'</span></td>';
html += '</tr>';
});
tbody.innerHTML = html || '<tr><td colspan="6" style="text-align:center;padding:48px 0;color:#999;">暂无体重记录</td></tr>';
}
function weightGoPage(delta){
var totalPages = Math.ceil(weightRecords.length / pageSize);
var np = weightPage + delta;
if(np < 0 || np >= totalPages) return;
weightPage = np;
renderWeight();
}
/* ===== 初始化 ===== */
(function init(){
var params = new URLSearchParams(location.search);
var empId = params.get('id') || 'CQ100235';
var dateFrom = params.get('dateFrom') || '';
var dateTo = params.get('dateTo') || '';
var emp = personnelData.find(function(p){return p.empId === empId;}) || personnelData[0];
// 日期筛选默认值
document.getElementById('filterDateFrom').value = dateFrom;
document.getElementById('filterDateTo').value = dateTo;
// 面包屑
document.getElementById('breadcrumbName').textContent = emp.name;
// 员工信息
document.getElementById('empAvatar').textContent = emp.name.charAt(0);
document.getElementById('empName').textContent = emp.name;
document.getElementById('empCode').textContent = '员工编号:'+emp.empId;
document.getElementById('empGender').textContent = '性别:'+emp.gender;
document.getElementById('empAge').textContent = '年龄:'+emp.age;
document.getElementById('empUnit').textContent = '单位:'+emp.unit;
document.getElementById('empDept').textContent = '部门:'+emp.dept;
// 指标
renderMetrics(emp);
// 三个tab表格
renderDiet();
renderSport();
renderWeight();
})();
</script>
</body>
</html>
@@ -0,0 +1,486 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>人员列表 | 历史干预 | 体重管理</title>
<style>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;min-width:1280px;}
:root{
--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;
--text-primary:#333;--text-secondary:#666;--text-placeholder:#999;--border:#E8E8E8;--background:#F5F7FA;
--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;
--radius-sm:4px;--radius-md:8px;--radius-lg:12px;
--shadow-sm:0 1px 4px rgba(0,0,0,0.08);--shadow-md:0 4px 12px rgba(0,0,0,0.10);
}
/* 顶部导航栏 */
.top-bar{display:flex;align-items:center;height:56px;background:#001529;padding:0 24px;position:fixed;top:0;left:0;right:0;z-index:100;}
.top-bar__logo{display:flex;align-items:center;gap:8px;color:#fff;font-size:var(--font-lg);font-weight:600;white-space:nowrap;width:240px;flex-shrink:0;}
.top-bar__logo svg{width:28px;height:28px;}
.top-bar__nav{display:flex;align-items:center;gap:4px;flex:1;}
.top-bar__nav a{color:rgba(255,255,255,0.65);text-decoration:none;padding:6px 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);transition:all .2s;}
.top-bar__nav a:hover{color:#fff;background:rgba(255,255,255,0.08);}
.top-bar__nav a.active{color:#fff;background:var(--primary);}
.top-bar__right{display:flex;align-items:center;gap:16px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);}
.btn-back{color:rgba(255,255,255,0.65);cursor:pointer;display:flex;align-items:center;gap:4px;text-decoration:none;}
.btn-back:hover{color:#fff;}
.avatar{width:32px;height:32px;border-radius:50%;background:#1890FF;display:flex;align-items:center;justify-content:center;color:#fff;font-size:var(--font-sm);cursor:pointer;}
/* 侧边栏 */
.sidebar{position:fixed;top:56px;left:0;bottom:0;width:240px;background:#001529;overflow-y:auto;z-index:90;padding-top:8px;}
.sidebar-menu__title{color:rgba(255,255,255,0.35);font-size:var(--font-xs);padding:16px 24px 8px;letter-spacing:.5px;}
.sidebar-item{display:flex;align-items:center;gap:8px;padding:10px 24px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);cursor:pointer;transition:all .15s;text-decoration:none;}
.sidebar-item:hover{color:#fff;background:rgba(255,255,255,0.06);}
.sidebar-item.active{color:#fff;background:var(--primary);}
/* 主内容区 */
.main{margin-left:240px;margin-top:56px;padding:24px;min-height:calc(100vh - 56px);}
/* 页面标题 */
.page-header{margin-bottom:16px;}
.page-header__breadcrumb{font-size:var(--font-sm);color:var(--text-placeholder);}
.page-header__breadcrumb span{color:var(--text-primary);}
/* 筛选栏 */
.filter-bar{background:#fff;padding:16px 24px;display:flex;align-items:center;gap:16px;flex-wrap:wrap;border-radius:var(--radius-md) var(--radius-md) 0 0;box-shadow:var(--shadow-sm);}
.filter-item{display:flex;align-items:center;gap:8px;}
.filter-item label{font-size:var(--font-xs);color:var(--text-secondary);white-space:nowrap;}
.filter-select{height:32px;min-width:140px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 10px;font-size:var(--font-xs);color:var(--text-primary);background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 8px center;cursor:pointer;outline:none;appearance:none;-webkit-appearance:none;}
/* 筛选输入框 */
.filter-input{height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 10px;font-size:var(--font-xs);color:var(--text-primary);outline:none;transition:border-color .2s;box-sizing:border-box;min-width:110px;}
.filter-input:focus{border-color:var(--primary);}
/* 日期筛选 */
.filter-date{height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 10px;font-size:var(--font-xs);outline:none;transition:border-color .2s;box-sizing:border-box;min-width:130px;color:var(--text-primary);}
.filter-date:focus{border-color:var(--primary);}
/* 按钮 */
.btn{height:32px;padding:0 16px;border-radius:var(--radius-sm);font-size:var(--font-xs);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;white-space:nowrap;}
.btn-primary{background:var(--primary);color:#fff;}.btn-primary:hover{background:#40a9ff;}
.btn-default{background:#fff;color:var(--text-primary);border:1px solid var(--border);}.btn-default:hover{color:var(--primary);border-color:var(--primary);}
.btn-export{background:#fff;color:var(--text-primary);border:1px solid var(--border);}.btn-export:hover{color:var(--primary);border-color:var(--primary);}
/* 操作栏 */
.action-bar{display:flex;align-items:center;gap:8px;padding:16px 24px;background:#fff;border-top:1px solid var(--border);}
/* 表格卡片 */
.table-card{background:#fff;border-radius:0 0 var(--radius-md) var(--radius-md);box-shadow:var(--shadow-sm);overflow:hidden;}
.table-card__content{overflow-x:auto;-webkit-overflow-scrolling:touch;}
table{width:100%;border-collapse:separate;border-spacing:0;min-width:2200px;}
/* 表头 */
thead th{background:#FAFAFA;padding:8px 7px;text-align:center;font-size:var(--font-xs);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);white-space:nowrap;}
/* 表体 */
tbody td{padding:10px 7px;text-align:center;font-size:var(--font-sm);color:var(--text-primary);border-bottom:1px solid #F0F0F0;white-space:nowrap;}
tbody tr:last-child td{border-bottom:none;}
tbody tr:hover{background:#F8FBFF;}
/* 第一列(姓名)固定左侧 — 仅第一行表头(避免rowspan第二行误匹配) */
thead tr:first-child th:nth-child(1),tbody td:nth-child(1){position:sticky;left:0;z-index:5;background:#fff;min-width:80px;max-width:80px;box-shadow:2px 0 6px rgba(0,0,0,0.08);}
thead tr:first-child th:nth-child(1){z-index:8;background:#FAFAFA;}
tbody tr:hover td:nth-child(1){background:#F8FBFF;}
/* 最后一列(详细数据)固定右侧 — 仅第一行表头(避免rowspan第二行误匹配到"变化"列) */
thead tr:first-child th:last-child,tbody td:last-child{position:sticky;right:0;z-index:5;background:#fff;min-width:80px;max-width:80px;box-shadow:-2px 0 6px rgba(0,0,0,0.08);}
thead tr:first-child th:last-child{z-index:8;background:#FAFAFA;}
tbody tr:hover td:last-child{background:#F8FBFF;}
.td-empty{text-align:center;padding:48px 0;color:var(--text-placeholder);font-size:var(--font-sm);}
/* 详细数据链接 */
.link{color:var(--primary);cursor:pointer;font-size:var(--font-sm);text-decoration:none;}.link:hover{color:#40a9ff;}
/* 变化值颜色 */
.change-down{color:var(--success);}
.change-up{color:var(--danger);}
.change-zero{color:var(--text-placeholder);}
/* 分页 */
.pagination{display:flex;align-items:center;justify-content:flex-end;padding:16px 24px;gap:8px;border-top:1px solid var(--border);}
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;}
.page-btn:hover,.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
/* Toast */
.toast{position:fixed;top:80px;left:50%;transform:translateX(-50%);background:#333;color:#fff;padding:10px 24px;border-radius:var(--radius-sm);font-size:var(--font-sm);z-index:9999;opacity:0;transition:opacity .2s;pointer-events:none;}
.toast.show{opacity:1;}
/* 单位部门级联面板 */
.org-wrap{position:relative;display:inline-block;}
.org-trigger{height:32px;min-width:160px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 10px;font-size:var(--font-xs);color:var(--text-primary);background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 8px center;cursor:pointer;display:flex;align-items:center;user-select:none;white-space:nowrap;}
.org-trigger.open,.org-trigger:hover{border-color:var(--primary);}
.org-panel{display:none;position:absolute;top:36px;left:0;z-index:310;background:#fff;border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:var(--shadow-md);width:380px;}
.org-panel.open{display:flex;}
.org-col{flex:1;overflow-y:auto;max-height:200px;border-right:1px solid var(--border);}
.org-col:last-child{border-right:none;}
.org-col__title{padding:6px 12px;font-size:var(--font-xs);color:var(--text-placeholder);background:#FAFAFA;border-bottom:1px solid var(--border);font-weight:500;}
.org-item{padding:8px 12px;font-size:var(--font-sm);color:var(--text-primary);cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:4px;}
.org-item:hover{background:#F0F8FF;color:var(--primary);}
.org-item.active{background:var(--primary-light);color:var(--primary);font-weight:500;}
</style>
</head>
<body>
<!-- 顶部导航栏 -->
<div class="top-bar">
<div class="top-bar__logo"><svg viewBox="0 0 28 28" fill="none"><rect width="28" height="28" rx="6" fill="#1890FF"/><path d="M7 14h14M14 7v14" stroke="#fff" stroke-width="2.5" stroke-linecap="round"/></svg> 体重管理</div>
<nav class="top-bar__nav">
<a href="archive-personal-weight-data.html">档案</a>
<a href="plan-list.html">计划管理</a>
<a href="registration-tracking.html">报名管理</a>
<a href="action-record.html">过程管理</a>
<a href="history-plan-list.html" class="active">历史干预</a>
<a href="personal-target-data.html">个人体重管理</a>
<a href="scale-device.html">设备管理</a>
<a href="exception-system-dirty.html">异常事件</a>
</nav>
<div class="top-bar__right">
<a class="btn-back" href="../../index.html"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg> 返回首页</a>
<div class="avatar"></div>
<span style="color:rgba(255,255,255,0.65);">系统管理员 ▾</span>
</div>
</div>
<!-- 侧边栏 -->
<aside class="sidebar">
<div class="sidebar-menu__title">历史干预</div>
<a href="history-plan-list.html" class="sidebar-item">计划列表</a>
<a href="history-personnel-list.html" class="sidebar-item active">人员列表</a>
</aside>
<!-- 主内容 -->
<main class="main">
<!-- 页面标题 -->
<div class="page-header">
<div class="page-header__breadcrumb">体重管理 / 历史干预 / <span>人员列表</span></div>
</div>
<!-- [交互] 筛选栏 — 姓名 + 员工编号 + 单位部门 + 日期范围 -->
<div class="filter-bar">
<div class="filter-item">
<label>姓名</label>
<input class="filter-input" id="filterName" placeholder="请输入姓名" style="width:110px;">
</div>
<div class="filter-item">
<label>员工编号</label>
<input class="filter-input" id="filterEmpId" placeholder="请输入编号" style="width:120px;">
</div>
<div class="filter-item">
<label>单位部门</label>
<div class="org-wrap" id="orgWrap">
<div class="org-trigger" id="orgTrigger" onclick="toggleOrg()">全部单位/部门</div>
<div class="org-panel" id="orgPanel">
<div class="org-col" id="unitCol">
<div class="org-col__title">单位</div>
<div class="org-item active" data-unit="" onclick="selectUnit(this,'全部单位/部门','')">全部单位/部门</div>
<div class="org-item" data-unit="第四采油厂" onclick="selectUnit(this,'第四采油厂','第四采油厂')">第四采油厂</div>
<div class="org-item" data-unit="采油一厂" onclick="selectUnit(this,'采油一厂','采油一厂')">采油一厂</div>
<div class="org-item" data-unit="采油二厂" onclick="selectUnit(this,'采油二厂','采油二厂')">采油二厂</div>
<div class="org-item" data-unit="采气一厂" onclick="selectUnit(this,'采气一厂','采气一厂')">采气一厂</div>
</div>
<div class="org-col" id="deptCol">
<div class="org-col__title">部门</div>
<div class="org-item active" data-dept="" onclick="selectDept(this,'全部部门','')">全部部门</div>
</div>
</div>
</div>
</div>
<div class="filter-item">
<label>日期范围</label>
<input class="filter-date" type="date" id="filterDateFrom">
<span style="font-size:var(--font-xs);color:var(--text-placeholder);"></span>
<input class="filter-date" type="date" id="filterDateTo">
</div>
<!-- [交互] 点击查询按钮筛选列表 -->
<button class="btn btn-primary" onclick="applyFilter()">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4.5" stroke="#fff" stroke-width="1.3"/><path d="M9.5 9.5L13 13" stroke="#fff" stroke-width="1.3" stroke-linecap="round"/></svg>查询
</button>
<button class="btn btn-default" onclick="resetFilter()">重置</button>
</div>
<!-- [交互] 操作按钮区 -->
<div class="action-bar">
<button class="btn btn-export" onclick="showToast('导出列表数据功能开发中')">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 10v2h10v-2M7 2v7M4.5 6.5L7 9l2.5-2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>导出列表数据
</button>
<button class="btn btn-default" onclick="showToast('导出任务列表开发中')">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><rect x="2" y="2" width="10" height="10" rx="1.5" stroke="currentColor" stroke-width="1.4"/><path d="M4 5h6M4 7.5h4" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>查看导出任务
</button>
</div>
<!-- 数据表格 -->
<div class="table-card">
<div class="table-card__content">
<table>
<thead>
<tr>
<th rowspan="2">姓名</th>
<th rowspan="2">员工编号</th>
<th rowspan="2">性别</th>
<th rowspan="2">年龄</th>
<th rowspan="2">单位</th>
<th rowspan="2">部门</th>
<th colspan="3">体重(kg)</th>
<th colspan="3">BMI</th>
<th colspan="3">体脂(%)</th>
<th colspan="3">腰围(cm)</th>
<th rowspan="2">饮食记录<br>次数</th>
<th rowspan="2">运动记录<br>次数</th>
<th rowspan="2">体重记录<br>次数</th>
<th rowspan="2">详细数据</th>
</tr>
<tr>
<th>初始</th><th>最终</th><th>变化</th>
<th>初始</th><th>最终</th><th>变化</th>
<th>初始</th><th>最终</th><th>变化</th>
<th>初始</th><th>最终</th><th>变化</th>
</tr>
</thead>
<tbody id="tableBody"></tbody>
</table>
</div>
<div class="pagination">
<span id="pageInfo">显示 0 条记录</span>
<button class="page-btn" onclick="goPage(-1)"></button>
<span id="pageNum" style="font-size:var(--font-sm);color:var(--text-secondary);">第 1 页</span>
<button class="page-btn" onclick="goPage(1)"></button>
</div>
</div>
</main>
<!-- Toast -->
<div class="toast" id="toast"></div>
<script>
/* ===== 侧边栏当前页高亮 ===== */
(function(){
var current = location.pathname.split('/').pop();
document.querySelectorAll('.sidebar-item').forEach(function(item){
var href = item.getAttribute('href');
item.classList.toggle('active', href === current);
});
})();
/* ===== Mock 数据:人员列表 ===== */
var personnelData = [
{name:'张建国',empId:'CQ100235',gender:'男',age:42,unit:'第四采油厂',dept:'健康管理部',weightInit:86.0,weightFinal:81.8,weightChange:-4.2,bmiInit:29.5,bmiFinal:28.1,bmiChange:-1.4,fatInit:28.8,fatFinal:25.6,fatChange:-3.2,waistInit:99.0,waistFinal:93.9,waistChange:-5.1,dietCount:98,sportCount:72,weightCount:45},
{name:'李明辉',empId:'CQ100458',gender:'男',age:38,unit:'第四采油厂',dept:'安全环保科',weightInit:82.5,weightFinal:79.0,weightChange:-3.5,bmiInit:28.0,bmiFinal:26.9,bmiChange:-1.1,fatInit:26.5,fatFinal:23.7,fatChange:-2.8,waistInit:95.0,waistFinal:90.7,waistChange:-4.3,dietCount:85,sportCount:64,weightCount:38},
{name:'王秀兰',empId:'CQ100672',gender:'女',age:35,unit:'第四采油厂',dept:'工会办公室',weightInit:68.0,weightFinal:65.7,weightChange:-2.3,bmiInit:25.8,bmiFinal:25.0,bmiChange:-0.8,fatInit:33.0,fatFinal:31.1,fatChange:-1.9,waistInit:83.0,waistFinal:79.8,waistChange:-3.2,dietCount:72,sportCount:55,weightCount:32},
{name:'赵铁柱',empId:'CQ100891',gender:'男',age:45,unit:'第四采油厂',dept:'生产技术部',weightInit:93.0,weightFinal:87.9,weightChange:-5.1,bmiInit:32.0,bmiFinal:30.3,bmiChange:-1.7,fatInit:32.5,fatFinal:28.4,fatChange:-4.1,waistInit:106.0,waistFinal:99.5,waistChange:-6.5,dietCount:105,sportCount:80,weightCount:50},
{name:'陈小燕',empId:'CQ101023',gender:'女',age:29,unit:'第四采油厂',dept:'财务部',weightInit:62.5,weightFinal:60.7,weightChange:-1.8,bmiInit:23.8,bmiFinal:23.2,bmiChange:-0.6,fatInit:30.5,fatFinal:29.1,fatChange:-1.4,waistInit:78.5,waistFinal:76.0,waistChange:-2.5,dietCount:65,sportCount:48,weightCount:28},
{name:'刘大军',empId:'CQ101145',gender:'男',age:50,unit:'第四采油厂',dept:'信息中心',weightInit:89.0,weightFinal:86.0,weightChange:-3.0,bmiInit:30.5,bmiFinal:29.5,bmiChange:-1.0,fatInit:31.0,fatFinal:28.5,fatChange:-2.5,waistInit:101.0,waistFinal:97.2,waistChange:-3.8,dietCount:78,sportCount:42,weightCount:35},
{name:'周红梅',empId:'CQ101267',gender:'女',age:40,unit:'第四采油厂',dept:'健康管理部',weightInit:72.5,weightFinal:69.9,weightChange:-2.6,bmiInit:27.3,bmiFinal:26.4,bmiChange:-0.9,fatInit:34.5,fatFinal:32.4,fatChange:-2.1,waistInit:86.5,waistFinal:83.0,waistChange:-3.5,dietCount:82,sportCount:60,weightCount:40},
{name:'吴国强',empId:'CQ101389',gender:'男',age:33,unit:'第四采油厂',dept:'安全环保科',weightInit:78.0,weightFinal:78.8,weightChange:+0.8,bmiInit:26.5,bmiFinal:26.8,bmiChange:+0.3,fatInit:24.8,fatFinal:25.4,fatChange:+0.6,waistInit:89.5,waistFinal:90.7,waistChange:+1.2,dietCount:30,sportCount:18,weightCount:12},
{name:'郑晓明',empId:'CQ101501',gender:'男',age:36,unit:'采油一厂',dept:'安全环保科',weightInit:84.0,weightFinal:80.2,weightChange:-3.8,bmiInit:28.8,bmiFinal:27.5,bmiChange:-1.3,fatInit:27.5,fatFinal:24.5,fatChange:-3.0,waistInit:96.5,waistFinal:91.9,waistChange:-4.6,dietCount:90,sportCount:68,weightCount:42},
{name:'黄丽华',empId:'CQ101623',gender:'女',age:31,unit:'采油一厂',dept:'健康管理部',weightInit:65.0,weightFinal:62.9,weightChange:-2.1,bmiInit:24.8,bmiFinal:24.1,bmiChange:-0.7,fatInit:31.5,fatFinal:29.9,fatChange:-1.6,waistInit:80.5,waistFinal:77.7,waistChange:-2.8,dietCount:68,sportCount:52,weightCount:30},
{name:'杨志强',empId:'CQ101745',gender:'男',age:44,unit:'采油一厂',dept:'生产技术部',weightInit:91.5,weightFinal:87.0,weightChange:-4.5,bmiInit:31.2,bmiFinal:29.7,bmiChange:-1.5,fatInit:31.5,fatFinal:28.0,fatChange:-3.5,waistInit:104.5,waistFinal:98.7,waistChange:-5.8,dietCount:102,sportCount:76,weightCount:48},
{name:'孙美玲',empId:'CQ101867',gender:'女',age:27,unit:'采油一厂',dept:'工会办公室',weightInit:59.0,weightFinal:57.5,weightChange:-1.5,bmiInit:22.5,bmiFinal:22.0,bmiChange:-0.5,fatInit:29.0,fatFinal:27.9,fatChange:-1.1,waistInit:76.0,waistFinal:74.0,waistChange:-2.0,dietCount:55,sportCount:40,weightCount:22},
{name:'林海峰',empId:'CQ101989',gender:'男',age:48,unit:'采油一厂',dept:'安全环保科',weightInit:87.0,weightFinal:84.2,weightChange:-2.8,bmiInit:29.8,bmiFinal:28.9,bmiChange:-0.9,fatInit:30.0,fatFinal:27.8,fatChange:-2.2,waistInit:99.5,waistFinal:96.1,waistChange:-3.4,dietCount:76,sportCount:45,weightCount:33},
{name:'何秀英',empId:'CQ102101',gender:'女',age:39,unit:'采油一厂',dept:'财务部',weightInit:71.0,weightFinal:67.8,weightChange:-3.2,bmiInit:26.8,bmiFinal:25.7,bmiChange:-1.1,fatInit:33.5,fatFinal:30.9,fatChange:-2.6,waistInit:85.0,waistFinal:81.0,waistChange:-4.0,dietCount:88,sportCount:62,weightCount:39},
{name:'马文博',empId:'CQ102223',gender:'男',age:32,unit:'采油一厂',dept:'生产技术部',weightInit:76.5,weightFinal:77.7,weightChange:+1.2,bmiInit:26.0,bmiFinal:26.4,bmiChange:+0.4,fatInit:24.0,fatFinal:24.9,fatChange:+0.9,waistInit:88.0,waistFinal:89.5,waistChange:+1.5,dietCount:28,sportCount:15,weightCount:10},
{name:'张翠花',empId:'CQ102345',gender:'女',age:43,unit:'采油二厂',dept:'工会办公室',weightInit:75.0,weightFinal:71.0,weightChange:-4.0,bmiInit:28.5,bmiFinal:27.2,bmiChange:-1.3,fatInit:35.5,fatFinal:32.2,fatChange:-3.3,waistInit:89.0,waistFinal:83.8,waistChange:-5.2,dietCount:95,sportCount:70,weightCount:44},
{name:'李伟强',empId:'CQ102467',gender:'男',age:37,unit:'采油二厂',dept:'安全环保科',weightInit:83.0,weightFinal:79.9,weightChange:-3.1,bmiInit:28.2,bmiFinal:27.2,bmiChange:-1.0,fatInit:27.0,fatFinal:24.6,fatChange:-2.4,waistInit:95.5,waistFinal:91.6,waistChange:-3.9,dietCount:80,sportCount:58,weightCount:36},
{name:'王雪琴',empId:'CQ102589',gender:'女',age:34,unit:'采油二厂',dept:'健康管理部',weightInit:67.5,weightFinal:65.0,weightChange:-2.5,bmiInit:25.5,bmiFinal:24.7,bmiChange:-0.8,fatInit:32.0,fatFinal:30.1,fatChange:-1.9,waistInit:82.0,waistFinal:78.9,waistChange:-3.1,dietCount:70,sportCount:50,weightCount:31},
{name:'赵勇刚',empId:'CQ102701',gender:'男',age:46,unit:'采油二厂',dept:'生产技术部',weightInit:94.5,weightFinal:89.2,weightChange:-5.3,bmiInit:32.5,bmiFinal:30.7,bmiChange:-1.8,fatInit:33.0,fatFinal:28.7,fatChange:-4.3,waistInit:107.5,waistFinal:100.8,waistChange:-6.7,dietCount:110,sportCount:82,weightCount:52},
{name:'陈晓峰',empId:'CQ102823',gender:'男',age:28,unit:'采油二厂',dept:'信息中心',weightInit:79.0,weightFinal:76.8,weightChange:-2.2,bmiInit:27.0,bmiFinal:26.3,bmiChange:-0.7,fatInit:25.5,fatFinal:23.8,fatChange:-1.7,waistInit:91.0,waistFinal:88.4,waistChange:-2.6,dietCount:62,sportCount:46,weightCount:26},
{name:'刘芳菲',empId:'CQ102945',gender:'女',age:30,unit:'采油二厂',dept:'工会办公室',weightInit:63.5,weightFinal:61.9,weightChange:-1.6,bmiInit:24.0,bmiFinal:23.5,bmiChange:-0.5,fatInit:30.0,fatFinal:28.8,fatChange:-1.2,waistInit:79.0,waistFinal:77.2,waistChange:-1.8,dietCount:52,sportCount:38,weightCount:20},
{name:'周建国',empId:'CQ103067',gender:'男',age:41,unit:'采油二厂',dept:'健康管理部',weightInit:85.0,weightFinal:81.4,weightChange:-3.6,bmiInit:29.0,bmiFinal:27.8,bmiChange:-1.2,fatInit:28.0,fatFinal:25.1,fatChange:-2.9,waistInit:98.0,waistFinal:93.5,waistChange:-4.5,dietCount:86,sportCount:65,weightCount:41},
{name:'吴明辉',empId:'CQ103189',gender:'男',age:35,unit:'采气一厂',dept:'生产技术部',weightInit:83.5,weightFinal:79.4,weightChange:-4.1,bmiInit:28.5,bmiFinal:27.1,bmiChange:-1.4,fatInit:27.2,fatFinal:24.1,fatChange:-3.1,waistInit:96.0,waistFinal:91.1,waistChange:-4.9,dietCount:92,sportCount:71,weightCount:43},
{name:'郑丽娟',empId:'CQ103301',gender:'女',age:33,unit:'采气一厂',dept:'信息中心',weightInit:66.5,weightFinal:64.5,weightChange:-2.0,bmiInit:25.2,bmiFinal:24.5,bmiChange:-0.7,fatInit:31.8,fatFinal:30.3,fatChange:-1.5,waistInit:81.5,waistFinal:79.1,waistChange:-2.4,dietCount:66,sportCount:49,weightCount:29},
{name:'黄志远',empId:'CQ103423',gender:'男',age:49,unit:'采气一厂',dept:'生产技术部',weightInit:92.0,weightFinal:87.2,weightChange:-4.8,bmiInit:31.8,bmiFinal:30.2,bmiChange:-1.6,fatInit:32.0,fatFinal:28.2,fatChange:-3.8,waistInit:105.5,waistFinal:99.5,waistChange:-6.0,dietCount:104,sportCount:78,weightCount:49},
{name:'杨小红',empId:'CQ103545',gender:'女',age:26,unit:'采气一厂',dept:'信息中心',weightInit:58.0,weightFinal:56.7,weightChange:-1.3,bmiInit:22.0,bmiFinal:21.6,bmiChange:-0.4,fatInit:28.5,fatFinal:27.5,fatChange:-1.0,waistInit:75.0,waistFinal:73.5,waistChange:-1.5,dietCount:48,sportCount:35,weightCount:18},
{name:'孙大伟',empId:'CQ103667',gender:'男',age:39,unit:'采气一厂',dept:'生产技术部',weightInit:84.5,weightFinal:81.2,weightChange:-3.3,bmiInit:28.8,bmiFinal:27.7,bmiChange:-1.1,fatInit:27.8,fatFinal:25.1,fatChange:-2.7,waistInit:97.0,waistFinal:92.8,waistChange:-4.2,dietCount:84,sportCount:62,weightCount:37},
{name:'林翠萍',empId:'CQ103789',gender:'女',age:44,unit:'采气一厂',dept:'信息中心',weightInit:73.5,weightFinal:69.8,weightChange:-3.7,bmiInit:27.8,bmiFinal:26.6,bmiChange:-1.2,fatInit:34.8,fatFinal:31.9,fatChange:-2.9,waistInit:87.5,waistFinal:82.8,waistChange:-4.7,dietCount:89,sportCount:67,weightCount:42},
{name:'何俊杰',empId:'CQ103901',gender:'男',age:31,unit:'采气一厂',dept:'生产技术部',weightInit:77.0,weightFinal:77.5,weightChange:+0.5,bmiInit:26.2,bmiFinal:26.4,bmiChange:+0.2,fatInit:24.2,fatFinal:24.6,fatChange:+0.4,waistInit:88.5,waistFinal:89.3,waistChange:+0.8,dietCount:35,sportCount:22,weightCount:14},
{name:'马兰花',empId:'CQ104023',gender:'女',age:37,unit:'采气一厂',dept:'信息中心',weightInit:70.0,weightFinal:67.1,weightChange:-2.9,bmiInit:26.5,bmiFinal:25.5,bmiChange:-1.0,fatInit:33.0,fatFinal:30.7,fatChange:-2.3,waistInit:84.0,waistFinal:80.4,waistChange:-3.6,dietCount:78,sportCount:56,weightCount:34},
{name:'张永强',empId:'CQ104145',gender:'男',age:43,unit:'第四采油厂',dept:'生产技术部',weightInit:90.5,weightFinal:85.5,weightChange:-5.0,bmiInit:31.0,bmiFinal:29.3,bmiChange:-1.7,fatInit:31.0,fatFinal:27.0,fatChange:-4.0,waistInit:104.0,waistFinal:97.7,waistChange:-6.3,dietCount:108,sportCount:79,weightCount:51},
{name:'李春梅',empId:'CQ104267',gender:'女',age:36,unit:'第四采油厂',dept:'工会办公室',weightInit:69.0,weightFinal:66.3,weightChange:-2.7,bmiInit:26.0,bmiFinal:25.1,bmiChange:-0.9,fatInit:32.5,fatFinal:30.4,fatChange:-2.1,waistInit:83.5,waistFinal:80.1,waistChange:-3.4,dietCount:74,sportCount:54,weightCount:31},
{name:'王海涛',empId:'CQ104389',gender:'男',age:29,unit:'第四采油厂',dept:'信息中心',weightInit:77.5,weightFinal:75.6,weightChange:-1.9,bmiInit:26.5,bmiFinal:25.9,bmiChange:-0.6,fatInit:25.0,fatFinal:23.5,fatChange:-1.5,waistInit:90.0,waistFinal:87.7,waistChange:-2.3,dietCount:60,sportCount:44,weightCount:25},
{name:'赵玉兰',empId:'CQ104501',gender:'女',age:41,unit:'采油一厂',dept:'健康管理部',weightInit:73.0,weightFinal:69.6,weightChange:-3.4,bmiInit:27.5,bmiFinal:26.4,bmiChange:-1.1,fatInit:34.0,fatFinal:31.3,fatChange:-2.7,waistInit:86.0,waistFinal:81.6,waistChange:-4.4,dietCount:84,sportCount:63,weightCount:38},
{name:'陈国强',empId:'CQ104623',gender:'男',age:34,unit:'采油一厂',dept:'工会办公室',weightInit:80.0,weightFinal:77.6,weightChange:-2.4,bmiInit:27.2,bmiFinal:26.4,bmiChange:-0.8,fatInit:26.0,fatFinal:24.1,fatChange:-1.9,waistInit:93.0,waistFinal:90.0,waistChange:-3.0,dietCount:69,sportCount:51,weightCount:30},
{name:'刘志强',empId:'CQ104745',gender:'男',age:47,unit:'采油二厂',dept:'健康管理部',weightInit:91.0,weightFinal:86.4,weightChange:-4.6,bmiInit:31.2,bmiFinal:29.7,bmiChange:-1.5,fatInit:31.5,fatFinal:27.8,fatChange:-3.7,waistInit:104.5,waistFinal:98.9,waistChange:-5.6,dietCount:100,sportCount:74,weightCount:47},
{name:'周秀芳',empId:'CQ104867',gender:'女',age:28,unit:'采油二厂',dept:'安全环保科',weightInit:60.0,weightFinal:58.6,weightChange:-1.4,bmiInit:22.8,bmiFinal:22.3,bmiChange:-0.5,fatInit:29.5,fatFinal:28.4,fatChange:-1.1,waistInit:77.0,waistFinal:75.3,waistChange:-1.7,dietCount:50,sportCount:36,weightCount:19},
{name:'吴建国',empId:'CQ104989',gender:'男',age:40,unit:'采油二厂',dept:'生产技术部',weightInit:84.0,weightFinal:80.1,weightChange:-3.9,bmiInit:28.5,bmiFinal:27.2,bmiChange:-1.3,fatInit:27.5,fatFinal:24.4,fatChange:-3.1,waistInit:96.5,waistFinal:91.7,waistChange:-4.8,dietCount:91,sportCount:69,weightCount:43},
{name:'郑志明',empId:'CQ105101',gender:'男',age:33,unit:'采气一厂',dept:'生产技术部',weightInit:82.0,weightFinal:79.4,weightChange:-2.6,bmiInit:27.8,bmiFinal:26.9,bmiChange:-0.9,fatInit:26.5,fatFinal:24.5,fatChange:-2.0,waistInit:94.0,waistFinal:90.8,waistChange:-3.2,dietCount:72,sportCount:53,weightCount:32},
{name:'黄美琴',empId:'CQ105223',gender:'女',age:38,unit:'采气一厂',dept:'信息中心',weightInit:71.5,weightFinal:68.4,weightChange:-3.1,bmiInit:27.0,bmiFinal:26.0,bmiChange:-1.0,fatInit:33.2,fatFinal:30.7,fatChange:-2.5,waistInit:85.5,waistFinal:81.6,waistChange:-3.9,dietCount:81,sportCount:59,weightCount:36}
];
var pageSize = 10;
var currentPage = 0;
var filteredData = personnelData.slice();
/* ===== 单位部门级联 ===== */
var deptMap = {
'第四采油厂':['健康管理部','安全环保科','工会办公室','生产技术部','财务部','信息中心'],
'采油一厂':['健康管理部','安全环保科','工会办公室','生产技术部'],
'采油二厂':['健康管理部','安全环保科','生产技术部','信息中心'],
'采气一厂':['生产技术部','信息中心']
};
var selUnitName = '';
var selUnitCode = '';
var selDeptName = '';
var selDeptCode = '';
function toggleOrg(){
var panel = document.getElementById('orgPanel');
var trigger = document.getElementById('orgTrigger');
panel.classList.toggle('open');
trigger.classList.toggle('open');
}
function selectUnit(elem, unitName, unitCode){
document.querySelectorAll('#unitCol .org-item').forEach(function(item){item.classList.remove('active');});
elem.classList.add('active');
selUnitName = unitName;
selUnitCode = unitCode;
var depts = deptMap[unitCode] || [];
var html = '<div class="org-col__title">部门</div>';
html += '<div class="org-item active" data-dept="" onclick="selectDept(this,\'全部部门\',\'\')">全部部门</div>';
depts.forEach(function(d){
html += '<div class="org-item" data-dept="'+d+'" onclick="selectDept(this,\''+d+'\',\''+d+'\')">'+d+'</div>';
});
document.getElementById('deptCol').innerHTML = html;
selDeptName = '';
selDeptCode = '';
}
function selectDept(elem, deptName, deptCode){
document.querySelectorAll('#deptCol .org-item').forEach(function(item){item.classList.remove('active');});
elem.classList.add('active');
selDeptName = deptName;
selDeptCode = deptCode;
var label = selUnitCode ? selUnitName : '全部单位';
label += selDeptCode ? ' / ' + deptName : ' / 全部部门';
document.getElementById('orgTrigger').textContent = label;
}
/* ===== 筛选 ===== */
function applyFilter(){
var name = document.getElementById('filterName').value.trim().toLowerCase();
var empId = document.getElementById('filterEmpId').value.trim().toLowerCase();
var unit = selUnitCode;
var dept = selDeptCode;
var dateFrom = document.getElementById('filterDateFrom').value;
var dateTo = document.getElementById('filterDateTo').value;
var data = personnelData.slice();
if(name){ data = data.filter(function(d){return d.name.toLowerCase().indexOf(name) !== -1;}); }
if(empId){ data = data.filter(function(d){return d.empId.toLowerCase().indexOf(empId) !== -1;}); }
if(unit){ data = data.filter(function(d){return d.unit === unit;}); }
if(dept){ data = data.filter(function(d){return d.dept === dept;}); }
// 日期范围筛选 — 基于记录日期(Mock 数据中没有日期字段,保留筛选逻辑用于后续对接真实数据)
if(dateFrom || dateTo){
// 当前 Mock 数据不含日期字段,日期筛选不影响结果
// 对接真实接口后启用:
// if(dateFrom){ data = data.filter(function(d){return d.recordDate >= dateFrom;}); }
// if(dateTo){ data = data.filter(function(d){return d.recordDate <= dateTo;}); }
}
filteredData = data;
currentPage = 0;
renderTable();
}
function resetFilter(){
document.getElementById('filterName').value = '';
document.getElementById('filterEmpId').value = '';
selUnitName = ''; selUnitCode = '';
selDeptName = ''; selDeptCode = '';
document.getElementById('orgTrigger').textContent = '全部单位/部门';
document.querySelectorAll('#unitCol .org-item').forEach(function(item){item.classList.remove('active');});
var firstUnit = document.querySelector('#unitCol .org-item');
if(firstUnit) firstUnit.classList.add('active');
document.getElementById('deptCol').innerHTML = '<div class="org-col__title">部门</div><div class="org-item active" data-dept="" onclick="selectDept(this,\'全部部门\',\'\')">全部部门</div>';
var now = new Date();
document.getElementById('filterDateFrom').value = now.getFullYear() + '-01-01';
document.getElementById('filterDateTo').value = now.getFullYear() + '-' + String(now.getMonth()+1).padStart(2,'0') + '-' + String(now.getDate()).padStart(2,'0');
applyFilter();
}
/* ===== 渲染表格 ===== */
function renderTable(){
var tbody = document.getElementById('tableBody');
var start = currentPage * pageSize;
var pageData = filteredData.slice(start, start + pageSize);
var totalPages = Math.ceil(filteredData.length / pageSize) || 1;
document.getElementById('pageInfo').textContent = '显示 ' + pageData.length + ' 条,共 ' + filteredData.length + ' 条记录';
document.getElementById('pageNum').textContent = '第 ' + (currentPage + 1) + '/' + totalPages + ' 页';
if(filteredData.length === 0){
tbody.innerHTML = '<tr><td colspan="22" class="td-empty">暂无匹配数据</td></tr>';
return;
}
var html = '';
pageData.forEach(function(d){
var wCls = d.weightChange < 0 ? 'change-down' : (d.weightChange > 0 ? 'change-up' : 'change-zero');
var bCls = d.bmiChange < 0 ? 'change-down' : (d.bmiChange > 0 ? 'change-up' : 'change-zero');
var fCls = d.fatChange < 0 ? 'change-down' : (d.fatChange > 0 ? 'change-up' : 'change-zero');
var waCls = d.waistChange < 0 ? 'change-down' : (d.waistChange > 0 ? 'change-up' : 'change-zero');
html += '<tr>';
html += '<td>'+esc(d.name)+'</td>';
html += '<td>'+esc(d.empId)+'</td>';
html += '<td>'+d.gender+'</td>';
html += '<td>'+d.age+'</td>';
html += '<td>'+esc(d.unit)+'</td>';
html += '<td>'+esc(d.dept)+'</td>';
html += '<td>'+d.weightInit.toFixed(1)+'</td>';
html += '<td>'+d.weightFinal.toFixed(1)+'</td>';
html += '<td class="'+wCls+'">'+(d.weightChange < 0 ? d.weightChange.toFixed(1) : (d.weightChange > 0 ? '+'+d.weightChange.toFixed(1) : '0'))+'</td>';
html += '<td>'+d.bmiInit.toFixed(1)+'</td>';
html += '<td>'+d.bmiFinal.toFixed(1)+'</td>';
html += '<td class="'+bCls+'">'+(d.bmiChange < 0 ? d.bmiChange.toFixed(1) : (d.bmiChange > 0 ? '+'+d.bmiChange.toFixed(1) : '0'))+'</td>';
html += '<td>'+d.fatInit.toFixed(1)+'</td>';
html += '<td>'+d.fatFinal.toFixed(1)+'</td>';
html += '<td class="'+fCls+'">'+(d.fatChange < 0 ? d.fatChange.toFixed(1) : (d.fatChange > 0 ? '+'+d.fatChange.toFixed(1) : '0'))+'</td>';
html += '<td>'+d.waistInit.toFixed(1)+'</td>';
html += '<td>'+d.waistFinal.toFixed(1)+'</td>';
html += '<td class="'+waCls+'">'+(d.waistChange < 0 ? d.waistChange.toFixed(1) : (d.waistChange > 0 ? '+'+d.waistChange.toFixed(1) : '0'))+'</td>';
html += '<td>'+d.dietCount+'</td>';
html += '<td>'+d.sportCount+'</td>';
html += '<td>'+d.weightCount+'</td>';
html += '<td><a class="link" href="history-personnel-detail.html?id='+esc(d.empId)+'&dateFrom='+encodeURIComponent(document.getElementById('filterDateFrom').value)+'&dateTo='+encodeURIComponent(document.getElementById('filterDateTo').value)+'">查看</a></td>';
html += '</tr>';
});
tbody.innerHTML = html;
}
/* ===== 翻页 ===== */
function goPage(delta){
var totalPages = Math.ceil(filteredData.length / pageSize);
var newPage = currentPage + delta;
if(newPage < 0 || newPage >= totalPages) return;
currentPage = newPage;
renderTable();
}
/* 点击外部关闭单位部门面板 */
document.addEventListener('click', function(e){
var ow = document.getElementById('orgWrap');
if(ow && !ow.contains(e.target)){
document.getElementById('orgPanel').classList.remove('open');
document.getElementById('orgTrigger').classList.remove('open');
}
});
/* ===== 工具函数 ===== */
function esc(s){return String(s||'').replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;').replace(/>/g,'&gt;');}
function showToast(msg){
var t=document.getElementById('toast');t.textContent=msg;t.classList.add('show');
setTimeout(function(){t.classList.remove('show');},2000);
}
/* ===== 初始化 ===== */
(function init(){
var now = new Date();
var yearStart = now.getFullYear() + '-01-01';
var today = now.getFullYear() + '-' + String(now.getMonth()+1).padStart(2,'0') + '-' + String(now.getDate()).padStart(2,'0');
document.getElementById('filterDateFrom').value = yearStart;
document.getElementById('filterDateTo').value = today;
renderTable();
})();
</script>
</body>
</html>
@@ -314,6 +314,7 @@ tbody tr:hover{background:#F8FBFF;}
<aside class="sidebar">
<div class="sidebar-menu__title">历史干预</div>
<a href="history-plan-list.html" class="sidebar-item active">计划列表</a>
<a href="history-personnel-list.html" class="sidebar-item">人员列表</a>
</aside>
<!-- 主内容 -->
@@ -165,6 +165,7 @@ tbody tr:hover td:nth-child(2){background:#F8FBFF;}
<aside class="sidebar">
<div class="sidebar-menu__title">历史干预</div>
<a href="history-plan-list.html" class="sidebar-item active">计划列表</a>
<a href="history-personnel-list.html" class="sidebar-item">人员列表</a>
</aside>
<!-- 主内容 -->
@@ -32,18 +32,8 @@
.sidebar-item.active{color:#fff;background:var(--primary);}
.main{margin-left:240px;margin-top:56px;padding:24px;min-height:calc(100vh - 56px);}
/* Tab 切换栏 */
.tab-bar{display:flex;gap:0;padding:0 24px;background:#fff;border-radius:var(--radius-md) var(--radius-md) 0 0;box-shadow:var(--shadow-sm);border-bottom:1px solid var(--border);}
.tab-item{padding:12px 20px;font-size:var(--font-sm);cursor:pointer;color:var(--text-secondary);border-bottom:2px solid transparent;margin-bottom:-1px;transition:all .2s;font-weight:500;}
.tab-item:hover{color:var(--primary);}
.tab-item.active{color:var(--primary);border-bottom-color:var(--primary);font-weight:600;}
.tab-item__badge{display:inline-block;margin-left:6px;padding:0 8px;border-radius:10px;font-size:var(--font-xs);background:#F0F0F0;color:var(--text-secondary);line-height:1.8;}
.tab-item.active .tab-item__badge{background:var(--primary-light);color:var(--primary);}
.tab-panel{display:none;}
.tab-panel.active{display:block;}
/* 筛选栏 */
.filter-bar{background:#fff;padding:16px 24px;display:flex;align-items:center;gap:16px;flex-wrap:wrap;border-bottom:1px solid var(--border);}
.filter-bar{background:#fff;padding:16px 24px;display:flex;align-items:center;gap:16px;flex-wrap:wrap;border-bottom:1px solid var(--border);border-radius:var(--radius-md) var(--radius-md) 0 0;}
.filter-item{display:flex;align-items:center;gap:8px;}
.filter-item label{font-size:var(--font-sm);color:var(--text-secondary);white-space:nowrap;}
.filter-input{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;min-width:140px;}
@@ -82,16 +72,16 @@
tbody tr:hover{background:#F8FBFF;}
.td-empty{text-align:center;padding:48px 0;color:var(--text-placeholder);font-size:var(--font-sm);}
/* 固定列:首两列左固定,末列右固定 */
.col-fixed-l1{position:sticky;left:0;z-index:2;}
.col-fixed-l2{position:sticky;left:72px;z-index:2;}
.col-fixed-r{position:sticky;right:0;z-index:2;}
thead .col-fixed-l1,thead .col-fixed-l2,thead .col-fixed-r{background:#FAFAFA;}
tbody .col-fixed-l1,tbody .col-fixed-l2,tbody .col-fixed-r{background:#fff;}
tbody tr:hover .col-fixed-l1,tbody tr:hover .col-fixed-l2,tbody tr:hover .col-fixed-r{background:#F8FBFF;}
/* 查看按钮 */
.btn-link{color:var(--primary);cursor:pointer;background:none;border:none;font-size:var(--font-sm);padding:0;text-decoration:none;}
.btn-link:hover{color:#40a9ff;text-decoration:underline;}
/* 固定列:首两列左固定,末列右固定 */
.col-fixed-l1{position:sticky;left:0;z-index:2;}
.col-fixed-l2{position:sticky;left:72px;z-index:2;}
.col-fixed-r{position:sticky;right:0;z-index:2;}
thead .col-fixed-l1,thead .col-fixed-l2,thead .col-fixed-r{background:#FAFAFA;}
tbody .col-fixed-l1,tbody .col-fixed-l2,tbody .col-fixed-r{background:#fff;}
tbody tr:hover .col-fixed-l1,tbody tr:hover .col-fixed-l2,tbody tr:hover .col-fixed-r{background:#F8FBFF;}
/* 查看按钮 */
.btn-link{color:var(--primary);cursor:pointer;background:none;border:none;font-size:var(--font-sm);padding:0;text-decoration:none;}
.btn-link:hover{color:#40a9ff;text-decoration:underline;}
/* 变化值颜色 */
.change-down{color:var(--success);}
@@ -129,223 +119,175 @@
<a href="personal-target-data.html" class="sidebar-item active">个人目标数据</a>
</aside>
<main class="main">
<!-- [交互] Tab 切换:已设置目标 / 未设置目标,切换时下方筛选区+列表联动 -->
<div class="tab-bar">
<div class="tab-item active" data-tab="0" onclick="switchTab(0)">已设置目标</div>
<div class="tab-item" data-tab="1" onclick="switchTab(1)">未设置目标</div>
</div>
<!-- Tab 0:已设置目标 -->
<div class="tab-panel active" id="tabPanel0">
<!-- 筛选条件 -->
<div class="filter-bar">
<!-- [交互] 单位部门双列面板:左选单位→右侧部门联动加载 -->
<div class="filter-item">
<label>单位部门</label>
<div class="org-select-wrap" id="orgWrap0">
<div class="org-trigger" id="orgTrigger0" onclick="toggleOrg(0)">全部单位/部门</div>
<div class="org-panel" id="orgPanel0">
<div class="org-col" id="orgUnitCol0">
<div class="org-col__title">单位</div>
<div class="org-item active" data-unit="" onclick="selectUnit(0, this, '全部单位/部门', '')">全部单位/部门</div>
<div class="org-item" data-unit="采油一厂" onclick="selectUnit(0, this, '采油一厂', '采油一厂')">采油一厂</div>
<div class="org-item" data-unit="采油二厂" onclick="selectUnit(0, this, '采油二厂', '采油二厂')">采油二厂</div>
<div class="org-item" data-unit="采气厂" onclick="selectUnit(0, this, '采气厂', '采气厂')">采气厂</div>
</div>
<div class="org-col" id="orgDeptCol0">
<div class="org-col__title">部门</div>
<div class="org-item active" data-dept="" onclick="selectDept(0, this, '全部部门', '')">全部部门</div>
</div>
<!-- 筛选条件 -->
<div class="filter-bar">
<!-- [交互] 单位部门双列面板:左选单位→右侧部门联动加载 -->
<div class="filter-item">
<label>单位部门</label>
<div class="org-select-wrap" id="orgWrap">
<div class="org-trigger" id="orgTrigger" onclick="toggleOrg()">全部单位/部门</div>
<div class="org-panel" id="orgPanel">
<div class="org-col" id="orgUnitCol">
<div class="org-col__title">单位</div>
<div class="org-item active" data-unit="" onclick="selectUnit(this, '全部单位/部门', '')">全部单位/部门</div>
<div class="org-item" data-unit="采油一厂" onclick="selectUnit(this, '采油一厂', '采油一厂')">采油一厂</div>
<div class="org-item" data-unit="采油二厂" onclick="selectUnit(this, '采油二厂', '采油二厂')">采油二厂</div>
<div class="org-item" data-unit="采气厂" onclick="selectUnit(this, '采气厂', '采气厂')">采气厂</div>
</div>
<div class="org-col" id="orgDeptCol">
<div class="org-col__title">部门</div>
<div class="org-item active" data-dept="" onclick="selectDept(this, '全部部门', '')">全部部门</div>
</div>
</div>
</div>
<div class="filter-item"><label>姓名</label><input class="filter-input" placeholder="请输入姓名" style="min-width:120px;"></div>
<div class="filter-item"><label>员工编号</label><input class="filter-input" placeholder="请输入员工编号" style="min-width:140px;"></div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
</div>
<!-- [交互] 操作按钮:导出列表数据触发浏览器下载;查看导出任务跳转至导出任务列表弹窗 -->
<div class="action-bar">
<button class="btn btn-default">导出列表数据</button>
<button class="btn btn-default">查看导出任务</button>
</div>
<!-- 数据列表 -->
<div class="table-card">
<div class="table-card__content">
<table>
<thead>
<tr>
<th rowspan="2" style="vertical-align:middle;" class="col-fixed-l1">姓名</th>
<th rowspan="2" style="vertical-align:middle;" class="col-fixed-l2">员工编号</th>
<th rowspan="2" style="vertical-align:middle;">性别</th>
<th rowspan="2" style="vertical-align:middle;">年龄</th>
<th rowspan="2" style="vertical-align:middle;">单位</th>
<th rowspan="2" style="vertical-align:middle;">部门</th>
<th colspan="2" style="text-align:center;border-bottom:1px solid var(--border);" class="th-divider">目标周期</th>
<th colspan="5" style="text-align:center;border-bottom:1px solid var(--border);" class="th-divider">初始指标</th>
<th colspan="4" style="text-align:center;border-bottom:1px solid var(--border);" class="th-divider">目标指标</th>
<th colspan="4" style="text-align:center;border-bottom:1px solid var(--border);" class="th-divider">当前指标</th>
<th colspan="4" style="text-align:center;border-bottom:1px solid var(--border);">变化</th>
<th rowspan="2" style="vertical-align:middle;" class="col-fixed-r">详细数据</th>
</tr>
<tr>
<th>目标起止日期</th><th class="th-divider">目标天数</th>
<th>身高(cm)</th><th>初始体重(kg)</th><th>初始BMI</th><th>初始体脂(%)</th><th class="th-divider">初始腰围(cm)</th>
<th>目标体重(kg)</th><th>目标BMI</th><th>目标体脂(%)</th><th class="th-divider">目标腰围(cm)</th>
<th>现体重(kg)</th><th>现BMI</th><th>现体脂(%)</th><th class="th-divider">现腰围(cm)</th>
<th>体重变化(kg)</th><th>BMI变化</th><th>体脂变化(%)</th><th>腰围变化(cm)</th>
</tr>
</thead>
<tbody>
<tr>
<td class="col-fixed-l1">张伟</td><td class="col-fixed-l2">EMP-10001</td><td></td><td>35</td><td>采油一厂</td><td>生产运行科</td>
<td>2024-03-01 ~ 2024-09-01</td><td class="th-divider">184</td>
<td>175</td><td>85.0</td><td>27.8</td><td>26.5</td><td class="th-divider">96</td>
<td>72.0</td><td>23.5</td><td>20.0</td><td class="th-divider">82</td>
<td>73.5</td><td>24.0</td><td>21.2</td><td class="th-divider">84</td>
<td class="change-down">-11.5</td><td class="change-down">-3.8</td><td class="change-down">-5.3</td><td class="change-down">-12</td>
<td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10001">查看</a></td>
</tr>
<tr>
<td class="col-fixed-l1">李娜</td><td class="col-fixed-l2">EMP-10002</td><td></td><td>28</td><td>采油一厂</td><td>安全环保科</td>
<td>2024-03-15 ~ 2024-09-15</td><td class="th-divider">184</td>
<td>163</td><td>68.5</td><td>25.8</td><td>32.0</td><td class="th-divider">82</td>
<td>55.0</td><td>20.7</td><td>24.0</td><td class="th-divider">68</td>
<td>57.2</td><td>21.5</td><td>25.1</td><td class="th-divider">70</td>
<td class="change-down">-11.3</td><td class="change-down">-4.3</td><td class="change-down">-6.9</td><td class="change-down">-12</td>
<td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10002">查看</a></td>
</tr>
<tr>
<td class="col-fixed-l1">王强</td><td class="col-fixed-l2">EMP-10003</td><td></td><td>42</td><td>采油二厂</td><td>综合管理科</td>
<td>2024-04-01 ~ 2024-10-01</td><td class="th-divider">183</td>
<td>170</td><td>92.0</td><td>31.8</td><td>30.2</td><td class="th-divider">105</td>
<td>78.0</td><td>27.0</td><td>24.0</td><td class="th-divider">90</td>
<td>80.5</td><td>27.9</td><td>25.8</td><td class="th-divider">93</td>
<td class="change-down">-11.5</td><td class="change-down">-3.9</td><td class="change-down">-4.4</td><td class="change-down">-12</td>
<td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10003">查看</a></td>
</tr>
<tr>
<td class="col-fixed-l1">赵敏</td><td class="col-fixed-l2">EMP-10004</td><td></td><td>31</td><td>采油二厂</td><td>生产运行科</td>
<td>2024-02-15 ~ 2024-08-15</td><td class="th-divider">182</td>
<td>160</td><td>62.0</td><td>24.2</td><td>28.5</td><td class="th-divider">78</td>
<td>52.0</td><td>20.3</td><td>22.0</td><td class="th-divider">66</td>
<td>53.5</td><td>20.9</td><td>23.1</td><td class="th-divider">68</td>
<td class="change-down">-8.5</td><td class="change-down">-3.3</td><td class="change-down">-5.4</td><td class="change-down">-10</td>
<td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10004">查看</a></td>
</tr>
<tr>
<td class="col-fixed-l1">刘洋</td><td class="col-fixed-l2">EMP-10005</td><td></td><td>38</td><td>采气厂</td><td>安全环保科</td>
<td>2024-03-20 ~ 2024-09-20</td><td class="th-divider">184</td>
<td>178</td><td>88.5</td><td>27.9</td><td>27.8</td><td class="th-divider">100</td>
<td>75.0</td><td>23.7</td><td>20.0</td><td class="th-divider">85</td>
<td>77.2</td><td>24.4</td><td>21.5</td><td class="th-divider">87</td>
<td class="change-down">-11.3</td><td class="change-down">-3.5</td><td class="change-down">-6.3</td><td class="change-down">-13</td>
<td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10005">查看</a></td>
</tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>共 156 条</span>
<button class="page-btn"></button>
<button class="page-btn active">1</button>
<button class="page-btn">2</button>
<button class="page-btn">3</button>
<button class="page-btn">...</button>
<button class="page-btn">16</button>
<button class="page-btn"></button>
</div>
</div>
<div class="filter-item"><label>姓名</label><input class="filter-input" placeholder="请输入姓名" style="min-width:120px;"></div>
<div class="filter-item"><label>员工编号</label><input class="filter-input" placeholder="请输入员工编号" style="min-width:140px;"></div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
</div>
<!-- Tab 1:未设置目标 -->
<div class="tab-panel" id="tabPanel1">
<!-- 筛选条件 -->
<div class="filter-bar">
<!-- [交互] 单位部门双列面板:左选单位→右侧部门联动加载 -->
<div class="filter-item">
<label>单位部门</label>
<div class="org-select-wrap" id="orgWrap1">
<div class="org-trigger" id="orgTrigger1" onclick="toggleOrg(1)">全部单位/部门</div>
<div class="org-panel" id="orgPanel1">
<div class="org-col" id="orgUnitCol1">
<div class="org-col__title">单位</div>
<div class="org-item active" data-unit="" onclick="selectUnit(1, this, '全部单位/部门', '')">全部单位/部门</div>
<div class="org-item" data-unit="采油一厂" onclick="selectUnit(1, this, '采油一厂', '采油一厂')">采油一厂</div>
<div class="org-item" data-unit="采油二厂" onclick="selectUnit(1, this, '采油二厂', '采油二厂')">采油二厂</div>
<div class="org-item" data-unit="采气厂" onclick="selectUnit(1, this, '采气厂', '采气厂')">采气厂</div>
</div>
<div class="org-col" id="orgDeptCol1">
<div class="org-col__title">部门</div>
<div class="org-item active" data-dept="" onclick="selectDept(1, this, '全部部门', '')">全部部门</div>
</div>
</div>
</div>
</div>
<div class="filter-item"><label>姓名</label><input class="filter-input" placeholder="请输入姓名" style="min-width:120px;"></div>
<div class="filter-item"><label>员工编号</label><input class="filter-input" placeholder="请输入员工编号" style="min-width:140px;"></div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
<!-- [交互] 操作按钮:导出列表数据触发浏览器下载;查看导出任务跳转至导出任务列表弹窗 -->
<div class="action-bar">
<button class="btn btn-default">导出列表数据</button>
<button class="btn btn-default">查看导出任务</button>
</div>
<!-- 数据列表:已设置目标 + 未设置目标融合展示,未设置目标的行在目标周期/目标指标等列显示"-" -->
<div class="table-card">
<div class="table-card__content">
<table>
<thead>
<tr>
<th rowspan="2" style="vertical-align:middle;" class="col-fixed-l1">姓名</th>
<th rowspan="2" style="vertical-align:middle;" class="col-fixed-l2">员工编号</th>
<th rowspan="2" style="vertical-align:middle;">性别</th>
<th rowspan="2" style="vertical-align:middle;">年龄</th>
<th rowspan="2" style="vertical-align:middle;">单位</th>
<th rowspan="2" style="vertical-align:middle;">部门</th>
<th colspan="2" style="text-align:center;border-bottom:1px solid var(--border);" class="th-divider">目标周期</th>
<th colspan="5" style="text-align:center;border-bottom:1px solid var(--border);" class="th-divider">初始指标</th>
<th colspan="4" style="text-align:center;border-bottom:1px solid var(--border);" class="th-divider">目标指标</th>
<th colspan="4" style="text-align:center;border-bottom:1px solid var(--border);" class="th-divider">当前指标</th>
<th colspan="4" style="text-align:center;border-bottom:1px solid var(--border);">变化</th>
<th rowspan="2" style="vertical-align:middle;" class="col-fixed-r">详细数据</th>
</tr>
<tr>
<th>目标起止日期</th><th class="th-divider">目标天数</th>
<th>身高(cm)</th><th>初始体重(kg)</th><th>初始BMI</th><th>初始体脂(%)</th><th class="th-divider">初始腰围(cm)</th>
<th>目标体重(kg)</th><th>目标BMI</th><th>目标体脂(%)</th><th class="th-divider">目标腰围(cm)</th>
<th>现体重(kg)</th><th>现BMI</th><th>现体脂(%)</th><th class="th-divider">现腰围(cm)</th>
<th>体重变化(kg)</th><th>BMI变化</th><th>体脂变化(%)</th><th>腰围变化(cm)</th>
</tr>
</thead>
<tbody>
<!-- 已设置目标的人员 -->
<tr>
<td class="col-fixed-l1">张伟</td><td class="col-fixed-l2">EMP-10001</td><td></td><td>35</td><td>采油一厂</td><td>生产运行科</td>
<td>2024-03-01 ~ 2024-09-01</td><td class="th-divider">184</td>
<td>175</td><td>85.0</td><td>27.8</td><td>26.5</td><td class="th-divider">96</td>
<td>72.0</td><td>23.5</td><td>20.0</td><td class="th-divider">82</td>
<td>73.5</td><td>24.0</td><td>21.2</td><td class="th-divider">84</td>
<td class="change-down">-11.5</td><td class="change-down">-3.8</td><td class="change-down">-5.3</td><td class="change-down">-12</td>
<td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10001">查看</a></td>
</tr>
<tr>
<td class="col-fixed-l1">李娜</td><td class="col-fixed-l2">EMP-10002</td><td></td><td>28</td><td>采油一厂</td><td>安全环保科</td>
<td>2024-03-15 ~ 2024-09-15</td><td class="th-divider">184</td>
<td>163</td><td>68.5</td><td>25.8</td><td>32.0</td><td class="th-divider">82</td>
<td>55.0</td><td>20.7</td><td>24.0</td><td class="th-divider">68</td>
<td>57.2</td><td>21.5</td><td>25.1</td><td class="th-divider">70</td>
<td class="change-down">-11.3</td><td class="change-down">-4.3</td><td class="change-down">-6.9</td><td class="change-down">-12</td>
<td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10002">查看</a></td>
</tr>
<tr>
<td class="col-fixed-l1">王强</td><td class="col-fixed-l2">EMP-10003</td><td></td><td>42</td><td>采油二厂</td><td>综合管理科</td>
<td>2024-04-01 ~ 2024-10-01</td><td class="th-divider">183</td>
<td>170</td><td>92.0</td><td>31.8</td><td>30.2</td><td class="th-divider">105</td>
<td>78.0</td><td>27.0</td><td>24.0</td><td class="th-divider">90</td>
<td>80.5</td><td>27.9</td><td>25.8</td><td class="th-divider">93</td>
<td class="change-down">-11.5</td><td class="change-down">-3.9</td><td class="change-down">-4.4</td><td class="change-down">-12</td>
<td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10003">查看</a></td>
</tr>
<tr>
<td class="col-fixed-l1">赵敏</td><td class="col-fixed-l2">EMP-10004</td><td></td><td>31</td><td>采油二厂</td><td>生产运行科</td>
<td>2024-02-15 ~ 2024-08-15</td><td class="th-divider">182</td>
<td>160</td><td>62.0</td><td>24.2</td><td>28.5</td><td class="th-divider">78</td>
<td>52.0</td><td>20.3</td><td>22.0</td><td class="th-divider">66</td>
<td>53.5</td><td>20.9</td><td>23.1</td><td class="th-divider">68</td>
<td class="change-down">-8.5</td><td class="change-down">-3.3</td><td class="change-down">-5.4</td><td class="change-down">-10</td>
<td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10004">查看</a></td>
</tr>
<tr>
<td class="col-fixed-l1">刘洋</td><td class="col-fixed-l2">EMP-10005</td><td></td><td>38</td><td>采气厂</td><td>安全环保科</td>
<td>2024-03-20 ~ 2024-09-20</td><td class="th-divider">184</td>
<td>178</td><td>88.5</td><td>27.9</td><td>27.8</td><td class="th-divider">100</td>
<td>75.0</td><td>23.7</td><td>20.0</td><td class="th-divider">85</td>
<td>77.2</td><td>24.4</td><td>21.5</td><td class="th-divider">87</td>
<td class="change-down">-11.3</td><td class="change-down">-3.5</td><td class="change-down">-6.3</td><td class="change-down">-13</td>
<td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10005">查看</a></td>
</tr>
<!-- 未设置目标的人员:目标周期/目标指标显示"-",当前指标和变化有实际称重数据 -->
<tr>
<td class="col-fixed-l1">孙磊</td><td class="col-fixed-l2">EMP-10101</td><td></td><td>29</td><td>采油一厂</td><td>生产运行科</td>
<td>-</td><td class="th-divider">-</td>
<td>172</td><td>78.0</td><td>26.4</td><td>24.5</td><td class="th-divider">92</td>
<td>-</td><td>-</td><td>-</td><td class="th-divider">-</td>
<td>77.5</td><td>26.2</td><td>24.0</td><td class="th-divider">91</td>
<td class="change-down">-0.5</td><td class="change-down">-0.2</td><td class="change-down">-0.5</td><td class="change-down">-1</td>
<td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10101">查看</a></td>
</tr>
<tr>
<td class="col-fixed-l1">周婷</td><td class="col-fixed-l2">EMP-10102</td><td></td><td>33</td><td>采油二厂</td><td>安全环保科</td>
<td>-</td><td class="th-divider">-</td>
<td>158</td><td>65.2</td><td>26.1</td><td>31.0</td><td class="th-divider">80</td>
<td>-</td><td>-</td><td>-</td><td class="th-divider">-</td>
<td>64.5</td><td>25.8</td><td>30.2</td><td class="th-divider">78</td>
<td class="change-down">-0.7</td><td class="change-down">-0.3</td><td class="change-down">-0.8</td><td class="change-down">-2</td>
<td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10102">查看</a></td>
</tr>
<tr>
<td class="col-fixed-l1">吴刚</td><td class="col-fixed-l2">EMP-10103</td><td></td><td>45</td><td>采气厂</td><td>综合管理科</td>
<td>-</td><td class="th-divider">-</td>
<td>168</td><td>90.5</td><td>32.1</td><td>33.5</td><td class="th-divider">108</td>
<td>-</td><td>-</td><td>-</td><td class="th-divider">-</td>
<td>91.2</td><td>32.3</td><td>34.2</td><td class="th-divider">110</td>
<td class="change-up">+0.7</td><td class="change-up">+0.2</td><td class="change-up">+0.7</td><td class="change-up">+2</td>
<td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10103">查看</a></td>
</tr>
<tr>
<td class="col-fixed-l1">陈静</td><td class="col-fixed-l2">EMP-10104</td><td></td><td>26</td><td>采油一厂</td><td>综合管理科</td>
<td>-</td><td class="th-divider">-</td>
<td>165</td><td>58.0</td><td>21.3</td><td>25.0</td><td class="th-divider">72</td>
<td>-</td><td>-</td><td>-</td><td class="th-divider">-</td>
<td>57.3</td><td>21.0</td><td>24.2</td><td class="th-divider">71</td>
<td class="change-down">-0.7</td><td class="change-down">-0.3</td><td class="change-down">-0.8</td><td class="change-down">-1</td>
<td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10104">查看</a></td>
</tr>
<tr>
<td class="col-fixed-l1">郑飞</td><td class="col-fixed-l2">EMP-10105</td><td></td><td>40</td><td>采油二厂</td><td>生产运行科</td>
<td>-</td><td class="th-divider">-</td>
<td>175</td><td>86.2</td><td>28.1</td><td>28.5</td><td class="th-divider">98</td>
<td>-</td><td>-</td><td>-</td><td class="th-divider">-</td>
<td>85.5</td><td>27.9</td><td>28.0</td><td class="th-divider">96</td>
<td class="change-down">-0.7</td><td class="change-down">-0.2</td><td class="change-down">-0.5</td><td class="change-down">-2</td>
<td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10105">查看</a></td>
</tr>
</tbody>
</table>
</div>
<!-- [交互] 操作按钮 -->
<div class="action-bar">
<button class="btn btn-default">导出列表数据</button>
<button class="btn btn-default">查看导出任务</button>
</div>
<!-- 数据列表 -->
<div class="table-card">
<div class="table-card__content">
<table style="min-width:1100px;">
<thead>
<tr>
<th class="col-fixed-l1">姓名</th>
<th class="col-fixed-l2">员工编号</th>
<th>性别</th>
<th>年龄</th>
<th>单位</th>
<th>部门</th>
<th>身高(cm)</th>
<th>初始体重(kg)</th>
<th>初始BMI</th>
<th>初始体脂(%)</th>
<th>初始腰围(cm)</th>
<th class="col-fixed-r">详细数据</th>
</tr>
</thead>
<tbody>
<tr><td class="col-fixed-l1">孙磊</td><td class="col-fixed-l2">EMP-10101</td><td></td><td>29</td><td>采油一厂</td><td>生产运行科</td><td>172</td><td>78.0</td><td>26.4</td><td>24.5</td><td>92</td><td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10101&tab=noTarget">查看</a></td></tr>
<tr><td class="col-fixed-l1">周婷</td><td class="col-fixed-l2">EMP-10102</td><td></td><td>33</td><td>采油二厂</td><td>安全环保科</td><td>158</td><td>65.2</td><td>26.1</td><td>31.0</td><td>80</td><td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10102&tab=noTarget">查看</a></td></tr>
<tr><td class="col-fixed-l1">吴刚</td><td class="col-fixed-l2">EMP-10103</td><td></td><td>45</td><td>采气厂</td><td>综合管理科</td><td>168</td><td>90.5</td><td>32.1</td><td>33.5</td><td>108</td><td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10103&tab=noTarget">查看</a></td></tr>
<tr><td class="col-fixed-l1">陈静</td><td class="col-fixed-l2">EMP-10104</td><td></td><td>26</td><td>采油一厂</td><td>综合管理科</td><td>165</td><td>58.0</td><td>21.3</td><td>25.0</td><td>72</td><td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10104&tab=noTarget">查看</a></td></tr>
<tr><td class="col-fixed-l1">郑飞</td><td class="col-fixed-l2">EMP-10105</td><td></td><td>40</td><td>采油二厂</td><td>生产运行科</td><td>175</td><td>86.2</td><td>28.1</td><td>28.5</td><td>98</td><td class="col-fixed-r"><a class="btn-link" href="personal-target-detail.html?empId=EMP-10105&tab=noTarget">查看</a></td></tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>共 42 条</span>
<button class="page-btn"></button>
<button class="page-btn active">1</button>
<button class="page-btn">2</button>
<button class="page-btn">3</button>
<button class="page-btn">...</button>
<button class="page-btn">5</button>
<button class="page-btn"></button>
</div>
<div class="pagination">
<span>共 198 条</span>
<button class="page-btn"></button>
<button class="page-btn active">1</button>
<button class="page-btn">2</button>
<button class="page-btn">3</button>
<button class="page-btn">...</button>
<button class="page-btn">20</button>
<button class="page-btn"></button>
</div>
</div>
</main>
<script>
/* [交互] Tab 切换:点击 tab 按钮切换显示对应的 tab-panel */
function switchTab(index) {
document.querySelectorAll('.tab-item').forEach(function(el, i) {
el.classList.toggle('active', i === index);
});
document.querySelectorAll('.tab-panel').forEach(function(el, i) {
el.classList.toggle('active', i === index);
});
}
/* ———— 单位部门双列面板交互 ———— */
/* 部门映射数据:选中左侧单位后,右侧部门动态加载 */
@@ -355,78 +297,72 @@ var deptMap = {
'采气厂': ['安全生产科', '综合管理科', '信息中心']
};
/* 每个tab实例的选中状态 */
var orgState = [
{ unitName: '', unitCode: '', deptName: '', deptCode: '' },
{ unitName: '', unitCode: '', deptName: '', deptCode: '' }
];
/* 选中状态 */
var orgState = { unitName: '', unitCode: '', deptName: '', deptCode: '' };
/* [交互] 展开/收起单位部门双列面板 */
function toggleOrg(tabIdx) {
var panel = document.getElementById('orgPanel' + tabIdx);
var trigger = document.getElementById('orgTrigger' + tabIdx);
var isOpen = panel.classList.contains('open');
function toggleOrg() {
var panel = document.getElementById('orgPanel');
var trigger = document.getElementById('orgTrigger');
panel.classList.toggle('open');
trigger.classList.toggle('open');
}
/* [交互] 选择左侧单位 → 右侧部门列表联动刷新,选中"全部"则清空部门 */
function selectUnit(tabIdx, elem, unitName, unitCode) {
document.querySelectorAll('#orgUnitCol' + tabIdx + ' .org-item').forEach(function(item) {
function selectUnit(elem, unitName, unitCode) {
document.querySelectorAll('#orgUnitCol .org-item').forEach(function(item) {
item.classList.remove('active');
});
elem.classList.add('active');
orgState[tabIdx].unitName = unitName;
orgState[tabIdx].unitCode = unitCode;
orgState.unitName = unitName;
orgState.unitCode = unitCode;
// 更新右侧部门列表
var depts = deptMap[unitCode] || [];
var html = '<div class="org-col__title">部门</div>';
html += '<div class="org-item active" data-dept="" onclick="selectDept(' + tabIdx + ', this, \'全部部门\', \'\')">全部部门</div>';
html += '<div class="org-item active" data-dept="" onclick="selectDept(this, \'全部部门\', \'\')">全部部门</div>';
depts.forEach(function(d) {
html += '<div class="org-item" data-dept="' + d + '" onclick="selectDept(' + tabIdx + ', this, \'' + d + '\', \'' + d + '\')">' + d + '</div>';
html += '<div class="org-item" data-dept="' + d + '" onclick="selectDept(this, \'' + d + '\', \'' + d + '\')">' + d + '</div>';
});
document.getElementById('orgDeptCol' + tabIdx).innerHTML = html;
orgState[tabIdx].deptName = '';
orgState[tabIdx].deptCode = '';
document.getElementById('orgDeptCol').innerHTML = html;
orgState.deptName = '';
orgState.deptCode = '';
// 更新触发器文本
var label = unitCode ? unitName : '全部单位';
label += ' / 全部部门';
document.getElementById('orgTrigger' + tabIdx).textContent = label;
document.getElementById('orgTrigger').textContent = label;
}
/* [交互] 选择右侧部门 → 更新触发器文本并关闭面板 */
function selectDept(tabIdx, elem, deptName, deptCode) {
document.querySelectorAll('#orgDeptCol' + tabIdx + ' .org-item').forEach(function(item) {
function selectDept(elem, deptName, deptCode) {
document.querySelectorAll('#orgDeptCol .org-item').forEach(function(item) {
item.classList.remove('active');
});
elem.classList.add('active');
orgState[tabIdx].deptName = deptName;
orgState[tabIdx].deptCode = deptCode;
orgState.deptName = deptName;
orgState.deptCode = deptCode;
// 更新触发器文本
var label = orgState[tabIdx].unitCode ? orgState[tabIdx].unitName : '全部单位';
var label = orgState.unitCode ? orgState.unitName : '全部单位';
if (deptCode) {
label += ' / ' + deptName;
} else {
label += ' / 全部部门';
}
document.getElementById('orgTrigger' + tabIdx).textContent = label;
document.getElementById('orgTrigger').textContent = label;
// 关闭面板
document.getElementById('orgPanel' + tabIdx).classList.remove('open');
document.getElementById('orgTrigger' + tabIdx).classList.remove('open');
document.getElementById('orgPanel').classList.remove('open');
document.getElementById('orgTrigger').classList.remove('open');
}
/* [交互] 点击面板外部区域关闭 */
document.addEventListener('click', function(e) {
for (var i = 0; i < 2; i++) {
var orgWrap = document.getElementById('orgWrap' + i);
if (orgWrap && !orgWrap.contains(e.target)) {
document.getElementById('orgPanel' + i).classList.remove('open');
document.getElementById('orgTrigger' + i).classList.remove('open');
}
var orgWrap = document.getElementById('orgWrap');
if (orgWrap && !orgWrap.contains(e.target)) {
document.getElementById('orgPanel').classList.remove('open');
document.getElementById('orgTrigger').classList.remove('open');
}
});
</script>
@@ -51,15 +51,14 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
/* 顶部三列信息卡片 */
.overview-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);margin-bottom:16px;display:flex;}
.overview-card__col{padding:12px 20px;}
.overview-card__col--left{width:200px;flex-shrink:0;border-right:1px solid var(--border);}
.overview-card__col--mid{flex:1;border-right:1px solid var(--border);display:flex;flex-direction:column;}
.overview-card__col--right{width:200px;flex-shrink:0;}
.overview-card__col{padding:16px 20px;min-width:0;}
.overview-card__col--left{flex:1;border-right:1px solid var(--border);}
.overview-card__col--mid{flex:1.3;border-right:1px solid var(--border);display:flex;flex-direction:column;}
.overview-card__col--right{flex:1;}
.overview-card__title{font-size:var(--font-sm);font-weight:600;color:var(--text-primary);margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid #F0F0F0;}
.overview-card__name{font-size:var(--font-base);font-weight:600;color:var(--text-primary);margin-bottom:8px;}
.overview-card__info-list{display:flex;flex-direction:column;gap:6px;}
.overview-card__info-row{display:flex;font-size:var(--font-sm);}
.overview-card__info-label{color:var(--text-secondary);width:65px;flex-shrink:0;}
.overview-card__name{font-size:var(--font-lg);font-weight:600;color:var(--text-primary);margin-bottom:10px;}
.overview-card__info-grid{display:grid;grid-template-columns:auto 1fr auto 1fr;gap:6px 12px;font-size:var(--font-sm);}
.overview-card__info-label{color:var(--text-secondary);white-space:nowrap;}
.overview-card__info-value{color:var(--text-primary);}
/* 中列:计划下拉 + 初始/目标/现三列指标 */
@@ -82,15 +81,16 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
.overview-card__metrics-value{font-weight:600;}
.overview-card__metrics-unit{font-size:var(--font-xs);color:var(--text-placeholder);}
/* 右列:累计天数 */
.overview-card__stat-list{display:flex;flex-direction:column;gap:12px;}
.overview-card__stat-item{display:flex;align-items:center;gap:12px;}
.overview-card__stat-icon{width:38px;height:38px;border-radius:var(--radius-sm);display:flex;align-items:center;justify-content:center;flex-shrink:0;}
/* 右列:累计天数 — 单行三列 */
.overview-card__stat-list{display:flex;flex-direction:row;gap:0;flex:1;align-items:center;}
.overview-card__stat-item{flex:1;display:flex;flex-direction:column;align-items:center;gap:8px;}
.overview-card__stat-icon{width:44px;height:44px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0;}
.overview-card__stat-icon svg{width:22px;height:22px;}
.overview-card__stat-icon--diet{background:#E6F7FF;color:var(--primary);}
.overview-card__stat-icon--exercise{background:#F6FFED;color:var(--success);}
.overview-card__stat-icon--weight{background:#FFF7E6;color:var(--warning);}
.overview-card__stat-body{display:flex;flex-direction:column;}
.overview-card__stat-val{font-size:20px;font-weight:700;color:var(--text-primary);line-height:1.2;}
.overview-card__stat-body{display:flex;flex-direction:column;align-items:center;gap:2px;}
.overview-card__stat-val{font-size:22px;font-weight:700;color:var(--text-primary);line-height:1.2;}
.overview-card__stat-label{font-size:var(--font-xs);color:var(--text-secondary);}
/* 搜索下拉(干预计划选择) */
@@ -110,6 +110,18 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
.search-select__clear.show{display:flex;}
.search-select--selected .search-select__input{background-image:none;padding-right:32px;}
/* 指标对比卡片 */
.metrics-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:20px 24px;margin-bottom:16px;}
.metrics-card__title{font-size:var(--font-base);font-weight:600;color:var(--text-primary);margin-bottom:16px;}
.metrics-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;}
.metric-group{background:#FAFAFA;border-radius:var(--radius-sm);padding:14px 16px;text-align:center;}
.metric-group__label{font-size:var(--font-xs);color:var(--text-secondary);margin-bottom:8px;}
.metric-row{display:flex;justify-content:center;align-items:center;gap:0;font-size:var(--font-xs);color:var(--text-primary);}
.metric-row__item{flex:1;display:flex;flex-direction:column;align-items:center;gap:2px;}
.metric-row__val{font-size:var(--font-base);font-weight:600;color:var(--text-primary);}
.metric-row__sub{font-size:var(--font-xs);color:var(--text-placeholder);}
.metric-arrow{font-size:var(--font-sm);color:var(--text-placeholder);margin:0 4px;}
/* 筛选栏 */
.filter-bar{background:#fff;padding:16px 24px;display:flex;align-items:center;gap:12px;flex-wrap:wrap;border-radius:var(--radius-md) var(--radius-md) 0 0;box-shadow:var(--shadow-sm);}
.filter-item{display:flex;align-items:center;gap:8px;}
@@ -195,12 +207,12 @@ tbody tr:hover{background:#F8FBFF;}
<div class="overview-card__col overview-card__col--left">
<div class="overview-card__title">个人信息</div>
<div class="overview-card__name" id="empName">-</div>
<div class="overview-card__info-list">
<div class="overview-card__info-row"><span class="overview-card__info-label">员工编号</span><span class="overview-card__info-value" id="empCode">-</span></div>
<div class="overview-card__info-row"><span class="overview-card__info-label">性别</span><span class="overview-card__info-value" id="empGender">-</span></div>
<div class="overview-card__info-row"><span class="overview-card__info-label">年龄</span><span class="overview-card__info-value" id="empAge">-</span></div>
<div class="overview-card__info-row"><span class="overview-card__info-label">单位</span><span class="overview-card__info-value" id="empOrg">-</span></div>
<div class="overview-card__info-row"><span class="overview-card__info-label">部门</span><span class="overview-card__info-value" id="empDept">-</span></div>
<div class="overview-card__info-grid">
<span class="overview-card__info-label">员工编号</span><span class="overview-card__info-value" id="empCode">-</span>
<span class="overview-card__info-label">性别</span><span class="overview-card__info-value" id="empGender">-</span>
<span class="overview-card__info-label">年龄</span><span class="overview-card__info-value" id="empAge">-</span>
<span class="overview-card__info-label">单位</span><span class="overview-card__info-value" id="empOrg">-</span>
<span class="overview-card__info-label">部门</span><span class="overview-card__info-value" id="empDept">-</span>
</div>
</div>
<!-- 中列:个人目标信息 + 干预计划下拉 -->
@@ -226,15 +238,6 @@ tbody tr:hover{background:#F8FBFF;}
</div>
</div>
<div class="overview-card__metrics-row">
<div class="overview-card__metrics-col">
<div class="overview-card__metrics-title">初始指标</div>
<div class="overview-card__metrics-line">
<div class="overview-card__metric"><span class="overview-card__metric-val" id="initWeight">-</span><span class="overview-card__metric-label">体重</span></div>
<div class="overview-card__metric"><span class="overview-card__metric-val" id="initBmi">-</span><span class="overview-card__metric-label">BMI</span></div>
<div class="overview-card__metric"><span class="overview-card__metric-val" id="initFat">-</span><span class="overview-card__metric-label">体脂率</span></div>
<div class="overview-card__metric"><span class="overview-card__metric-val" id="initWaist">-</span><span class="overview-card__metric-label">腰围</span></div>
</div>
</div>
<div class="overview-card__metrics-col">
<div class="overview-card__metrics-title">目标指标</div>
<div class="overview-card__metrics-line">
@@ -244,51 +247,9 @@ tbody tr:hover{background:#F8FBFF;}
<div class="overview-card__metric"><span class="overview-card__metric-val" id="tgWaist">-</span><span class="overview-card__metric-label">腰围</span></div>
</div>
</div>
<div class="overview-card__metrics-col">
<div class="overview-card__metrics-title">最新指标</div>
<div class="overview-card__metrics-line">
<div class="overview-card__metric"><span class="overview-card__metric-val" id="curWeight">-</span><span class="overview-card__metric-label">体重</span></div>
<div class="overview-card__metric"><span class="overview-card__metric-val" id="curBmi">-</span><span class="overview-card__metric-label">BMI</span></div>
<div class="overview-card__metric"><span class="overview-card__metric-val" id="curFat">-</span><span class="overview-card__metric-label">体脂率</span></div>
<div class="overview-card__metric"><span class="overview-card__metric-val" id="curWaist">-</span><span class="overview-card__metric-label">腰围</span></div>
</div>
</div>
</div>
</div><!-- /targetContent -->
</div>
<!-- 右列:累计记录天数 -->
<div class="overview-card__col overview-card__col--right">
<div class="overview-card__title">累计记录天数</div>
<div class="overview-card__stat-list">
<div class="overview-card__stat-item">
<div class="overview-card__stat-icon overview-card__stat-icon--diet">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><rect x="3" y="2" width="18" height="20" rx="2" stroke="currentColor" stroke-width="1.5"/><path d="M3 8h18" stroke="currentColor" stroke-width="1.5"/><path d="M8 12h2M14 12h2M8 16h2M14 16h2" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
</div>
<div class="overview-card__stat-body">
<span class="overview-card__stat-val" id="dietDays">0</span>
<span class="overview-card__stat-label">饮食记录天数</span>
</div>
</div>
<div class="overview-card__stat-item">
<div class="overview-card__stat-icon overview-card__stat-icon--exercise">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="1.5"/><path d="M8 12h8M12 8v8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
</div>
<div class="overview-card__stat-body">
<span class="overview-card__stat-val" id="exerciseDays">0</span>
<span class="overview-card__stat-label">运动记录天数</span>
</div>
</div>
<div class="overview-card__stat-item">
<div class="overview-card__stat-icon overview-card__stat-icon--weight">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"><rect x="4" y="2" width="16" height="20" rx="2" stroke="currentColor" stroke-width="1.5"/><path d="M8 8h4M8 12h4M8 16h8" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>
</div>
<div class="overview-card__stat-body">
<span class="overview-card__stat-val" id="weightDays">0</span>
<span class="overview-card__stat-label">体重记录天数</span>
</div>
</div>
</div>
</div>
</div>
<!-- [交互] 筛选栏 — 日期范围(默认当日)、查询/重置 -->
@@ -304,6 +265,12 @@ tbody tr:hover{background:#F8FBFF;}
<button class="btn btn-default" onclick="resetFilter()">重置</button>
</div>
<!-- 指标对比卡片:初始指标 → 当前指标 → 变化 -->
<div class="metrics-card">
<div class="metrics-card__title">体重管理指标变化</div>
<div class="metrics-grid" id="metricsGrid"></div>
</div>
<!-- [交互] 操作按钮区 -->
<div class="action-bar">
<button class="btn btn-export" onclick="showToast('导出列表数据功能开发中')">
@@ -440,22 +407,7 @@ function buildDailyData(emp, target){
/* ===== 计算行动累计 ===== */
function updateSummaryCards(){
if(!dailyData.length){
document.getElementById('dietDays').textContent = '0';
document.getElementById('exerciseDays').textContent = '0';
document.getElementById('weightDays').textContent = '0';
return;
}
var currentFiltered = getFilteredData();
var dietCount = 0, exerciseCount = 0, weightCount = 0;
currentFiltered.forEach(function(d){
if(d.dietKcal > 0) dietCount++;
if(d.exerciseKcal > 0) exerciseCount++;
if(d.weight > 0) weightCount++;
});
document.getElementById('dietDays').textContent = dietCount;
document.getElementById('exerciseDays').textContent = exerciseCount;
document.getElementById('weightDays').textContent = weightCount;
// 累计记录天数已移除
}
/* ===== 渲染员工信息卡片 ===== */
@@ -500,6 +452,44 @@ function showPlanPanel(){
document.getElementById('planPanel').classList.add('show');
}
/* ===== 渲染指标对比卡片 ===== */
function renderMetricsCard(){
if(!currentEmployee) return;
var latest = dailyData.length ? dailyData[dailyData.length - 1] : null;
var metrics = [
{label:'体重(kg)', init:currentEmployee.weight, cur:latest ? latest.weight : null},
{label:'BMI', init:currentEmployee.bmi, cur:latest ? latest.bmi : null},
{label:'体脂率(%)', init:currentEmployee.fat, cur:latest ? latest.fat : null},
{label:'腰围(cm)', init:currentEmployee.waist, cur:latest ? latest.waist : null}
];
var html = '';
metrics.forEach(function(m){
var hasCur = m.cur !== null && m.cur !== undefined;
var change = hasCur ? (m.cur - m.init) : null;
var cls = '';
var sign = '';
var changeText = '-';
if(hasCur && change !== null){
cls = change < 0 ? 'change-down' : (change > 0 ? 'change-up' : 'change-zero');
sign = change > 0 ? '+' : '';
changeText = sign + change.toFixed(1);
}
html += '<div class="metric-group">';
html += '<div class="metric-group__label">'+m.label+'</div>';
html += '<div class="metric-row">';
html += '<div class="metric-row__item"><span class="metric-row__sub">初始</span><span class="metric-row__val">'+m.init.toFixed(1)+'</span></div>';
html += '<span class="metric-arrow"></span>';
html += '<div class="metric-row__item"><span class="metric-row__sub">当前</span><span class="metric-row__val">'+(hasCur ? m.cur.toFixed(1) : '-')+'</span></div>';
html += '<span class="metric-arrow"></span>';
html += '<div class="metric-row__item"><span class="metric-row__sub">变化</span><span class="metric-row__val '+cls+'">'+changeText+'</span></div>';
html += '</div></div>';
});
document.getElementById('metricsGrid').innerHTML = html;
}
/* [交互] 选中个人目标 → 更新目标指标 */
function selectPlan(targetId){
selectedPlanId = targetId;
@@ -528,11 +518,10 @@ function selectPlan(targetId){
statusEl.className = 'plan-status plan-status--active';
}
// 初始指标(来自员工档案)
document.getElementById('initWeight').innerHTML = currentEmployee.weight + '<span class="unit">kg</span>';
document.getElementById('initBmi').textContent = currentEmployee.bmi;
document.getElementById('initFat').innerHTML = currentEmployee.fat + '<span class="unit">%</span>';
document.getElementById('initWaist').innerHTML = currentEmployee.waist + '<span class="unit">cm</span>';
// 日期范围自动代入目标起止日期
document.getElementById('filterDateFrom').value = target.dateFrom;
document.getElementById('filterDateTo').value = target.dateTo;
// 目标指标
document.getElementById('tgWeight').innerHTML = target.targetWeight + '<span class="unit">kg</span>';
document.getElementById('tgBmi').textContent = target.targetBmi;
@@ -543,8 +532,8 @@ function selectPlan(targetId){
dailyData = buildDailyData(currentEmployee, target);
currentPage = 0;
applyFilter();
// 现指标取最新一条数据
updateCurrentMetrics();
// 更新指标对比卡片
renderMetricsCard();
}
/* [交互] 清空已选目标 */
@@ -555,31 +544,17 @@ function clearPlan(){
document.getElementById('planSelect').classList.remove('search-select--selected');
document.getElementById('planPanel').classList.remove('show');
document.getElementById('planDateInfo').style.display = 'none';
document.getElementById('initWeight').textContent = '-';
document.getElementById('initBmi').textContent = '-';
document.getElementById('initFat').textContent = '-';
document.getElementById('initWaist').textContent = '-';
document.getElementById('tgWeight').textContent = '-';
document.getElementById('tgBmi').textContent = '-';
document.getElementById('tgFat').textContent = '-';
document.getElementById('tgWaist').textContent = '-';
document.getElementById('curWeight').textContent = '-';
document.getElementById('curBmi').textContent = '-';
document.getElementById('curFat').textContent = '-';
document.getElementById('curWaist').textContent = '-';
// 重置日期筛选
document.getElementById('filterDateFrom').value = '';
document.getElementById('filterDateTo').value = '';
dailyData = [];
currentPage = 0;
applyFilter();
}
/* ===== 更新现指标(取最新一条数据) ===== */
function updateCurrentMetrics(){
if(!dailyData.length) return;
var latest = dailyData[dailyData.length - 1];
document.getElementById('curWeight').innerHTML = latest.weight + '<span class="unit">kg</span>';
document.getElementById('curBmi').textContent = latest.bmi;
document.getElementById('curFat').innerHTML = latest.fat + '<span class="unit">%</span>';
document.getElementById('curWaist').innerHTML = latest.waist + '<span class="unit">cm</span>';
renderMetricsCard();
}
/* ===== 筛选 ===== */
@@ -671,18 +646,20 @@ document.addEventListener('click',function(e){
(function init(){
var empId = getParam('empId');
var targetId = getParam('targetId');
var tab = getParam('tab');
// 查找员工
currentEmployee = allEmployees.find(function(e){return e.empId === empId;}) || allEmployees[0];
// 根据员工是否设置了目标来判断显示模式
var hasTarget = currentEmployee.targetIds && currentEmployee.targetIds.length > 0;
// 未设置目标:显示缺省样式,隐藏目标内容区
if(tab === 'noTarget'){
if(!hasTarget){
document.getElementById('targetContent').style.display = 'none';
var emptyEl = document.getElementById('targetEmpty');
emptyEl.style.display = 'flex';
}
// 查找员工
currentEmployee = allEmployees.find(function(e){return e.empId === empId;}) || allEmployees[0];
// 渲染员工信息
renderEmployeeCard();
@@ -696,12 +673,13 @@ document.addEventListener('click',function(e){
});
document.getElementById('planPanel').innerHTML = html;
// 默认选中员工第一个目标(未设置目标时生成无目标数据
if(tab === 'noTarget'){
// 未设置目标时生成无目标数据;否则默认选中员工第一个目标
if(!hasTarget){
dailyData = buildDailyData(currentEmployee, null);
applyFilter();
renderMetricsCard();
} else {
var defaultTargetId = targetId ? parseInt(targetId) : (currentEmployee.targetIds && currentEmployee.targetIds.length ? currentEmployee.targetIds[0] : targets[0].id);
var defaultTargetId = targetId ? parseInt(targetId) : currentEmployee.targetIds[0];
if(defaultTargetId){
selectPlan(defaultTargetId);
}
@@ -266,9 +266,9 @@ tbody tr:hover{background:#F8FBFF;}
<aside class="sidebar">
<div class="sidebar-menu__title">过程管理</div>
<a href="action-record.html" class="sidebar-item">行动记录</a>
<a href="action-overview.html" class="sidebar-item">活动总览</a>
<a href="detail-data.html" class="sidebar-item">详细数据</a>
<a href="weight-ranking.html" class="sidebar-item active">体重排名</a>
<a href="action-overview.html" class="sidebar-item">活动总览</a>
<a href="activity-statistics.html" class="sidebar-item">活动统计</a>
</aside>