docs: 健康监测模块PRD文档与页面优化

- 生成web-admin健康监测PRD文档(81页)及全量截图
- 生成employee-app健康监测PRD文档(28页)及全量截图
- 修复archive-unit.html表头重复和统计行列数不对齐问题
- 重构archive-algorithm.html匹配实际设计稿
- 更新index.html导航页添加健康监测PRD链接和完成状态
- 优化多个二级详情页面的筛选条件和表格结构

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-26 20:53:09 +08:00
co-authored by Claude Opus 4.6
parent adbf247ea2
commit 104016f07a
124 changed files with 2286 additions and 299 deletions
+112 -6
View File
@@ -40,9 +40,36 @@
.sidebar-subgroup.open>.sidebar-subgroup__body{display:block;}
.sidebar-subgroup__body .sidebar-item{padding-left:36px;font-size:12px;}
.main{margin-left:240px;margin-top:56px;padding:24px;min-height:calc(100vh - 56px);}
.page-placeholder{display:flex;flex-direction:column;align-items:center;justify-content:center;height:calc(100vh - 56px - 48px);color:var(--text-placeholder);gap:12px;}
.page-placeholder svg{opacity:.25;}
.page-placeholder p{font-size:var(--font-base);}
/* 筛选栏 */
.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-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-input:focus{border-color:var(--primary);}
/* 按钮 */
.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);}
.btn-danger-link{background:none;border:none;color:var(--danger);cursor:pointer;font-size:var(--font-sm);padding:0 4px;}
.btn-danger-link:hover{color:#ff7875;}
/* 操作栏 */
.action-bar{display:flex;align-items:center;gap:8px;margin-bottom:16px;}
/* 表格卡片 */
.table-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);overflow:hidden;}
.table-card__content{overflow-x:auto;overflow-y:hidden;}
.table-card__content table{min-width:100%;white-space:nowrap;}
table{width:100%;border-collapse:collapse;}
thead th{background:#FAFAFA;padding:12px 16px;text-align:left;font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);white-space:nowrap;}
tbody td{padding:14px 16px;font-size:var(--font-sm);color:var(--text-primary);border-bottom:1px solid var(--border);white-space:nowrap;}
tbody tr:last-child td{border-bottom:none;}
tbody tr:hover{background:#F8FBFF;}
/* 链接 */
.link{color:var(--primary);cursor:pointer;font-size:var(--font-sm);text-decoration:none;}.link:hover{color:#40a9ff;}
/* 分页 */
.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);}
</style>
</head>
<body>
@@ -72,9 +99,88 @@
<a href="archive-algorithm.html" class="sidebar-item active">算法模型</a>
</aside>
<main class="main">
<div class="page-placeholder">
<svg width="64" height="64" viewBox="0 0 64 64" fill="none"><rect x="8" y="8" width="48" height="48" rx="8" stroke="#ccc" stroke-width="2"/><path d="M20 32h24M32 20v24" stroke="#ccc" stroke-width="2" stroke-linecap="round"/></svg>
<p>算法模型</p>
<!-- 筛选栏 -->
<div class="filter-bar">
<div class="filter-item">
<label>文档名称</label>
<input class="filter-input" type="text" placeholder="请输入文档名称">
</div>
<div class="filter-item">
<label>制作年份</label>
<input class="filter-input" type="text" 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-primary"><svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M7 2v10M2 7h10" stroke="#fff" stroke-width="1.4" stroke-linecap="round"/></svg>新增</button>
<button class="btn btn-default"><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"><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>序号</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>测试PDF</td>
<td>测试PDF预览</td>
<td>研发</td>
<td>研发人员</td>
<td>2023</td>
<td>2026-04-17 13:36:34</td>
<td><a class="link">预览</a>&nbsp;&nbsp;<a class="link">下载</a></td>
<td><a class="link">编辑</a>&nbsp;&nbsp;<a class="btn-danger-link">删除</a></td>
</tr>
<tr>
<td>2</td>
<td>预览WORD</td>
<td>测试的</td>
<td>家里</td>
<td>张老师</td>
<td>2025</td>
<td>2026-04-17 13:06:38</td>
<td><a class="link">预览</a>&nbsp;&nbsp;<a class="link">下载</a></td>
<td><a class="link">编辑</a>&nbsp;&nbsp;<a class="btn-danger-link">删除</a></td>
</tr>
<tr>
<td>3</td>
<td>心理算法</td>
<td>心理算法模型</td>
<td>交大</td>
<td>王老师</td>
<td>2025</td>
<td>2026-04-15 16:46:54</td>
<td><a class="link">预览</a>&nbsp;&nbsp;<a class="link">下载</a></td>
<td><a class="link">编辑</a>&nbsp;&nbsp;<a class="btn-danger-link">删除</a></td>
</tr>
</tbody>
</table>
</div>
<!-- 分页 -->
<div class="pagination">
<span>总共 3 条数据</span>
<button class="page-btn"></button>
<button class="page-btn active">1</button>
<button class="page-btn"></button>
</div>
</div>
</main>
<script>function toggleSubgroup(h){h.parentElement.classList.toggle('open');}(function(){var a=document.querySelector('.sidebar-item.active');if(!a)return;var s=a.closest('.sidebar-subgroup');if(s)s.classList.add('open');})();</script>
+37 -81
View File
@@ -68,7 +68,7 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
.table-card__title{font-size:var(--font-base);font-weight:600;}
.table-card__content{overflow-x:auto;-webkit-overflow-scrolling:touch;}
table{width:100%;border-collapse:collapse;min-width:100%;white-space:nowrap;}
thead th{background:#FAFAFA;padding:12px 16px;text-align:left;font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);white-space:nowrap;}
thead th{background:#FAFAFA;padding:12px 16px;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:14px 16px;font-size:var(--font-sm);color:var(--text-primary);border-bottom:1px solid var(--border);white-space:nowrap;}
tbody tr:last-child td{border-bottom:none;}
tbody tr:hover{background:#F8FBFF;}
@@ -119,46 +119,14 @@ tbody tr:hover{background:#F8FBFF;}
<!-- 主内容区 -->
<div class="main">
<!-- 统计卡片 -->
<div class="stats-row">
<div class="stat-card">
<div class="stat-card__icon blue">👤</div>
<div class="stat-card__info">
<div class="stat-card__value">1,280</div>
<div class="stat-card__label">监控员工总数</div>
</div>
</div>
<div class="stat-card">
<div class="stat-card__icon green"></div>
<div class="stat-card__info">
<div class="stat-card__value">1,156</div>
<div class="stat-card__label">健康排查完成人数</div>
</div>
</div>
<div class="stat-card">
<div class="stat-card__icon orange"></div>
<div class="stat-card__info">
<div class="stat-card__value">892</div>
<div class="stat-card__label">穿戴监测覆盖人数</div>
</div>
</div>
<div class="stat-card">
<div class="stat-card__icon green">⚖️</div>
<div class="stat-card__info">
<div class="stat-card__value">756</div>
<div class="stat-card__label">体重监测覆盖人数</div>
</div>
</div>
</div>
<!-- 筛选栏 -->
<div class="filter-bar">
<div class="filter-item">
<label>姓名/</label>
<label>姓名/员工编</label>
<input class="filter-input" type="text" placeholder="请输入姓名或工号">
</div>
<div class="filter-item">
<label>所属单位</label>
<label>单位部门</label>
<select class="filter-select">
<option>全部</option>
<option>长庆油田总部</option>
@@ -167,17 +135,6 @@ tbody tr:hover{background:#F8FBFF;}
<option>采气一厂</option>
</select>
</div>
<div class="filter-item">
<label>所属部门</label>
<select class="filter-select">
<option>全部</option>
<option>研发部</option>
<option>市场部</option>
<option>运营部</option>
<option>财务部</option>
<option>人事部</option>
</select>
</div>
<div class="filter-item">
<label>年份</label>
<select class="filter-select">
@@ -205,21 +162,25 @@ tbody tr:hover{background:#F8FBFF;}
<table>
<thead>
<tr>
<th>姓名</th>
<th></th>
<th>所属单位</th>
<th>所属部门</th>
<th>健康排查-积分</th>
<th>健康排查-连续签到天数</th>
<th>穿戴监测-已绑定</th>
<th>穿戴监测-异常次数</th>
<th>体重监测-最初体重(kg)</th>
<th>体重监测-最初BMI</th>
<th>体重监测-最终体重(kg)</th>
<th>体重监测-最终BMI</th>
<th>体重监测-体重变化(kg)</th>
<th>体重监测-BMI变化</th>
<th>操作</th>
<th rowspan="2">姓名</th>
<th rowspan="2">员工编</th>
<th rowspan="2">所属单位</th>
<th rowspan="2">所属部门</th>
<th colspan="2">健康排查</th>
<th colspan="2">穿戴监测</th>
<th colspan="6">体重监测</th>
</tr>
<tr>
<th>积分 ↕</th>
<th>连续签到天数 ↕</th>
<th>绑定设备 ↕</th>
<th>异常次数 ↕</th>
<th>最初体重(kg) ↕</th>
<th>最终体重(kg) ↕</th>
<th>体重变化(kg) ↕</th>
<th>最初BMI ↕</th>
<th>最终BMI ↕</th>
<th>BMI变化 ↕</th>
</tr>
</thead>
<tbody>
@@ -227,36 +188,31 @@ tbody tr:hover{background:#F8FBFF;}
<td>张伟</td><td>EMP001</td><td>长庆油田总部</td><td>研发部</td>
<td>92</td><td>128</td>
<td><span class="tag tag-green"></span></td><td>2</td>
<td>72.5</td><td>24.1</td><td>70.2</td><td>23.4</td><td>-2.3</td><td>-0.7</td>
<td><a class="link" href="#">查看详情</a></td>
<td>72.5</td><td>70.2</td><td>-2.3</td><td>24.1</td><td>23.4</td><td>-0.7</td>
</tr>
<tr>
<td>李娜</td><td>EMP002</td><td>长庆油田总部</td><td>市场部</td>
<td>88</td><td>125</td>
<td><span class="tag tag-green"></span></td><td>1</td>
<td>58.3</td><td>21.8</td><td>57.8</td><td>21.6</td><td>-0.5</td><td>-0.2</td>
<td><a class="link" href="#">查看详情</a></td>
</tr>
<tr>
<td>王磊</td><td>EMP003</td><td>采油一厂</td><td>运营部</td>
<td>76</td><td>98</td>
<td><span class="tag tag-orange"></span></td><td>0</td>
<td>85.6</td><td>28.2</td><td>83.4</td><td>27.5</td><td>-2.2</td><td>-0.7</td>
<td><a class="link" href="#">查看详情</a></td>
</tr>
<tr>
<td>赵敏</td><td>EMP004</td><td>采油二厂</td><td>财务部</td>
<td>95</td><td>131</td>
<td><span class="tag tag-green"></span></td><td>0</td>
<td>62.1</td><td>23.2</td><td>61.5</td><td>23.0</td><td>-0.6</td><td>-0.2</td>
<td><a class="link" href="#">查看详情</a></td>
<td>58.3</td><td>57.8</td><td>-0.5</td><td>21.8</td><td>21.6</td><td>-0.2</td>
</tr>
<tr>
<td>陈刚</td><td>EMP005</td><td>长庆油田总部</td><td>人事部</td>
<td>78</td><td>120</td>
<td><span class="tag tag-green"></span></td><td>3</td>
<td>78.9</td><td>26.1</td><td>76.5</td><td>25.3</td><td>-2.4</td><td>-0.8</td>
<td><a class="link" href="#">查看详情</a></td>
<td>78.9</td><td>76.5</td><td>-2.4</td><td>26.1</td><td>25.3</td><td>-0.8</td>
</tr>
<tr>
<td>王磊</td><td>EMP003</td><td>采油一厂</td><td>运营部</td>
<td>76</td><td>98</td>
<td><span class="tag tag-orange"></span></td><td>0</td>
<td>85.6</td><td>83.4</td><td>-2.2</td><td>28.2</td><td>27.5</td><td>-0.7</td>
</tr>
<tr>
<td>赵敏</td><td>EMP004</td><td>采油二厂</td><td>财务部</td>
<td>95</td><td>131</td>
<td><span class="tag tag-green"></span></td><td>0</td>
<td>62.1</td><td>61.5</td><td>-0.6</td><td>23.2</td><td>23.0</td><td>-0.2</td>
</tr>
</tbody>
</table>
@@ -75,11 +75,11 @@ tbody tr:hover{background:#F8FBFF;}
健康监测
</div>
<nav class="top-bar__nav">
<a href="archive-personal.html">档案</a>
<a href="archive-personal.html" class="active">档案</a>
<a href="health-checkup/survey-category.html">健康排查</a>
<a href="wearable/tool-manage.html">穿戴监测</a>
<a href="weight/scale-device.html">体重监测</a>
<a href="environment/indoor-device-list.html" class="active">环境监测</a>
<a href="environment/indoor-device-list.html">环境监测</a>
<a href="exception-dirty.html">异常事件</a>
</nav>
<div class="top-bar__right">
@@ -126,6 +126,7 @@ tbody tr:hover{background:#F8FBFF;}
<div class="tab-item" onclick="switchTab('outdoor',this)">室外设备</div>
<div class="tab-item" onclick="switchTab('water',this)">水质设备</div>
<div class="tab-item" onclick="switchTab('pollen',this)">花粉设备</div>
<div class="tab-item" onclick="switchTab('alarm',this)">报警次数</div>
</div>
<!-- 室内设备面板 -->
@@ -150,42 +151,42 @@ tbody tr:hover{background:#F8FBFF;}
<table>
<thead>
<tr>
<th>序号</th>
<th>设备名称</th>
<th>设备ID</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>SENSOR-001</td>
<td>研发部办公室</td>
<td><span class="tag tag-green">正常</span></td>
<td>2026-05-13 08:30</td>
<td>0</td>
<td>室内空气监测仪A1</td>
<td>IA-2024-001</td>
<td>PM2.5检测仪</td>
<td>采油一厂</td>
<td>办公楼3F会议室</td>
<td>2024-06-15</td>
<td>328</td>
</tr>
<tr>
<td>2</td>
<td>湿度传感器-市场部</td>
<td>SENSOR-002</td>
<td>市场部办公室</td>
<td><span class="tag tag-green">正常</span></td>
<td>2026-05-13 08:15</td>
<td>0</td>
<td>室内空气监测仪A2</td>
<td>IA-2024-002</td>
<td>甲醛检测仪</td>
<td>采油一厂</td>
<td>宿舍楼2F走廊</td>
<td>2024-07-01</td>
<td>312</td>
</tr>
<tr>
<td>3</td>
<td>空气质量传感器-会议室</td>
<td>SENSOR-003</td>
<td>一楼会议室</td>
<td><span class="tag tag-orange">异常</span></td>
<td>2026-05-13 07:45</td>
<td>3</td>
<td>室内空气监测仪B1</td>
<td>IA-2024-003</td>
<td>CO2检测仪</td>
<td>采油二厂</td>
<td>食堂大厅</td>
<td>2024-08-10</td>
<td>272</td>
</tr>
</tbody>
</table>
@@ -222,33 +223,33 @@ tbody tr:hover{background:#F8FBFF;}
<table>
<thead>
<tr>
<th>序号</th>
<th>设备名称</th>
<th>设备ID</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>WEATHER-001</td>
<td>停车场北侧</td>
<td><span class="tag tag-green">正常</span></td>
<td>2026-05-13 08:45</td>
<td>1</td>
<td>室外空气监测站A1</td>
<td>OA-2024-001</td>
<td>空气质量监测站</td>
<td>采油一厂</td>
<td>厂区东门广场</td>
<td>2024-05-10</td>
<td>364</td>
</tr>
<tr>
<td>2</td>
<td>风速计-厂区</td>
<td>WIND-001</td>
<td>区中央</td>
<td><span class="tag tag-green">正常</span></td>
<td>2026-05-13 08:30</td>
<td>0</td>
<td>室外空气监测站A2</td>
<td>OA-2024-002</td>
<td>气象监测站</td>
<td>采油一</td>
<td>停车场北侧</td>
<td>2024-06-20</td>
<td>323</td>
</tr>
</tbody>
</table>
@@ -284,33 +285,33 @@ tbody tr:hover{background:#F8FBFF;}
<table>
<thead>
<tr>
<th>序号</th>
<th>设备名称</th>
<th>设备ID</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>pH传感器-取水口</td>
<td>WATER-001</td>
<td>取水口</td>
<td><span class="tag tag-green">正常</span></td>
<td>2026-05-13 07:50</td>
<td>0</td>
<td>水质分析仪A1</td>
<td>WQ-2024-001</td>
<td>水质多参数分析仪</td>
<td>采油一厂</td>
<td>生活区供水站</td>
<td>2024-04-20</td>
<td>384</td>
</tr>
<tr>
<td>2</td>
<td>浊度计-处理池</td>
<td>WATER-002</td>
<td>处理池</td>
<td><span class="tag tag-green">正常</span></td>
<td>2026-05-13 08:00</td>
<td>0</td>
<td>水质分析仪A2</td>
<td>WQ-2024-002</td>
<td>浊度检测仪</td>
<td>采油一厂</td>
<td>处理池出水口</td>
<td>2024-05-15</td>
<td>359</td>
</tr>
</tbody>
</table>
@@ -346,24 +347,24 @@ tbody tr:hover{background:#F8FBFF;}
<table>
<thead>
<tr>
<th>序号</th>
<th>设备名称</th>
<th>设备ID</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>POLLEN-001</td>
<td>办公楼前广场</td>
<td><span class="tag tag-green">正常</span></td>
<td>2026-05-13 06:30</td>
<td>0</td>
<td>花粉采样器A1</td>
<td>PL-2024-001</td>
<td>花粉采样器</td>
<td>采油一厂</td>
<td>厂区绿化带东</td>
<td>2024-03-01</td>
<td>434</td>
</tr>
</tbody>
</table>
@@ -377,6 +378,107 @@ tbody tr:hover{background:#F8FBFF;}
</div>
</div>
<!-- 报警次数面板 -->
<div class="tab-panel" id="panel-alarm">
<div class="filter-bar">
<div class="filter-item">
<label>设备名称</label>
<input class="filter-input" type="text" placeholder="请输入设备名称">
</div>
<div class="filter-item">
<label>设备类型</label>
<select class="filter-select" onchange="updateMonitorType(this)">
<option>全部</option>
<option>室内设备</option>
<option>室外设备</option>
<option>水质设备</option>
<option>花粉设备</option>
</select>
</div>
<!-- [交互] 监测类型与设备类型联动:需先选择设备类型后,监测类型选项动态更新 -->
<div class="filter-item">
<label>监测类型</label>
<select class="filter-select" id="monitorTypeSelect" disabled>
<option>请先选择设备类型</option>
</select>
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
</div>
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-default">导出列表数据</button>
</div>
<div class="table-card">
<div class="table-card__header">
<span class="table-card__title">报警记录列表</span>
<span style="font-size:var(--font-sm);color:var(--text-secondary);">共 12 条</span>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<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>室内空气监测仪A1</td>
<td>IA-2024-001</td>
<td>室内设备</td>
<td>采油一厂</td>
<td>办公楼3F会议室</td>
<td>PM2.5</td>
<td>μg/m³</td>
<td>75</td>
<td style="color:var(--danger);font-weight:500;">128</td>
<td>2026-05-13 14:20</td>
</tr>
<tr>
<td>室外空气监测站A1</td>
<td>OA-2024-001</td>
<td>室外设备</td>
<td>采油一厂</td>
<td>厂区东门广场</td>
<td>CO2</td>
<td>ppm</td>
<td>1000</td>
<td style="color:var(--danger);font-weight:500;">1350</td>
<td>2026-05-12 16:45</td>
</tr>
<tr>
<td>水质分析仪A1</td>
<td>WQ-2024-001</td>
<td>水质设备</td>
<td>采油一厂</td>
<td>生活区供水站</td>
<td>浊度</td>
<td>NTU</td>
<td>1.0</td>
<td style="color:var(--danger);font-weight:500;">2.3</td>
<td>2026-05-11 09:30</td>
</tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>显示 3 条,共 12 条</span>
<button class="page-btn"></button>
<button class="page-btn active">1</button>
<button class="page-btn">2</button>
<button class="page-btn"></button>
</div>
</div>
</div>
</main>
<script>
@@ -400,6 +502,26 @@ var displayName = unit + (dept ? ' - ' + dept : '');
document.getElementById('unitDept').textContent = displayName;
document.getElementById('detailTitle').textContent = displayName + ' — 环境监测 详情';
document.getElementById('detailMeta').textContent = '2026年 · 设备总数 39';
// [交互] 设备类型与监测类型联动
var monitorTypeMap = {
'室内设备': ['全部','PM2.5','甲醛','CO2','温度','湿度','TVOC'],
'室外设备': ['全部','AQI','PM2.5','PM10','SO2','NO2','O3'],
'水质设备': ['全部','pH值','浊度','余氯','溶解氧','电导率'],
'花粉设备': ['全部','花粉浓度','花粉种类']
};
function updateMonitorType(el) {
var sel = document.getElementById('monitorTypeSelect');
var val = el.value;
if (val === '全部') {
sel.disabled = true;
sel.innerHTML = '<option>请先选择设备类型</option>';
} else {
sel.disabled = false;
var opts = monitorTypeMap[val] || ['全部'];
sel.innerHTML = opts.map(function(o){ return '<option>'+o+'</option>'; }).join('');
}
}
</script>
</body>
</html>
@@ -75,8 +75,8 @@ tbody tr:hover{background:#F8FBFF;}
健康监测
</div>
<nav class="top-bar__nav">
<a href="archive-personal.html">档案</a>
<a href="health-checkup/survey-category.html" class="active">健康排查</a>
<a href="archive-personal.html" class="active">档案</a>
<a href="health-checkup/survey-category.html">健康排查</a>
<a href="wearable/tool-manage.html">穿戴监测</a>
<a href="weight/scale-device.html">体重监测</a>
<a href="environment/indoor-device-list.html">环境监测</a>
@@ -75,9 +75,9 @@ tbody tr:hover{background:#F8FBFF;}
健康监测
</div>
<nav class="top-bar__nav">
<a href="archive-personal.html">档案</a>
<a href="archive-personal.html" class="active">档案</a>
<a href="health-checkup/survey-category.html">健康排查</a>
<a href="wearable/tool-manage.html" class="active">穿戴监测</a>
<a href="wearable/tool-manage.html">穿戴监测</a>
<a href="weight/scale-device.html">体重监测</a>
<a href="environment/indoor-device-list.html">环境监测</a>
<a href="exception-dirty.html">异常事件</a>
@@ -272,8 +272,24 @@ tbody tr:hover{background:#F8FBFF;}
<div class="tab-panel" id="panel-exception-times">
<div class="filter-bar">
<div class="filter-item">
<label>设备编码</label>
<input class="filter-input" type="text" placeholder="请输入设备编码">
<label>员工姓名</label>
<input class="filter-input" type="text" placeholder="请输入员工姓名">
</div>
<div class="filter-item">
<label>员工编号</label>
<input class="filter-input" type="text" placeholder="请输入员工姓名">
</div>
<div class="filter-item">
<label>告警类型</label>
<select class="filter-select">
<option>全部</option>
<option>一键告警</option>
<option>心率异常</option>
<option>血氧异常</option>
<option>体温异常</option>
<option>压力异常</option>
<option>摔倒</option>
</select>
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
@@ -283,53 +299,68 @@ tbody tr:hover{background:#F8FBFF;}
</div>
<div class="table-card">
<div class="table-card__header">
<span class="table-card__title">异常设备列表</span>
<span style="font-size:var(--font-sm);color:var(--text-secondary);">6</span>
<span class="table-card__title">告警事件列表</span>
<span style="font-size:var(--font-sm);color:var(--text-secondary);">12</span>
</div>
<div class="table-card__content">
<table>
<thead>
<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>
<th>告警位置</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>DEV010</td>
<td>智能手环-010</td>
<td>智能手环</td>
<td>3</td>
<td>2026-05-12 14:30</td>
<td>李建国</td>
<td>CQ001156</td>
<td><span style="font-family:monospace">WD-2024-002</span></td>
<td><span class="tag tag-red">一键告警</span></td>
<td style="font-weight:500">主动触发</td>
<td></td>
<td>2026-05-11 14:28</td>
<td>采油一厂 第二作业区</td>
</tr>
<tr>
<td>2</td>
<td>DEV015</td>
<td>智能手表-005</td>
<td>智能手表</td>
<td>2</td>
<td>2026-05-11 10:15</td>
<td>王磊</td>
<td>CQ002301</td>
<td><span style="font-family:monospace">WD-2024-031</span></td>
<td><span class="tag tag-purple">血氧异常</span></td>
<td style="font-weight:500">88%</td>
<td>≥95%</td>
<td>2026-05-11 14:15</td>
<td>采气一厂 第一作业区</td>
</tr>
<tr>
<td>3</td>
<td>DEV020</td>
<td>智能手环-020</td>
<td>智能手环</td>
<td>1</td>
<td>2026-05-10 09:45</td>
<td>孙浩然</td>
<td>CQ004210</td>
<td><span style="font-family:monospace">WD-2024-022</span></td>
<td><span class="tag tag-cyan">体温异常</span></td>
<td style="font-weight:500">37.6℃</td>
<td>36.0~37.3℃</td>
<td>2026-05-11 13:50</td>
<td>天然气处理厂 压缩作业区</td>
</tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>显示 3 条,共 6</span>
<span>显示 3 条,共 12</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">4</button>
<button class="page-btn"></button>
</div>
</div>
@@ -341,6 +372,10 @@ tbody tr:hover{background:#F8FBFF;}
<div class="filter-item">
<label>员工姓名</label>
<input class="filter-input" type="text" placeholder="请输入员工姓名">
</div>
<div class="filter-item">
<label>员工编号</label>
<input class="filter-input" type="text" placeholder="请输入员工姓名">
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
@@ -361,8 +396,10 @@ tbody tr:hover{background:#F8FBFF;}
<th>员工姓名</th>
<th>员工编号</th>
<th>部门名称</th>
<th>异常类型</th>
<th>异常次数</th>
<th>最后异常时间</th>
<th>异常类型</th>
<th>告警位置</th>
</tr>
</thead>
<tbody>
@@ -371,24 +408,30 @@ tbody tr:hover{background:#F8FBFF;}
<td>马超</td>
<td>EMP004</td>
<td>研发部</td>
<td>心率异常</td>
<td>3</td>
<td>2026-05-12 15:20</td>
<td><span class="tag tag-orange">心率异常</span></td>
<td>研发部 办公区</td>
</tr>
<tr>
<td>2</td>
<td>赵敏</td>
<td>EMP005</td>
<td>财务部</td>
<td>血氧异常</td>
<td>2</td>
<td>2026-05-11 11:30</td>
<td><span class="tag tag-purple">血氧异常</span></td>
<td>财务部 办公区</td>
</tr>
<tr>
<td>3</td>
<td>刘洋</td>
<td>EMP006</td>
<td>采购部</td>
<td>体温异常</td>
<td>1</td>
<td>2026-05-10 10:00</td>
<td><span class="tag tag-cyan">体温异常</span></td>
<td>采购部 办公区</td>
</tr>
</tbody>
</table>
@@ -75,10 +75,10 @@ tbody tr:hover{background:#F8FBFF;}
健康监测
</div>
<nav class="top-bar__nav">
<a href="archive-personal.html">档案</a>
<a href="archive-personal.html" class="active">档案</a>
<a href="health-checkup/survey-category.html">健康排查</a>
<a href="wearable/tool-manage.html">穿戴监测</a>
<a href="weight/scale-device.html" class="active">体重监测</a>
<a href="weight/scale-device.html">体重监测</a>
<a href="environment/indoor-device-list.html">环境监测</a>
<a href="exception-dirty.html">异常事件</a>
</nav>
@@ -122,16 +122,19 @@ tbody tr:hover{background:#F8FBFF;}
<!-- [交互] Tab 切换 -->
<div class="tab-bar">
<div class="tab-item active" onclick="switchTab('normal',this)">正常BMI</div>
<div class="tab-item" onclick="switchTab('abnormal',this)">异常BMI</div>
<div class="tab-item active" onclick="switchTab('scale',this)">体重秤设备</div>
<div class="tab-item" onclick="switchTab('bluetooth',this)">蓝牙称设备</div>
<div class="tab-item" onclick="switchTab('analyzer',this)">体脂仪设备</div>
<div class="tab-item" onclick="switchTab('equipment',this)">运动器械设备</div>
<div class="tab-item" onclick="switchTab('overweight',this)">体重超标人员</div>
</div>
<!-- 正常BMI面板 -->
<div class="tab-panel active" id="panel-normal">
<!-- 体重秤设备面板 -->
<div class="tab-panel active" id="panel-scale">
<div class="filter-bar">
<div class="filter-item">
<label>员工姓名</label>
<input class="filter-input" type="text" placeholder="请输入员工姓名">
<label>设备编码</label>
<input class="filter-input" type="text" placeholder="请输入设备编码">
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
@@ -141,59 +144,59 @@ tbody tr:hover{background:#F8FBFF;}
</div>
<div class="table-card">
<div class="table-card__header">
<span class="table-card__title">正常BMI员工列表</span>
<span style="font-size:var(--font-sm);color:var(--text-secondary);">76</span>
<span class="table-card__title">体重秤设备列表</span>
<span style="font-size:var(--font-sm);color:var(--text-secondary);">42</span>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<th>序号</th>
<th>员工姓名</th>
<th>员工编号</th>
<th>部门名称</th>
<th>当前体重(kg)</th>
<th>当前BMI</th>
<th>BMI等级</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>EMP001</td>
<td>研发部</td>
<td>70.2</td>
<td>23.4</td>
<td>SC-2024-001</td>
<td>体重秤A1</td>
<td>华为</td>
<td>HW-S100</td>
<td>采油一厂</td>
<td>职工活动中心1F</td>
<td>2024-03-15</td>
<td><span class="tag tag-green">正常</span></td>
<td>2026-05-13 08:30</td>
</tr>
<tr>
<td>2</td>
<td>李娜</td>
<td>EMP002</td>
<td>市场部</td>
<td>57.8</td>
<td>21.6</td>
<td>SC-2024-002</td>
<td>体重秤A2</td>
<td>小米</td>
<td>MI-Scale2</td>
<td>采油一厂</td>
<td>办公楼2F健身房</td>
<td>2024-03-18</td>
<td><span class="tag tag-green">正常</span></td>
<td>2026-05-13 09:15</td>
</tr>
<tr>
<td>3</td>
<td>陈刚</td>
<td>EMP005</td>
<td>人事部</td>
<td>76.5</td>
<td>25.3</td>
<td><span class="tag tag-green">正常</span></td>
<td>2026-05-13 07:45</td>
<td>SC-2024-003</td>
<td>体重秤B1</td>
<td>乐心</td>
<td>LX-Pro</td>
<td>采油二厂</td>
<td>员工食堂入口</td>
<td>2024-04-02</td>
<td><span class="tag tag-orange">维护中</span></td>
</tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>显示 3 条,共 76</span>
<span>显示 3 条,共 42</span>
<button class="page-btn"></button>
<button class="page-btn active">1</button>
<button class="page-btn">2</button>
@@ -202,8 +205,237 @@ tbody tr:hover{background:#F8FBFF;}
</div>
</div>
<!-- 异常BMI面板 -->
<div class="tab-panel" id="panel-abnormal">
<!-- 蓝牙称设备面板 -->
<div class="tab-panel" id="panel-bluetooth">
<div class="filter-bar">
<div class="filter-item">
<label>设备编码</label>
<input class="filter-input" type="text" placeholder="请输入设备编码">
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
</div>
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-default">导出列表数据</button>
</div>
<div class="table-card">
<div class="table-card__header">
<span class="table-card__title">蓝牙称设备列表</span>
<span style="font-size:var(--font-sm);color:var(--text-secondary);">共 28 条</span>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<th>设备编码</th>
<th>设备名称</th>
<th>设备厂商</th>
<th>设备型号</th>
<th>所属单位</th>
<th>布放位置</th>
<th>入库日期</th>
<th>设备状态</th>
</tr>
</thead>
<tbody>
<tr>
<td>BT-2024-001</td>
<td>蓝牙称A1</td>
<td>华为</td>
<td>HW-S100</td>
<td>采油一厂</td>
<td>职工活动中心1F</td>
<td>2024-03-15</td>
<td><span class="tag tag-green">正常</span></td>
</tr>
<tr>
<td>BT-2024-002</td>
<td>蓝牙称A2</td>
<td>小米</td>
<td>MI-Scale2</td>
<td>采油一厂</td>
<td>办公楼2F健身房</td>
<td>2024-03-18</td>
<td><span class="tag tag-green">正常</span></td>
</tr>
<tr>
<td>BT-2024-003</td>
<td>蓝牙称B1</td>
<td>乐心</td>
<td>LX-Pro</td>
<td>采油二厂</td>
<td>员工食堂入口</td>
<td>2024-04-02</td>
<td><span class="tag tag-orange">维护中</span></td>
</tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>显示 3 条,共 28 条</span>
<button class="page-btn"></button>
<button class="page-btn active">1</button>
<button class="page-btn"></button>
</div>
</div>
</div>
<!-- 体脂仪设备面板 -->
<div class="tab-panel" id="panel-analyzer">
<div class="filter-bar">
<div class="filter-item">
<label>设备编码</label>
<input class="filter-input" type="text" placeholder="请输入设备编码">
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
</div>
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-default">导出列表数据</button>
</div>
<div class="table-card">
<div class="table-card__header">
<span class="table-card__title">体脂仪设备列表</span>
<span style="font-size:var(--font-sm);color:var(--text-secondary);">共 15 条</span>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<th>设备编码</th>
<th>设备名称</th>
<th>设备厂商</th>
<th>设备型号</th>
<th>所属单位</th>
<th>布放位置</th>
<th>入库日期</th>
<th>设备状态</th>
</tr>
</thead>
<tbody>
<tr>
<td>FT-2024-001</td>
<td>体脂仪A1</td>
<td>华为</td>
<td>HW-S100</td>
<td>采油一厂</td>
<td>职工活动中心1F</td>
<td>2024-03-15</td>
<td><span class="tag tag-green">正常</span></td>
</tr>
<tr>
<td>FT-2024-002</td>
<td>体脂仪A2</td>
<td>小米</td>
<td>MI-Scale2</td>
<td>采油一厂</td>
<td>办公楼2F健身房</td>
<td>2024-03-18</td>
<td><span class="tag tag-green">正常</span></td>
</tr>
<tr>
<td>FT-2024-003</td>
<td>体脂仪B1</td>
<td>乐心</td>
<td>LX-Pro</td>
<td>采油二厂</td>
<td>员工食堂入口</td>
<td>2024-04-02</td>
<td><span class="tag tag-orange">维护中</span></td>
</tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>显示 3 条,共 15 条</span>
<button class="page-btn"></button>
<button class="page-btn active">1</button>
<button class="page-btn"></button>
</div>
</div>
</div>
<!-- 运动器械设备面板 -->
<div class="tab-panel" id="panel-equipment">
<div class="filter-bar">
<div class="filter-item">
<label>设备编码</label>
<input class="filter-input" type="text" placeholder="请输入设备编码">
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
</div>
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-default">导出列表数据</button>
</div>
<div class="table-card">
<div class="table-card__header">
<span class="table-card__title">运动器械设备列表</span>
<span style="font-size:var(--font-sm);color:var(--text-secondary);">共 24 条</span>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<th>设备编码</th>
<th>设备名称</th>
<th>设备类型</th>
<th>设备厂商</th>
<th>设备型号</th>
<th>所属单位</th>
<th>布放位置</th>
<th>入库日期</th>
<th>设备状态</th>
</tr>
</thead>
<tbody>
<tr>
<td>SP-2024-001</td>
<td>跑步机T1</td>
<td><span class="tag tag-blue">有氧器械</span></td>
<td>舒华</td>
<td>SH-T5170</td>
<td>采油一厂</td>
<td>职工活动中心1F</td>
<td>2024-03-15</td>
<td><span class="tag tag-green">正常</span></td>
</tr>
<tr>
<td>SP-2024-002</td>
<td>椭圆机E1</td>
<td><span class="tag tag-blue">有氧器械</span></td>
<td>岱宇</td>
<td>DY-E600</td>
<td>采油一厂</td>
<td>办公楼2F健身房</td>
<td>2024-03-18</td>
<td><span class="tag tag-green">正常</span></td>
</tr>
<tr>
<td>SP-2024-003</td>
<td>划船机R1</td>
<td><span class="tag tag-blue">有氧器械</span></td>
<td>美国诺德</td>
<td>NordicTrack-RW</td>
<td>采油二厂</td>
<td>员工食堂入口</td>
<td>2024-04-02</td>
<td><span class="tag tag-green">正常</span></td>
</tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>显示 3 条,共 24 条</span>
<button class="page-btn"></button>
<button class="page-btn active">1</button>
<button class="page-btn"></button>
</div>
</div>
</div>
<!-- 体重超标人员面板 -->
<div class="tab-panel" id="panel-overweight">
<div class="filter-bar">
<div class="filter-item">
<label>员工姓名</label>
@@ -217,7 +449,7 @@ tbody tr:hover{background:#F8FBFF;}
</div>
<div class="table-card">
<div class="table-card__header">
<span class="table-card__title">异常BMI员工列表</span>
<span class="table-card__title">体重超标人员列表</span>
<span style="font-size:var(--font-sm);color:var(--text-secondary);">共 14 条</span>
</div>
<div class="table-card__content">
@@ -228,9 +460,10 @@ tbody tr:hover{background:#F8FBFF;}
<th>员工姓名</th>
<th>员工编号</th>
<th>部门名称</th>
<th>当前体重(kg)</th>
<th>当前BMI</th>
<th>BMI等级</th>
<th>身高(cm)</th>
<th>体重(kg)</th>
<th>BMI</th>
<th>体脂率(%)</th>
<th>最后更新时间</th>
</tr>
</thead>
@@ -240,9 +473,10 @@ tbody tr:hover{background:#F8FBFF;}
<td>王磊</td>
<td>EMP003</td>
<td>运营部</td>
<td>175</td>
<td>83.4</td>
<td>27.5</td>
<td><span class="tag tag-orange">超重</span></td>
<td>27.5 <span class="tag tag-orange">超重</span></td>
<td>28.3</td>
<td>2026-05-12 10:20</td>
</tr>
<tr>
@@ -250,9 +484,10 @@ tbody tr:hover{background:#F8FBFF;}
<td>周明</td>
<td>EMP006</td>
<td>采购部</td>
<td>172</td>
<td>88.5</td>
<td>29.2</td>
<td><span class="tag tag-orange">肥胖</span></td>
<td>29.2 <span class="tag tag-orange">肥胖</span></td>
<td>32.1</td>
<td>2026-05-11 14:35</td>
</tr>
</tbody>
+1 -5
View File
@@ -248,14 +248,10 @@ tbody tr.stat-row:hover{background:#E6F0FF;}
<th>花粉设备数 ↕</th>
<th>报警次数 ↕</th>
</tr>
<th>水质设备数 ↕</th>
<th>花粉设备数 ↕</th>
<th>报警次数 ↕</th>
</tr>
</thead>
<tbody>
<tr class="stat-row">
<td>统计行</td><td>5</td><td>405</td><td>384</td><td>21</td><td>405</td><td>384</td><td>14</td><td>8</td><td>384</td><td>82</td><td>41</td><td>27</td><td>15</td><td>24</td><td>8</td><td>4</td><td>4</td><td>5</td>
<td>统计行</td><td></td><td>405</td><td>384</td><td>21</td><td>405</td><td>384</td><td>14</td><td>8</td><td>384</td><td>82</td><td>41</td><td>27</td><td>15</td><td>24</td><td>8</td><td>4</td><td>4</td><td>5</td>
</tr>
<tr><td>采油一厂</td><td>研发部</td><td>85</td><td>82</td><td>3</td><td>85</td><td>82</td><td>2</td><td>1</td><td>82</td><td>18</td><td>9</td><td>6</td><td>3</td><td>6</td><td>2</td><td>1</td><td>1</td><td>1</td></tr>
<tr><td>采油一厂</td><td>运营部</td><td>120</td><td>112</td><td>8</td><td>120</td><td>112</td><td>5</td><td>3</td><td>112</td><td>24</td><td>12</td><td>8</td><td>5</td><td>8</td><td>3</td><td>1</td><td>1</td><td>1</td></tr>
+928
View File
@@ -0,0 +1,928 @@
# 健康监测(管理端)产品需求文档
## 模块概述
健康监测管理端为运营/管理人员提供员工健康数据的全方位监测与管理能力,涵盖健康档案管理、健康排查问卷配置与签到记录、穿戴设备管理与异常告警、体重监测设备与数据管理、环境监测设备与报警管理、异常事件汇总等功能。
### 页面导航结构
```
健康监测(管理端)
├── 档案
│ ├── 个人监测数据
│ ├── 单位报表数据
│ │ ├── 健康排查详情
│ │ ├── 穿戴监测详情
│ │ ├── 体重监测详情
│ │ └── 环境监测详情
│ └── 算法模型
├── 健康排查
│ ├── 问卷分类
│ ├── 问卷题目
│ ├── 问卷评分
│ ├── 问卷模板
│ ├── 签到格言
│ ├── 员工签到记录
│ └── 部门签到记录
├── 穿戴监测
│ ├── 工具管理
│ ├── 绑定记录
│ ├── 用户数据
│ ├── 异常事件
│ ├── 通知消息
│ ├── 部门数据统计
│ ├── 部门报表
│ └── 个人数据统计
├── 体重监测
│ ├── 体重秤设备管理 ⇄ 新增设备弹窗
│ ├── 体重秤监测数据 → 监测详情
│ ├── 蓝牙称设备管理 ⇄ 新增设备弹窗
│ ├── 蓝牙称监测数据 → 监测详情
│ ├── 体脂仪设备管理 ⇄ 新增设备弹窗
│ ├── 体脂仪监测数据 → 监测详情
│ ├── 运动器械设备管理 ⇄ 新增设备弹窗
│ ├── 运动器械监测数据 → 监测详情
│ ├── 员工数据 → 员工数据记录
│ ├── 员工统计
│ └── 部门统计
├── 环境监测(×4类型:室内/室外/水质/花粉)
│ ├── 设备列表
│ ├── 设备分类
│ ├── 数据分析
│ ├── 数据监测
│ ├── 异常报警
│ ├── APP记录
│ ├── 历史数据 → 监测详情
│ └── 历史报警 → 报警详情
│ └── 花粉知识(仅花粉)
└── 异常事件
├── 系统脏数据
└── 结果异常
```
## 页面清单
### 档案
| 序号 | 二级菜单 | 页面/弹窗 | 文件 | 类型 |
|------|----------|-----------|------|------|
| 1 | 个人监测数据 | 个人监测数据列表 | archive-personal.html | 页面 |
| 2 | 单位报表数据 | 单位报表数据列表 | archive-unit.html | 页面 |
| 3 | | 健康排查详情 | archive-unit-health-checkup-detail.html | 页面 |
| 4 | | 穿戴监测详情 | archive-unit-wearable-detail.html | 页面 |
| 5 | | 体重监测详情 | archive-unit-weight-detail.html | 页面 |
| 6 | | 环境监测详情 | archive-unit-environment-detail.html | 页面 |
| 7 | 算法模型 | 算法模型列表 | archive-algorithm.html | 页面 |
### 健康排查
| 序号 | 二级菜单 | 页面/弹窗 | 文件 | 类型 |
|------|----------|-----------|------|------|
| 8 | 问卷分类 | 问卷分类列表 | health-checkup/survey-category.html | 页面 |
| 9 | 问卷题目 | 问卷题目列表 | health-checkup/survey-question.html | 页面 |
| 10 | 问卷评分 | 问卷评分配置 | health-checkup/survey-score.html | 页面 |
| 11 | 问卷模板 | 问卷模板列表 | health-checkup/survey-template.html | 页面 |
| 12 | 签到格言 | 签到格言管理 | health-checkup/maxim.html | 页面 |
| 13 | 员工签到记录 | 员工签到记录 | health-checkup/record-user.html | 页面 |
| 14 | 部门签到记录 | 部门签到记录 | health-checkup/record-dept.html | 页面 |
### 穿戴监测
| 序号 | 二级菜单 | 页面/弹窗 | 文件 | 类型 |
|------|----------|-----------|------|------|
| 15 | 工具管理 | 设备管理列表 | wearable/tool-manage.html | 页面 |
| 16 | 绑定记录 | 绑定记录列表 | wearable/bind-record.html | 页面 |
| 17 | 用户数据 | 用户监测数据 | wearable/user-data.html | 页面 |
| 18 | 异常事件 | 告警事件列表 | wearable/exception-event.html | 页面 |
| 19 | 通知消息 | 通知消息列表 | wearable/notification.html | 页面 |
| 20 | 部门数据统计 | 部门数据统计 | wearable/dept-stat.html | 页面 |
| 21 | 部门报表 | 部门报表 | wearable/dept-report.html | 页面 |
| 22 | 个人数据统计 | 个人数据统计 | wearable/personal-stat.html | 页面 |
### 体重监测
| 序号 | 二级菜单 | 页面/弹窗 | 文件 | 类型 |
|------|----------|-----------|------|------|
| 23 | 体重秤设备 | 体重秤设备列表 | weight/scale-device.html | 页面 |
| 24 | | 新增体重秤设备 | weight/scale-device-add.html | 弹窗 |
| 25 | | 体重秤监测数据 | weight/scale-monitor.html | 页面 |
| 26 | | 体重秤监测详情 | weight/scale-monitor-detail.html | 页面 |
| 27 | 蓝牙称设备 | 蓝牙称设备列表 | weight/bluetooth-device.html | 页面 |
| 28 | | 新增蓝牙称设备 | weight/bluetooth-device-add.html | 弹窗 |
| 29 | | 蓝牙称监测数据 | weight/bluetooth-monitor.html | 页面 |
| 30 | | 蓝牙称监测详情 | weight/bluetooth-monitor-detail.html | 页面 |
| 31 | 体脂仪设备 | 体脂仪设备列表 | weight/fat-device.html | 页面 |
| 32 | | 新增体脂仪设备 | weight/fat-device-add.html | 弹窗 |
| 33 | | 体脂仪监测数据 | weight/fat-monitor.html | 页面 |
| 34 | | 体脂仪监测详情 | weight/fat-monitor-detail.html | 页面 |
| 35 | 运动器械设备 | 运动器械设备列表 | weight/sport-device.html | 页面 |
| 36 | | 新增运动器械设备 | weight/sport-device-add.html | 弹窗 |
| 37 | | 运动器械监测数据 | weight/sport-monitor.html | 页面 |
| 38 | | 运动器械监测详情 | weight/sport-monitor-detail.html | 页面 |
| 39 | 员工数据 | 员工数据列表 | weight/employee-data.html | 页面 |
| 40 | | 员工数据记录 | weight/employee-data-record.html | 页面 |
| 41 | 员工统计 | 员工统计 | weight/employee-stat.html | 页面 |
| 42 | 部门统计 | 部门统计 | weight/dept-stat.html | 页面 |
### 环境监测
| 序号 | 二级菜单 | 页面/弹窗 | 文件 | 类型 |
|------|----------|-----------|------|------|
| 43 | 室内-设备列表 | 室内设备列表 | environment/indoor-device-list.html | 页面 |
| 44 | 室内-设备分类 | 室内设备分类 | environment/indoor-device-category.html | 页面 |
| 45 | 室内-数据分析 | 室内数据分析 | environment/indoor-data-analysis.html | 页面 |
| 46 | 室内-数据监测 | 室内数据监测 | environment/indoor-data-monitor.html | 页面 |
| 47 | 室内-异常报警 | 室内异常报警 | environment/indoor-exception-alarm.html | 页面 |
| 48 | 室内-APP记录 | 室内APP记录 | environment/indoor-app-record.html | 页面 |
| 49 | 室内-历史数据 | 室内历史数据 | environment/indoor-history-data.html | 页面 |
| 50 | | 室内历史监测详情 | environment/indoor-history-monitor-detail.html | 页面 |
| 51 | | 室内历史报警详情 | environment/indoor-history-alarm-detail.html | 页面 |
| 52 | 室外-设备列表 | 室外设备列表 | environment/outdoor-device-list.html | 页面 |
| 53 | 室外-设备分类 | 室外设备分类 | environment/outdoor-device-category.html | 页面 |
| 54 | 室外-数据分析 | 室外数据分析 | environment/outdoor-data-analysis.html | 页面 |
| 55 | 室外-数据监测 | 室外数据监测 | environment/outdoor-data-monitor.html | 页面 |
| 56 | 室外-异常报警 | 室外异常报警 | environment/outdoor-exception-alarm.html | 页面 |
| 57 | 室外-APP记录 | 室外APP记录 | environment/outdoor-app-record.html | 页面 |
| 58 | 室外-历史数据 | 室外历史数据 | environment/outdoor-history-data.html | 页面 |
| 59 | | 室外历史监测详情 | environment/outdoor-history-monitor-detail.html | 页面 |
| 60 | | 室外历史报警详情 | environment/outdoor-history-alarm-detail.html | 页面 |
| 61 | 水质-设备列表 | 水质设备列表 | environment/water-device-list.html | 页面 |
| 62 | 水质-设备分类 | 水质设备分类 | environment/water-device-category.html | 页面 |
| 63 | 水质-数据分析 | 水质数据分析 | environment/water-data-analysis.html | 页面 |
| 64 | 水质-数据监测 | 水质数据监测 | environment/water-data-monitor.html | 页面 |
| 65 | 水质-异常报警 | 水质异常报警 | environment/water-exception-alarm.html | 页面 |
| 66 | 水质-APP记录 | 水质APP记录 | environment/water-app-record.html | 页面 |
| 67 | 水质-历史数据 | 水质历史数据 | environment/water-history-data.html | 页面 |
| 68 | | 水质历史监测详情 | environment/water-history-monitor-detail.html | 页面 |
| 69 | | 水质历史报警详情 | environment/water-history-alarm-detail.html | 页面 |
| 70 | 花粉-设备列表 | 花粉设备列表 | environment/pollen-device-list.html | 页面 |
| 71 | 花粉-设备分类 | 花粉设备分类 | environment/pollen-device-category.html | 页面 |
| 72 | 花粉-数据分析 | 花粉数据分析 | environment/pollen-data-analysis.html | 页面 |
| 73 | 花粉-数据监测 | 花粉数据监测 | environment/pollen-data-monitor.html | 页面 |
| 74 | 花粉-异常报警 | 花粉异常报警 | environment/pollen-exception-alarm.html | 页面 |
| 75 | 花粉-APP记录 | 花粉APP记录 | environment/pollen-app-record.html | 页面 |
| 76 | 花粉-历史数据 | 花粉历史数据 | environment/pollen-history-data.html | 页面 |
| 77 | | 花粉历史监测详情 | environment/pollen-history-monitor-detail.html | 页面 |
| 78 | | 花粉历史报警详情 | environment/pollen-history-alarm-detail.html | 页面 |
| 79 | 花粉知识 | 花粉知识管理 | environment/pollen-knowledge.html | 页面 |
### 异常事件
| 序号 | 二级菜单 | 页面/弹窗 | 文件 | 类型 |
|------|----------|-----------|------|------|
| 80 | 系统脏数据 | 系统脏数据列表 | exception-dirty.html | 页面 |
| 81 | 结果异常 | 结果异常列表 | exception-result.html | 页面 |
---
## 逐页说明
---
## 一、档案
### 1. 个人监测数据(archive-personal.html
![页面截图](screenshots/archive-personal.jpg)
**功能说明:** 以员工为维度展示个人健康监测数据汇总,支持按姓名、编号、单位部门筛选。
**筛选条件:** 员工姓名(输入框)、员工编号(输入框)、所属单位(下拉)、所属部门(下拉)
**表格列:** 序号、员工姓名、员工编号、所属单位、所属部门、健康排查积分、穿戴异常次数、体重BMI、环境报警次数
**交互说明:**
- 支持导出列表数据
- 各数据列点击可跳转到对应模块的个人详情
---
### 2. 单位报表数据(archive-unit.html
![页面截图](screenshots/archive-unit.jpg)
**功能说明:** 以单位/部门为维度展示各业务模块的汇总统计数据,支持二级单位和三级单位两个维度切换。
**Tab切换:** 二级单位 / 三级单位
**筛选条件:** 单位名称(下拉)、年份(下拉)
**二级单位表格列(多级表头):**
- 单位名称、总人数
- 健康排查:已签到人数、未签到人数
- 穿戴监测:入库设备数、分配设备数、异常次数、异常人数
- 体重监测:体重秤设备数、蓝牙称设备数、体脂仪设备数、运动器械设备数、体重超标人数
- 环境监测:室内设备数、室外设备数、水质设备数、花粉设备数、报警次数
**三级单位表格列:** 在二级单位基础上增加"部门名称"列
**业务规则:**
- 表格首行为统计行(汇总数据),背景色区分
- 所有数据列支持排序(↕)
- 各业务模块数据列点击跳转到对应的二级详情页
**交互说明:**
- 点击健康排查列数据跳转到健康排查详情页
- 点击穿戴监测列数据跳转到穿戴监测详情页
- 点击体重监测列数据跳转到体重监测详情页
- 点击环境监测列数据跳转到环境监测详情页
- 跳转时通过URL参数传递单位名称和部门名称
---
### 3. 健康排查详情(archive-unit-health-checkup-detail.html
![页面截图](screenshots/archive-unit-health-checkup-detail.jpg)
**功能说明:** 展示指定单位/部门的健康排查签到详情,按已签到和未签到分Tab展示。
**Tab切换:** 已签到 / 未签到
**筛选条件:** 员工姓名(输入框)、员工编号(输入框)
**已签到表格列:** 序号、员工姓名、员工编号、部门名称、积分、连续签到天数、签到日期
**未签到表格列:** 序号、员工姓名、员工编号、部门名称
**交互说明:**
- 面包屑导航:单位报表数据 / 单位名称 / 健康排查
- 返回按钮跳转回单位报表数据页
- 标题和面包屑通过URL参数动态显示单位和部门信息
---
### 4. 穿戴监测详情(archive-unit-wearable-detail.html
![页面截图](screenshots/archive-unit-wearable-detail.jpg)
**功能说明:** 展示指定单位/部门的穿戴监测详情,包含设备入库、分配、异常次数和异常人数四个维度。
**Tab切换:** 入库设备 / 分配设备 / 异常次数 / 异常人数
**入库设备筛选:** 设备编码(输入框)
**入库设备表格列:** 序号、设备编码、设备名称、设备类型、厂商、入库时间
**分配设备筛选:** 员工姓名(输入框)
**分配设备表格列:** 序号、员工姓名、员工编号、部门名称、设备编码、设备类型、分配日期
**异常次数筛选:** 员工姓名(输入框)、员工编号(输入框)、告警类型(下拉:全部/一键告警/心率异常/血氧异常/体温异常/压力异常/摔倒)
**异常次数表格列:** 序号、员工姓名、员工编号、设备编码、告警类型、告警值、参考范围、告警时间、告警位置
**异常人数筛选:** 员工姓名(输入框)、员工编号(输入框)
**异常人数表格列:** 序号、员工姓名、员工编号、部门名称、总异常次数、最后异常时间、异常类型、告警位置
**交互说明:**
- 面包屑导航:单位报表数据 / 单位名称 / 穿戴监测
- 返回按钮跳转回单位报表数据页
---
### 5. 体重监测详情(archive-unit-weight-detail.html
![页面截图](screenshots/archive-unit-weight-detail.jpg)
**功能说明:** 展示指定单位/部门的体重监测详情,按设备类型和超标人员分Tab展示。
**Tab切换:** 体重秤设备 / 蓝牙称设备 / 体脂仪设备 / 运动器械设备 / 体重超标人员
**设备Tab筛选:** 设备编码(输入框)
**设备Tab表格列(体重秤/蓝牙称/体脂仪):** 序号、设备编码、设备名称、设备厂商、设备型号、所属单位、布放位置、入库日期、设备状态
**运动器械设备表格列:** 序号、设备编码、设备名称、设备类型、设备厂商、设备型号、所属单位、布放位置、入库日期、设备状态
**体重超标人员筛选:** 员工姓名(输入框)、员工编号(输入框)
**体重超标人员表格列:** 序号、员工姓名、员工编号、部门名称、身高(cm)、体重(kg)、BMI(数值+等级标签)、体脂率(%)、最后更新时间
**业务规则:**
- BMI等级标签:正常(绿色)、超重(橙色)、肥胖(红色)
- 设备状态标签:在线(绿色)、离线(灰色)
**交互说明:**
- 面包屑导航:单位报表数据 / 单位名称 / 体重监测
- 返回按钮跳转回单位报表数据页
---
### 6. 环境监测详情(archive-unit-environment-detail.html
![页面截图](screenshots/archive-unit-environment-detail.jpg)
**功能说明:** 展示指定单位/部门的环境监测详情,按设备类型和报警次数分Tab展示。
**Tab切换:** 室内设备 / 室外设备 / 水质设备 / 花粉设备 / 报警次数
**设备Tab筛选:** 设备编码(输入框)
**设备Tab表格列:** 序号、设备名称、设备编码、设备分类、所属单位、设备位置、布点日期、监测时长(天)
**报警次数筛选:** 设备编码(输入框)、设备类型(下拉:全部/室内/室外/水质/花粉)、监测类型(下拉,联动设备类型)
**报警次数表格列:** 序号、设备名称、设备编号、设备类型、所属单位、设备位置、监测类型、单位、阈值、异常值、报警时间
**业务规则:**
- 监测类型下拉选项联动设备类型:选择设备类型后才可选择对应的监测类型
- 室内监测类型:温度、湿度、PM2.5、CO2、甲醛、TVOC
- 室外监测类型:温度、湿度、风速、噪音、PM2.5、PM10
- 水质监测类型:pH值、浊度、余氯、溶解氧、电导率
- 花粉监测类型:花粉浓度、花粉种类
**交互说明:**
- 面包屑导航:单位报表数据 / 单位名称 / 环境监测
- 返回按钮跳转回单位报表数据页
- 设备类型切换时清空监测类型选择
---
### 7. 算法模型(archive-algorithm.html
![页面截图](screenshots/archive-algorithm.jpg)
**功能说明:** 管理健康监测相关的算法模型文档,支持文档的增删改查和附件预览下载。
**筛选条件:** 文档名称(输入框)、制作年份(输入框)
**表格列:** 序号、文档名称、文档描述、制作机构、制作人、制作年份、上传日期↕、附件、操作
**业务规则:**
- 附件支持预览和下载两种操作
- 操作列包含编辑和删除
**交互说明:**
- 点击"新增"打开新增文档表单
- 点击"预览"在新窗口预览附件内容
- 点击"下载"下载附件文件
- 点击"编辑"打开编辑表单
- 点击"删除"弹出确认提示后删除
- 支持导出列表数据
---
## 二、健康排查
### 8. 问卷分类(health-checkup/survey-category.html
![页面截图](screenshots/health-checkup/survey-category.jpg)
**功能说明:** 管理健康排查问卷的分类体系,支持树状层级结构的分类增删改查。
**筛选条件:** 分类名称(输入框)
**表格列:** 展开按钮、分类名称、分类排序、操作
**业务规则:**
- 树状表格结构,支持展开/收起子分类
- 支持多级分类嵌套
**交互说明:**
- 点击"新增"打开新增分类弹窗(分类名称、排序、所属分类下拉)
- 操作列:编辑、删除、添加下级
- 点击"编辑"打开编辑弹窗
---
### 9. 问卷题目(health-checkup/survey-question.html
![页面截图](screenshots/health-checkup/survey-question.jpg)
**功能说明:** 管理健康排查问卷的题目库,支持按分类筛选和题目的增删改查。
**筛选条件:** 问题分类(级联选择)、问题描述(输入框)
**表格列:** 问题分类、问题描述、问题类型、问题排序、是否必填、频次、操作
**交互说明:**
- 点击"新增"打开新增问题弹窗(级联选择分类、文本输入、下拉选择、动态选项列表)
- 操作列:编辑、删除
---
### 10. 问卷评分(health-checkup/survey-score.html
![页面截图](screenshots/health-checkup/survey-score.jpg)
**功能说明:** 配置健康排查问卷的积分规则参数。
**表单字段:** 积分起始值(数字输入)、递增值(数字输入)、最大值(数字输入)
**交互说明:**
- 点击"保存"提交积分规则配置
- 点击"重置"恢复默认值
---
### 11. 问卷模板(health-checkup/survey-template.html
![页面截图](screenshots/health-checkup/survey-template.jpg)
**功能说明:** 管理健康排查问卷模板,支持模板的创建、编辑、查看和删除。
**表格列:** 模板名称、用户类别、模板状态、操作
**交互说明:**
- 点击"新增模板"打开新增弹窗
- 点击"编辑"打开编辑模板弹窗(文本输入、下拉选择、树状多选标签)
- 点击"查看"打开只读查看弹窗(展示模板关联的题目表格)
- 操作列:编辑、删除、查看
---
### 12. 签到格言(health-checkup/maxim.html
![页面截图](screenshots/health-checkup/maxim.jpg)
**功能说明:** 管理员工健康排查签到时展示的格言内容,支持增删改查。
**筛选条件:** 格言内容(输入框)
**表格列:** 格言内容、格言作者、格言来源、创建日期、操作
**交互说明:**
- 点击"新增"打开新增格言弹窗(格言内容文本域、作者输入框、来源输入框)
- 操作列:编辑、删除
---
### 13. 员工签到记录(health-checkup/record-user.html
![页面截图](screenshots/health-checkup/record-user.jpg)
**功能说明:** 查看员工健康排查签到的明细记录,支持按员工、单位、时间筛选。
**筛选条件:** 员工姓名(输入框)、员工编号(输入框)、所属单位(下拉)、签到日期(日期范围)
**表格列:** 序号、员工姓名、员工编号、所属单位、所属部门、签到日期、签到时间、积分
**交互说明:**
- 支持导出列表数据
---
### 14. 部门签到记录(health-checkup/record-dept.html
![页面截图](screenshots/health-checkup/record-dept.jpg)
**功能说明:** 以部门为维度统计健康排查签到情况,展示各部门签到率。
**筛选条件:** 所属单位(下拉)、统计日期(日期选择)
**表格列:** 序号、单位名称、部门名称、总人数、已签到人数、未签到人数、签到率
**交互说明:**
- 支持导出列表数据
---
## 三、穿戴监测
### 15. 工具管理(wearable/tool-manage.html
![页面截图](screenshots/wearable/tool-manage.jpg)
**功能说明:** 管理穿戴监测设备的全生命周期,包括设备入库、绑定员工、换绑、报废等操作。
**筛选条件:** 设备编码(输入框)、设备类型(下拉)、绑定状态(下拉)、所属单位(下拉)
**表格列:** 序号、设备编码、设备名称、设备类型、厂商、绑定状态、绑定员工、所属单位、入库时间、操作
**业务规则:**
- 绑定状态:已绑定(绿色)、未绑定(灰色)、已报废(红色)
- 操作项根据设备状态动态显示:未绑定可"绑定员工",已绑定可"换绑/解绑",均可"报废"
**交互说明:**
- 点击"新增设备"打开新增设备表单弹窗
- 点击"批量入库"打开文件上传弹窗(Excel导入)
- 点击"绑定员工"打开绑定弹窗(选择员工)
- 点击"绑定记录"打开该设备的绑定历史弹窗
- 支持导出列表数据
---
### 16. 绑定记录(wearable/bind-record.html
![页面截图](screenshots/wearable/bind-record.jpg)
**功能说明:** 查看所有穿戴设备的绑定历史记录。
**筛选条件:** 设备编码(输入框)、所属单位(下拉)、员工姓名(输入框)、工号(输入框)、绑定状态(下拉)、绑定时间(日期范围)
**表格列:** 序号、设备编码、设备类型、员工姓名、所属单位、作业区、绑定时间、解绑时间、状态
**交互说明:**
- 支持导出列表数据
---
### 17. 用户数据(wearable/user-data.html
![页面截图](screenshots/wearable/user-data.jpg)
**功能说明:** 展示员工穿戴设备采集的实时监测数据,包括心率、血氧、体温、血压、步数等指标。
**筛选条件:** 员工姓名(输入框)、所属单位(下拉)、设备编码(输入框)
**表格列:** 序号、员工姓名、员工编号、所属单位、设备编码、心率(bpm)、血氧(%)、体温(℃)、收缩压、舒张压、步数、最后更新时间、操作
**业务规则:**
- 异常值红色标注(超出正常范围)
- 操作列"查看详情"打开数据详情弹窗
**交互说明:**
- 数据详情弹窗包含:当日统计卡片、趋势图Tab、历史明细Tab
- 趋势图支持切换监测项和时间范围
---
### 18. 异常事件(wearable/exception-event.html
![页面截图](screenshots/wearable/exception-event.jpg)
**功能说明:** 展示穿戴设备产生的告警事件列表,顶部有今日告警统计概览。
**统计卡片:** 今日告警总计、一键告警、心率异常、血氧异常、体温/压力异常
**筛选条件:** 员工姓名(输入框)、员工编号(输入框)、所属单位(下拉)、告警类型(下拉)、告警时间(日期范围)
**表格列:** 序号、员工姓名、员工编号、设备编码、告警类型、告警值、参考范围、告警时间、告警位置、操作
**业务规则:**
- 告警类型标签颜色:一键告警(红色)、心率异常(橙色)、血氧异常(紫色)、体温异常(青色)、压力异常(蓝色)、摔倒(红色)
**交互说明:**
- 点击"查看详情"打开告警详情弹窗(含位置信息)
- 支持导出列表数据
---
### 19. 通知消息(wearable/notification.html
![页面截图](screenshots/wearable/notification.jpg)
**功能说明:** 管理向穿戴设备用户发送的通知消息。
**表格列:** 序号、通知标题、通知范围、目标人数、已读人数、发送时间、操作
**交互说明:**
- 点击"发送通知"打开发送通知弹窗(标题/内容/通知范围)
- 点击"查看详情"打开通知详情弹窗
- 点击"阅读统计"打开已读/未读人员列表弹窗
---
### 20. 部门数据统计(wearable/dept-stat.html
![页面截图](screenshots/wearable/dept-stat.jpg)
**功能说明:** 以部门为维度统计穿戴设备的佩戴情况和异常数据。
**Tab切换:** 部门佩戴统计 / 员工每日明细
**部门佩戴统计表格列:** 序号、单位名称、部门名称、分配设备数、今日佩戴人数、佩戴率、心率异常人数、血氧异常人数、体温异常人数
**员工每日明细表格列:** 序号、员工姓名、员工编号、部门名称、佩戴时长、数据上报次数、是否有异常
**交互说明:**
- 支持导出列表数据
---
### 21. 部门报表(wearable/dept-report.html
![页面截图](screenshots/wearable/dept-report.jpg)
**功能说明:** 按月生成部门维度的穿戴监测报表,支持按组织结构树选择部门查看报表状态。
**筛选条件:** 日期年份(下拉)
**表格列:** 月份、报告状态(标签)、报告生成时间、报告下载(按钮)、操作
**业务规则:**
- 左侧为树形组织结构选择面板
- 报告状态:已生成(绿色)、生成中(蓝色)、未生成(灰色)
**交互说明:**
- 点击左侧组织树节点切换部门
- 点击"报告下载"下载已生成的报表文件
- 操作列:生成报告、强制结束
---
### 22. 个人数据统计(wearable/personal-stat.html
![页面截图](screenshots/wearable/personal-stat.jpg)
**功能说明:** 以天为维度统计每位员工的心率、血氧、体温的最大值/最小值/平均值及步数、有效佩戴时段。
**筛选条件:** 员工姓名(输入框)、所属单位(下拉)、统计日期(日期选择)
**表格列(多级表头):**
- 员工姓名、员工编号、所属单位
- 心率:最大值、最小值、平均值
- 血氧:最大值、最小值、平均值
- 体温:最大值、最小值、平均值
- 步数、有效佩戴时段
**业务规则:**
- 异常值红色标注
**交互说明:**
- 支持导出列表数据
---
## 四、体重监测
### 23-38. 设备管理与监测数据(4类设备×4页面)
体重监测模块包含4类设备(体重秤、蓝牙称、体脂仪、运动器械),每类设备均有相同的页面结构:设备列表、新增设备弹窗、监测数据列表、监测详情。
#### 设备列表页(scale-device / bluetooth-device / fat-device / sport-device
![体重秤设备](screenshots/weight/scale-device.jpg)
**功能说明:** 管理对应类型的体重监测设备,支持设备的增删改查。
**筛选条件:** 设备编码(输入框)、设备名称(输入框)、所属单位(下拉)、设备状态(下拉)
**表格列:** 序号、设备编码、设备名称、设备厂商、设备型号、所属单位、布放位置、入库日期、设备状态、操作
**业务规则:**
- 设备状态:在线(绿色)、离线(灰色)、故障(红色)
- 运动器械设备额外增加"设备类型"列
**交互说明:**
- 点击"新增"打开新增设备弹窗
- 操作列:编辑、删除
- 支持导出列表数据
#### 监测数据页(scale-monitor / bluetooth-monitor / fat-monitor / sport-monitor
![体重秤监测](screenshots/weight/scale-monitor.jpg)
**功能说明:** 展示对应设备类型采集的监测数据列表。
**筛选条件:** 员工姓名(输入框)、设备编码(输入框)、监测日期(日期范围)
**表格列:** 序号、员工姓名、员工编号、设备编码、体重(kg)、BMI、体脂率(%)、监测时间、操作
**交互说明:**
- 点击"查看详情"跳转到监测详情页
- 支持导出列表数据
#### 监测详情页(scale-monitor-detail / bluetooth-monitor-detail / fat-monitor-detail / sport-monitor-detail
**功能说明:** 展示单次监测的详细数据和历史趋势。
---
### 39. 员工数据(weight/employee-data.html
![页面截图](screenshots/weight/employee-data.jpg)
**功能说明:** 以员工为维度展示体重监测汇总数据。
**筛选条件:** 员工姓名(输入框)、员工编号(输入框)、所属单位(下拉)
**表格列:** 序号、员工姓名、员工编号、所属单位、所属部门、最新体重(kg)、BMI、体脂率(%)、最后测量时间、操作
**交互说明:**
- 点击"查看记录"跳转到员工数据记录页
---
### 40. 员工数据记录(weight/employee-data-record.html
![页面截图](screenshots/weight/employee-data-record.jpg)
**功能说明:** 展示单个员工的体重监测历史测量记录。
**筛选条件:** 测量设备(下拉)、测量日期(日期范围)
**表格列:** 测量时间、测量设备、设备编码、身高、体重、BMI、基础代谢、体脂肪量、体脂肪率、体水分量、蛋白质量、操作
**交互说明:**
- 点击"查看"打开测量详情弹窗
---
### 41. 员工统计(weight/employee-stat.html
![页面截图](screenshots/weight/employee-stat.jpg)
**功能说明:** 以员工为维度统计各类体重监测设备的使用频次。
**筛选条件:** 年份(下拉)、姓名(输入框)、员工编号(输入框)、单位部门(下拉)
**表格列:** 姓名、员工编号、性别、年龄、所属单位、所属部门、体重秤使用次数↕、蓝牙称使用次数↕、体脂仪使用次数↕、运动器械使用次数↕
**交互说明:**
- 表头支持排序
- 支持导出列表数据
---
### 42. 部门统计(weight/dept-stat.html
![页面截图](screenshots/weight/dept-stat.jpg)
**功能说明:** 以部门为维度统计各类体重监测设备的配置和使用情况。
**Tab切换:** 二级单位 / 三级单位
**筛选条件:** 年份(下拉)、所属单位(下拉)、所属部门(下拉,仅三级单位Tab)
**表格列(多级表头):**
- 单位、部门(三级单位)、总人数
- 体重秤:设备数量、使用次数、使用人数
- 蓝牙称:设备数量、使用次数、使用人数
- 体脂仪:设备数量、使用次数、使用人数
- 运动器械:设备数量、使用次数、使用人数
**交互说明:**
- Tab切换二级/三级单位维度
- 表头支持排序
- 支持导出列表数据
---
## 五、环境监测
环境监测模块包含4种监测类型(室内、室外、水质、花粉),每种类型均有相同的页面结构。以下以室内为例说明,其他类型结构相同。
### 43. 设备列表(environment/indoor-device-list.html
![页面截图](screenshots/environment/indoor-device-list.jpg)
**功能说明:** 管理室内环境监测设备,支持设备的增删改查和状态管理。
**筛选条件:** 设备编码(输入框)、设备名称(输入框)、所属单位(下拉)、设备状态(下拉)
**表格列:** 序号、设备名称、设备编码、设备分类、所属单位、设备位置、布点日期、监测时长(天)、设备状态、操作
**交互说明:**
- 支持新增、编辑、删除设备
- 支持导出列表数据
---
### 44. 设备分类(environment/indoor-device-category.html
![页面截图](screenshots/environment/indoor-device-category.jpg)
**功能说明:** 管理环境监测设备的分类及各监测指标的阈值配置。
**筛选条件:** 分类名称(输入框)
**表格列:** 分类名称、温度阈值(min~max)、湿度阈值、CO₂阈值、甲醛阈值、PM2.5阈值、PM10阈值、操作
**交互说明:**
- 点击"新增"打开右侧抽屉弹窗(含阈值设置表单)
- 点击"编辑"打开编辑抽屉弹窗
- 操作列:编辑、删除
---
### 45. 数据分析(environment/indoor-data-analysis.html
![页面截图](screenshots/environment/indoor-data-analysis.jpg)
**功能说明:** 以可视化图表展示单个设备的环境监测数据趋势分析。
**业务规则:**
- 左侧为设备卡片列表,右侧为趋势折线图
- 支持按时间范围切换:近24小时、近7日、近30日、近3个月
- 支持按监测类型切换:温度、湿度、CO₂、甲醛、PM2.5、PM10
**交互说明:**
- 点击左侧设备卡片切换当前分析设备
- 点击时间范围Tab切换图表数据
- 点击监测类型按钮切换图表指标
- 返回按钮跳转回数据监测列表
---
### 46. 数据监测(environment/indoor-data-monitor.html
![页面截图](screenshots/environment/indoor-data-monitor.jpg)
**功能说明:** 实时展示所有环境监测设备的当前监测数据。
**筛选条件:** 设备名称(输入框)、设备编码(输入框)、所属单位(下拉)、空气质量指数(下拉)
**表格列:** 设备名称、设备编码、所属单位、设备位置、数据更新时间、温度、湿度、CO₂、甲醛、PM2.5、PM10、空气质量指数(标签)、操作
**业务规则:**
- 空气质量指数标签:优(绿色)、良(蓝色)、轻度污染(橙色)、中度污染(红色)
**交互说明:**
- 点击"动态分析"跳转到数据分析页面
- 支持导出列表数据
---
### 47. 异常报警(environment/indoor-exception-alarm.html
![页面截图](screenshots/environment/indoor-exception-alarm.jpg)
**功能说明:** 展示环境监测设备触发的报警事件列表。
**筛选条件:** 设备编码(输入框)、报警类型(下拉)、报警时间(日期范围)
**表格列:** 序号、设备名称、设备编码、监测类型、报警值、阈值、报警时间、报警位置、操作
**交互说明:**
- 支持导出列表数据
---
### 48. APP记录(environment/indoor-app-record.html
![页面截图](screenshots/environment/indoor-app-record.jpg)
**功能说明:** 统计员工通过APP查看环境数据的点击次数,按设备维度汇总。
**筛选条件:** 设备名称(输入框)、设备编码(输入框)、所属单位(下拉)
**表格列:** 设备名称、设备编码、所属单位、设备位置、温度点击次数、湿度点击次数、CO₂点击次数、甲醛点击次数、PM2.5点击次数、PM10点击次数、总点击次数↕
**交互说明:**
- 表头支持排序
- 支持导出列表数据
---
### 49-51. 历史数据与详情
#### 历史数据(environment/indoor-history-data.html
![页面截图](screenshots/environment/indoor-history-data.jpg)
**功能说明:** 查询环境监测设备的历史数据记录,支持按设备和时间范围筛选。
**筛选条件:** 设备名称(输入框)、设备编码(输入框)、所属单位(下拉)
**表格列:** 设备名称、设备编码、所属单位、设备位置、监测日期、监测时长(天)、监测数据(链接)、异常数据(链接)
**交互说明:**
- 点击"监测数据"链接跳转到历史监测详情页
- 点击"异常数据"链接跳转到历史报警详情页
- 支持导出列表数据
#### 历史监测详情(environment/indoor-history-monitor-detail.html
**功能说明:** 展示单个设备某时段的详细监测数据和趋势图。
#### 历史报警详情(environment/indoor-history-alarm-detail.html
**功能说明:** 展示单次报警事件的详细信息,包含报警前后的数据变化。
---
### 79. 花粉知识(environment/pollen-knowledge.html
![页面截图](screenshots/environment/pollen-knowledge.jpg)
**功能说明:** 管理花粉相关的科普知识文章,供员工端APP展示。仅花粉监测类型独有此页面。
**筛选条件:** 文章标题(输入框)
**表格列:** 文章标题、封面图、文章内容(预览)、创建日期、查看次数、排序、状态(标签)、操作
**业务规则:**
- 状态标签:已发布(绿色)、草稿(灰色)
**交互说明:**
- 点击"新增"打开右侧抽屉弹窗(含富文本编辑器)
- 点击"编辑"打开编辑抽屉弹窗
- 操作列:编辑、删除
---
## 六、异常事件
### 80. 系统脏数据(exception-dirty.html
![页面截图](screenshots/exception-dirty.jpg)
**功能说明:** 展示系统中检测到的脏数据记录,供管理员排查和清理。
**筛选条件:** 业务模块(下拉)、异常类型(下拉)、年份(下拉)
**表格列:** 业务模块、异常类型(标签)、异常描述、异常检测时间、表名、字段名、编号、异常值(高亮)、数据产生时间
**交互说明:**
- 支持导出列表数据
---
### 81. 结果异常(exception-result.html
![页面截图](screenshots/exception-result.jpg)
**功能说明:** 汇总展示各业务模块产生的结果异常数据,支持多维度筛选。
**筛选条件:** 员工名称(输入框)、员工编号(输入框)、单位部门(下拉)、业务模块(下拉:全部/健康排查/穿戴监测/体重监测/环境监测)、异常等级(下拉:全部/严重/中等/轻微)、年份(下拉)
**表格列:** 员工、员工编号、单位名称、部门名称、业务模块、异常指标、异常值、异常等级、发现时间
**业务规则:**
- 异常等级标签:严重(红色)、中等(橙色)、轻微(灰色)
**交互说明:**
- 支持导出列表数据
Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

+36 -12
View File
@@ -115,6 +115,24 @@ tbody tr:hover{background:#F8FBFF;}
<!-- 筛选栏 -->
<div class="filter-bar">
<div class="filter-item">
<label>员工名称</label>
<input class="filter-select" type="text" placeholder="请输入员工名称" style="min-width:140px;padding-right:12px;background-image:none;">
</div>
<div class="filter-item">
<label>员工编号</label>
<input class="filter-select" type="text" placeholder="请输入员工编号" style="min-width:140px;padding-right:12px;background-image:none;">
</div>
<div class="filter-item">
<label>单位部门</label>
<select class="filter-select">
<option>全部</option>
<option>采油一厂</option>
<option>采油二厂</option>
<option>采气一厂</option>
<option>天然气处理厂</option>
</select>
</div>
<div class="filter-item">
<label>业务模块</label>
<select class="filter-select">
@@ -159,65 +177,71 @@ tbody tr:hover{background:#F8FBFF;}
<thead>
<tr>
<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>张伟</td>
<td>CQ001023</td>
<td>采油一厂</td>
<td>研发部</td>
<td>体重监测</td>
<td>BMI异常</td>
<td>28.5</td>
<td><span class="tag tag-orange">中等</span></td>
<td>2026-05-14 10:30</td>
<td><span class="tag tag-gray">未处理</span></td>
<td><a class="link" href="#">标记处理</a></td>
</tr>
<tr>
<td>李娜</td>
<td>CQ002156</td>
<td>采油二厂</td>
<td>市场部</td>
<td>穿戴监测</td>
<td>心率异常</td>
<td>125 bpm</td>
<td><span class="tag tag-red">严重</span></td>
<td>2026-05-13 14:22</td>
<td><span class="tag tag-green">已处理</span></td>
<td><a class="link" href="#">查看详情</a></td>
</tr>
<tr>
<td>王磊</td>
<td>CQ002301</td>
<td>采气一厂</td>
<td>运营部</td>
<td>健康排查</td>
<td>积分异常</td>
<td>0分</td>
<td><span class="tag tag-orange">中等</span></td>
<td>2026-05-12 09:15</td>
<td><span class="tag tag-gray">未处理</span></td>
<td><a class="link" href="#">标记处理</a></td>
</tr>
<tr>
<td>赵敏</td>
<td>CQ003088</td>
<td>天然气处理厂</td>
<td>财务部</td>
<td>环境监测</td>
<td>温度异常</td>
<td>38.2°C</td>
<td><span class="tag tag-red">严重</span></td>
<td>2026-05-11 16:45</td>
<td><span class="tag tag-green">已处理</span></td>
<td><a class="link" href="#">查看详情</a></td>
</tr>
<tr>
<td>陈刚</td>
<td>CQ004210</td>
<td>采油一厂</td>
<td>采购部</td>
<td>穿戴监测</td>
<td>血氧异常</td>
<td>92%</td>
<td><span class="tag tag-orange">轻微</span></td>
<td>2026-05-10 11:20</td>
<td><span class="tag tag-gray">未处理</span></td>
<td><a class="link" href="#">标记处理</a></td>
</tr>
</tbody>
</table>
@@ -141,9 +141,9 @@
<tr>
<th>单位名称</th>
<th>员工总数</th>
<th>打卡人数</th>
<th>打卡人数</th>
<th>打卡日期</th>
<th>签到人数</th>
<th>签到人数</th>
<th>签到日期</th>
<th>操作</th>
</tr>
</thead>
@@ -156,7 +156,7 @@
<div class="modal-mask" id="recordModal">
<div class="modal">
<div class="modal__header">
<h3 id="recordTitle">打卡记录</h3>
<h3 id="recordTitle">签到记录</h3>
<button class="modal__close" onclick="closeModal()">×</button>
</div>
<div class="modal__body">
@@ -170,8 +170,8 @@
<th>员工编号</th>
<th>单位名称</th>
<th>部门名称</th>
<th>是否打卡</th>
<th>打卡时间</th>
<th>是否签到</th>
<th>签到时间</th>
</tr>
</thead>
<tbody id="recordTbody"></tbody>
@@ -183,6 +183,36 @@
</div>
</div>
<!-- 员工列表弹窗 -->
<div class="modal-mask" id="employeeModal">
<div class="modal">
<div class="modal__header">
<h3 id="employeeTitle">员工列表</h3>
<button class="modal__close" onclick="closeEmployeeModal()">×</button>
</div>
<div class="modal__body">
<div style="display:flex;justify-content:flex-end;margin-bottom:12px;">
<button class="btn btn-default" onclick="showToast('导出成功')">导出</button>
</div>
<table>
<thead>
<tr>
<th>员工姓名</th>
<th>员工编号</th>
<th>单位名称</th>
<th>部门名称</th>
<th id="signTimeHeader" style="display:none;">签到时间</th>
</tr>
</thead>
<tbody id="employeeTbody"></tbody>
</table>
</div>
<div class="modal__footer">
<button class="btn btn-default" onclick="closeEmployeeModal()">关闭</button>
</div>
</div>
</div>
<div class="toast" id="toast"></div>
<script>
function toggleSubgroup(h){h.parentElement.classList.toggle('open');}
@@ -217,12 +247,12 @@ function renderTable(data){
html+='<tr>';
html+='<td>'+d.unit+'</td>';
html+='<td>'+d.total+'</td>';
html+='<td style="color:var(--success);font-weight:500;">'+d.checked+'</td>';
html+='<td style="color:var(--danger);font-weight:500;">'+d.unchecked+'</td>';
html+='<td><span class="link" onclick="openEmployeeModal('+i+', \'checked\')">'+d.checked+'</span></td>';
html+='<td><span class="link" onclick="openEmployeeModal('+i+', \'unchecked\')">'+d.unchecked+'</span></td>';
html+='<td>'+d.date+'</td>';
html+='<td><span class="link" onclick="showToast(\'导出成功\')">按日导出</span>';
html+='<span style="color:var(--border);margin:0 6px;">|</span>';
html+='<span class="link" onclick="openRecordModal('+i+')">打卡记录</span></td>';
html+='<span class="link" onclick="openRecordModal('+i+')">签到记录</span></td>';
html+='</tr>';
});
document.getElementById('tbody').innerHTML=html||'<tr><td colspan="6" style="text-align:center;padding:40px;color:var(--text-placeholder);">暂无数据</td></tr>';
@@ -244,7 +274,7 @@ function resetFilter(){
function openRecordModal(idx){
var d=deptData[idx];
document.getElementById('recordTitle').textContent=d.unit+' - 打卡记录';
document.getElementById('recordTitle').textContent=d.unit+' - 签到记录';
var html='';
recordData.forEach(function(r){
var checkedColor=r.checked==='是'?'var(--success)':'var(--danger)';
@@ -262,6 +292,41 @@ function openRecordModal(idx){
}
function closeModal(){document.getElementById('recordModal').classList.remove('show');}
function openEmployeeModal(idx, type){
var d=deptData[idx];
var isChecked=type==='checked';
var title=d.unit+' - '+(isChecked?'已签到':'未签到')+'员工列表';
document.getElementById('employeeTitle').textContent=title;
var signTimeHeader=document.getElementById('signTimeHeader');
if(isChecked){
signTimeHeader.style.display='';
}else{
signTimeHeader.style.display='none';
}
var html='';
recordData.forEach(function(r){
var isMatch=(isChecked&&r.checked==='是')||(isChecked===false&&r.checked==='否');
if(isMatch){
html+='<tr>';
html+='<td>'+r.name+'</td>';
html+='<td>'+r.code+'</td>';
html+='<td>'+r.unit+'</td>';
html+='<td>'+r.dept+'</td>';
if(isChecked){
html+='<td>'+r.time+'</td>';
}
html+='</tr>';
}
});
document.getElementById('employeeTbody').innerHTML=html||'<tr><td colspan="'+(isChecked?5:4)+'" style="text-align:center;padding:40px;color:var(--text-placeholder);">暂无数据</td></tr>';
document.getElementById('employeeModal').classList.add('show');
}
function closeEmployeeModal(){document.getElementById('employeeModal').classList.remove('show');}
function showToast(msg){
var t=document.getElementById('toast');
t.textContent=msg;t.classList.add('show');
@@ -272,6 +337,7 @@ initUnitSelect();
renderTable(deptData);
document.getElementById('recordModal').addEventListener('click',function(e){if(e.target===this)closeModal();});
document.getElementById('employeeModal').addEventListener('click',function(e){if(e.target===this)closeEmployeeModal();});
</script>
</body>
</html>
@@ -133,14 +133,10 @@
</div>
<div class="filter-item">
<span class="filter-item__label">单位部门</span>
<div class="cascade-wrap">
<select class="form-control" id="filterUnit" onchange="onUnitChange()">
<option value="">选择单位</option>
<option value="">选择</option>
</select>
<select class="form-control" id="filterDept">
<option value="">选择部门</option>
</select>
</div>
</div>
<button class="btn btn-primary" onclick="filterTable()">查询</button>
<button class="btn btn-default" onclick="resetFilter()">重置</button>
@@ -204,7 +200,7 @@
<div class="modal-mask" id="recordModal">
<div class="modal modal-lg">
<div class="modal__header">
<h3>打卡记录</h3>
<h3>签到记录</h3>
<button class="modal__close" onclick="closeModal('recordModal')">×</button>
</div>
<div class="modal__body">
@@ -212,7 +208,7 @@
<table>
<thead>
<tr>
<th>打卡时间</th>
<th>签到时间</th>
<th>增加积分</th>
<th>完成状态</th>
<th>操作</th>
@@ -294,7 +290,7 @@ var surveyAnswers=[
// 初始化单位下拉
function initUnitSelect(){
var s=document.getElementById('filterUnit');
s.innerHTML='<option value="">选择单位</option>';
s.innerHTML='<option value="">选择</option>';
orgTree.forEach(function(o){s.innerHTML+='<option>'+o.label+'</option>';});
}
function onUnitChange(){
@@ -319,7 +315,7 @@ function renderTable(data){
html+='<td>'+e.lastTime+'</td>';
html+='<td><span class="link" onclick="openExportModal('+idx+')">按月导出</span>';
html+='<span style="color:var(--border);margin:0 6px;">|</span>';
html+='<span class="link" onclick="openRecordModal('+idx+')">打卡记录</span></td>';
html+='<span class="link" onclick="openRecordModal('+idx+')">签到记录</span></td>';
html+='</tr>';
});
document.getElementById('tbody').innerHTML=html||'<tr><td colspan="8" style="text-align:center;padding:40px;color:var(--text-placeholder);">暂无数据</td></tr>';
@@ -183,7 +183,7 @@
<th>设备编码</th>
<th>告警类型</th>
<th>告警值</th>
<th>参考范围</th>
<th>阈值范围</th>
<th>告警时间</th>
<th>告警位置</th>
<th>操作</th>
@@ -102,10 +102,7 @@
<a href="dept-report.html" class="sidebar-item">单位数据分析报告</a>
</aside>
<main class="main">
<div class="info-tip">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" style="flex-shrink:0;margin-top:1px;"><circle cx="7" cy="7" r="6" stroke="#1890FF" stroke-width="1.5"/><path d="M7 6v4M7 4.5v.5" stroke="#1890FF" stroke-width="1.5" stroke-linecap="round"/></svg>
统计每位员工在所选日期范围内的设备佩戴情况,包括应佩戴天数、实际佩戴天数及最大连续未佩戴天数。
</div>
<!-- 筛选栏 -->
<div class="filter-bar">
<div class="filter-item">