fix: 更新健康监测文档和页面,删除活动统计页

This commit is contained in:
liuyunqin
2026-07-13 18:57:55 +08:00
parent a11702f727
commit 80722a05e0
67 changed files with 1294 additions and 951 deletions
+32 -36
View File
@@ -33,7 +33,7 @@
│ ├── 水质监测(达标/未达标 · 6项指标)
│ └── 花粉监测(5级评价 · 8种花粉+总数)
├── 设备详情(依 Tab 切换指标下拉、阈值线与等级文案)
└── 报警数据(依 Tab 切换可选报警类型与阈值范围
└── 报警数据(依 Tab 切换展示不同类型报警,支持按年月筛选
```
## 页面清单
@@ -225,17 +225,17 @@
**功能说明:** 穿戴设备监测数据的主页,展示设备连接状态和各项健康指标的最新数据卡片网格。
**主要UI元素:**
- 设备连接状态栏(设备图标、设备名称如"华为 WATCH GT5 Pro"、设备序列号、连接状态
- 设备连接状态栏(手表图标、设备名称如"华为 WATCH GT5 Pro"、设备序列号如"SF55996622586"
- 监测卡片网格(2列布局,共9张卡片):
- 步数卡片(当前步数、距离换算、同步时间)
- 睡眠卡片(睡眠时长、平均睡眠参考、同步时间)
- 心率卡片(当前心率、范围值、同步时间)
- 体温卡片(当前体温、范围值、同步时间)
- 血氧卡片(当前血氧、范围值、同步时间)
- 压力卡片(当前压力值、范围值、同步时间)
- 血压卡片(收缩压/舒张压、状态标签、同步时间。手表不支持时,隐藏该模块
- 心电图卡片(心率值、分类结果标签、同步时间。手表不支持时,隐藏该模块
- 锻炼卡片(锻炼次数/时长/消耗统计、同步时间)
- 步数卡片(当前步数 8,562、距离换算"相当于步行5.2公里"、同步时间)
- 睡眠卡片(睡眠时长 7h 32min、平均睡眠参考"平均睡眠8小时57分"、同步时间)
- 心率卡片(当前心率 72 bpm、范围值 89~120、同步时间)
- 体温卡片(当前体温 36.5℃、范围值 36.2~37.1℃、同步时间)
- 血氧卡片(当前血氧 98%、范围值 95~99%、同步时间)
- 压力卡片(当前压力值 42、范围值 18~82、同步时间)
- 血压卡片(收缩压/舒张压 120/78 mmHg、状态标签"正常"、同步时间)
- 心电图卡片(心率 75 次/分钟、分类结果标签"窦性心律"、同步时间
- 锻炼卡片(消耗 680 千卡、锻炼时长 52 分钟、同步时间)
**交互说明:**
- 点击各卡片进入对应详情页面
@@ -269,18 +269,17 @@
**功能说明:** 展示心率预警记录列表,支持按年份和月份筛选。
**主要UI元素:**
- 预警记录列表标题(含总条数)
- 筛选按钮
- 预警记录卡片(时间、等级、数值、持续时长、触发原因、右侧阈值范围显示)
- 时间筛选弹窗(年份/月份下拉
- 预警记录列表标题(含总条数,如"预警记录(共 3 条)"
- 筛选按钮(显示当前筛选年月,如"2026-4"
- 预警记录卡片
- 预警时间(如"2026-04-28 16:32"
- 预警数值(如"142 bpm"
- 时间筛选弹窗(年份/月份下拉选择,取消/确定按钮)
**业务规则:**
- 预警等级:严重(红色)、警告(橙色)
- 每条预警卡片右侧显示正常阈值范围参考
**交互说明:**
- 点击筛选按钮打开时间筛选弹窗
- 选择年份和月份后点击"确定"应用筛选
- 选择年份和月份后点击"确定"应用筛选,卡片列表按所选年月过滤
---
@@ -288,7 +287,7 @@
**血氧详情(wearable/blood-oxygen.html):** 展示血氧监测数据,图表采用柱状图形式,支持日/周/月/年多时间维度查看,底部时间轴滑块可交互选择具体时间点。
**血氧预警历史(wearable/blood-oxygen-alerts.html):** 页面结构与心率预警历史一致,展示血氧预警记录列表,每条卡片右侧显示正常阈值范围
**血氧预警历史(wearable/blood-oxygen-alerts.html):** 展示血氧预警记录列表,支持按年月筛选。页面结构与心率预警历史一致,区别在于确定按钮为绿色主题。示例数据:1条记录(2026年3月),93%(严重)
![血氧详情](screenshots/wearable/blood-oxygen.jpg)
![血氧预警](screenshots/wearable/blood-oxygen-alerts.jpg)
@@ -302,13 +301,13 @@
**血压详情(wearable/blood-pressure.html):** 展示收缩压/舒张压双线图表,统计卡片分别显示收缩压和舒张压的最高/最低值。
**血压预警历史(wearable/blood-pressure-alerts.html):** 预警记录卡片同时显示收缩压舒张压数值,右侧显示正常阈值范围。
**血压预警历史(wearable/blood-pressure-alerts.html):** 预警记录以"收缩压/舒张压"格式显示(如"158/98 mmHg"),支持按年月筛选。示例数据:4条记录(2026年5月)
---
### 14-15. 体温详情与预警历史
**体温详情(wearable/temperature.html****体温预警历史(wearable/temperature-alerts.html** 的页面结构与心率一致,预警历史页面每条卡片右侧显示正常阈值范围
**体温详情(wearable/temperature.html****体温预警历史(wearable/temperature-alerts.html** 的页面结构与心率一致。
![体温详情](screenshots/wearable/temperature.jpg)
![体温预警](screenshots/wearable/temperature-alerts.jpg)
@@ -317,7 +316,7 @@
### 16-17. 压力详情与预警历史
**压力详情(wearable/stress.html****压力预警历史(wearable/stress-alerts.html** 的页面结构与心率一致额外显示压力等级评估徽章,预警历史页面每条卡片右侧显示正常阈值范围
**压力详情(wearable/stress.html****压力预警历史(wearable/stress-alerts.html** 的页面结构与心率一致。压力详情额外显示压力等级评估徽章。
![压力详情](screenshots/wearable/stress.jpg)
![压力预警](screenshots/wearable/stress-alerts.jpg)
@@ -452,9 +451,6 @@
**典型设备:** 空气质量监测站、PM10检测仪、臭氧检测仪、气象参数监测仪、VOC检测仪(共6台示例)
**等级描述(示例):**
- 优:空气质量令人满意,基本无污染
- 严重污染:健康人群运动耐受力降低,有明显强烈症状,提前出现某些疾病
##### 23.1.1 设备底部弹窗
@@ -609,47 +605,47 @@
![页面截图](screenshots/environment/alarm-data.jpg)
**功能说明:** 展示环境监测设备的报警记录,支持按日期范围和报警类型筛选。页面根据 URL 参数 `tab` 决定可选报警类型与展示的报警列表。
**功能说明:** 展示环境监测设备的报警记录,支持按时间筛选。页面根据 URL 参数 `tab`outdoor/indoor/water/pollen)决定展示的报警类型与数据列表。
**通用 UI 元素:**
- 筛选区:日期范围(起始/结束日期选择器)、类型下拉、重置按钮、查询按钮
- 统计条:报警总条数(红色突出)
- 报警卡片列表:左侧红色边条,顶部"{指标} 超标报警" + 时间,中部报警值(红底)→ 阈值范围(灰底),底部设备名称/位置
- 筛选按钮(显示当前年月,如"2026-5"
- 报警卡片列表:左侧红色边条,顶部"{指标} 超标报警" + 时间,中部"报警值(数值+单位)› 阈值范围(min~max+单位)"
- 数据通过 JavaScript 动态渲染
**通用交互说明:**
- 设置日期范围和类型后点击"查询"筛选
- 点击"重置"恢复默认日期与类型筛选条件
- 点击筛选按钮打开时间筛选弹窗,选择年月后确定
- 列表为空时显示"暂无报警数据"占位
**业务规则:**
- 报警值高于阈值上限或低于阈值下限时进入报警列表
- 报警卡片同时呈现实际值与允许阈值范围(min~max),便于直观判断超标幅度
- 报警卡片同时呈现实际值与允许阈值范围(min~max),直观判断超标幅度
#### 25.1 室外空气
![室外空气报警数据](screenshots/environment/alarm-data-outdoor.jpg)
**可选报警类型:** PM2.5、PM10、温度、湿度、风速、太阳辐射、照度
**示例数据(8条,2026年5月):** PM2.5156 μg/m³,阈值 0~75)、PM10218 μg/m³,阈值 0~150)、风速(13.5 m/s,阈值 0~10)、太阳辐射(1180 W/m²,阈值 0~1000)、温度(42.3℃,阈值 -10~40)、PM2.5195 μg/m³)、PM10285 μg/m³)、照度(98500 lm/m²,阈值 0~95000
#### 25.2 室内空气
![室内空气报警数据](screenshots/environment/alarm-data-indoor.jpg)
**可选报警类型:** PM2.5、PM10、CO₂、甲醛、温度、湿度
**示例数据(6条,2026年5月):** CO₂(1250 ppm,阈值 400~1000)、甲醛(0.15 mg/m³,阈值 0~0.10)、PM2.5135 μg/m³,阈值 0~75)、CO₂(980 ppm,敏感场所阈值 400~800)、湿度(85%,阈值 30~80)、甲醛(0.12 mg/m³)
#### 25.3 水质监测
![水质监测报警数据](screenshots/environment/alarm-data-water.jpg)
**可选报警类型:** PH、电导率、盐度、TDS、电阻率、温度
**示例数据(6条,2026年5月):** 电导率(1250 μS/cm,阈值 50~1000)、PH8.5,阈值 6.5~8.0)、TDS840 mg/L,阈值 0~500)、盐度(920 mg/L,阈值 0~500)、电导率(1680 μS/cm)、PH9.2
#### 25.4 花粉监测
![花粉监测报警数据](screenshots/environment/alarm-data-pollen.jpg)
**可选报警类型:** 花粉总数
**示例数据(3条,2026年5月):** 花粉总数(1098、924、860 粒/千mm²,阈值 0~800
> 备注:花粉监测仅对"花粉总数"设置统一报警阈值,各属/科单一指标暂不单独报警。
Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 10 KiB

@@ -15,17 +15,159 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
.nav-back { width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; cursor: pointer; }
.nav-title { flex: 1; text-align: center; font-size: 17px; font-weight: 600; color: #1a1a1a; margin-right: 28px; }
/* 筛选 */
.filter-bar { background: #fff; padding: 12px 16px; border-bottom: 1px solid #f0f0f0; flex-shrink: 0; display: flex; flex-direction: column; gap: 8px; }
.filter-row { display: flex; align-items: center; gap: 8px; }
.filter-label { font-size: 12px; color: #999; flex-shrink: 0; }
.filter-date-input { height: 32px; border: 1px solid #e8e8e8; border-radius: 8px; padding: 0 8px; font-size: 12px; color: #333; outline: none; background: #fff; flex: 1; min-width: 0; }
.filter-date-input:focus { border-color: #1aad8d; }
.filter-sep { font-size: 12px; color: #bbb; flex-shrink: 0; }
.filter-select { height: 32px; border: 1px solid #e8e8e8; border-radius: 8px; padding: 0 24px 0 10px; font-size: 12px; color: #333; background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5'%3E%3Cpath d='M0 0l4 5 4-5z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 8px center; appearance: none; outline: none; cursor: pointer; flex: 1; }
.filter-btn { height: 32px; padding: 0 16px; border-radius: 8px; border: none; font-size: 12px; font-weight: 600; cursor: pointer; flex-shrink: 0; }
.filter-btn--primary { background: #1aad8d; color: #fff; }
.filter-btn--reset { background: #f5f5f5; color: #666; }
/* 筛选按钮 */
.filter-btn {
display: flex;
align-items: center;
gap: 4px;
padding: 4px 2px;
border: none;
background: transparent;
font-size: 13px;
color: #333;
font-weight: 600;
cursor: pointer;
}
.filter-btn__arrow {
font-size: 9px;
color: #999;
}
/* 时间筛选弹窗 */
.time-filter-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: none;
z-index: 1000;
}
.time-filter-modal.active {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
}
.time-filter-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.4);
}
.time-filter-panel {
position: relative;
width: 100%;
max-width: 390px;
background: #fff;
border-radius: 16px 16px 0 0;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
animation: slideUp 0.3s ease-out;
}
@keyframes slideUp {
from { transform: translateY(100%); }
to { transform: translateY(0); }
}
.time-filter-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px;
border-bottom: 1px solid #f0f0f0;
font-size: 16px;
font-weight: 600;
color: #1a1a1a;
}
.time-filter-close {
width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
border: none;
background: none;
font-size: 20px;
color: #999;
cursor: pointer;
}
.time-filter-content {
padding: 16px;
display: flex;
flex-direction: column;
gap: 16px;
}
.filter-section {
display: flex;
flex-direction: column;
gap: 8px;
}
.filter-label {
font-size: 13px;
font-weight: 600;
color: #333;
}
.filter-select {
padding: 10px 12px;
border: 1px solid #ddd;
border-radius: 8px;
font-size: 14px;
color: #333;
background: #fff;
cursor: pointer;
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%23666' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 10px center;
padding-right: 32px;
}
.time-filter-footer {
display: flex;
gap: 12px;
padding: 16px;
border-top: 1px solid #f0f0f0;
}
.filter-btn-cancel,
.filter-btn-confirm {
flex: 1;
padding: 12px;
border: none;
border-radius: 8px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
}
.filter-btn-cancel {
background: #f5f5f5;
color: #666;
}
.filter-btn-cancel:active {
background: #e8e8e8;
}
.filter-btn-confirm {
background: #ff7a8a;
color: #fff;
}
.filter-btn-confirm:active {
background: #ff5a7a;
}
/* 统计条 */
.stat-bar { padding: 10px 16px; display: flex; align-items: center; justify-content: space-between; }
@@ -70,42 +212,67 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
<div class="nav-title">报警数据</div>
</div>
<!-- 筛选 -->
<div class="filter-bar">
<div class="filter-row">
<span class="filter-label">日期</span>
<input class="filter-date-input" type="date" id="dateFrom" value="2026-05-01">
<span class="filter-sep"></span>
<input class="filter-date-input" type="date" id="dateTo" value="2026-05-25">
</div>
<div class="filter-row">
<span class="filter-label">类型</span>
<select class="filter-select" id="typeFilter">
<option value="">全部类型</option>
</select>
<button class="filter-btn filter-btn--reset" onclick="resetFilter()">重置</button>
<button class="filter-btn filter-btn--primary" onclick="applyFilter()">查询</button>
</div>
</div>
<!-- 统计 -->
<!-- 统计与筛选 -->
<div class="stat-bar">
<span class="stat-bar__count"><strong id="totalCount">0</strong> 条报警</span>
<button class="filter-btn" id="filterBtn" onclick="openTimeFilter()">
<span id="filterLabel">2026-5</span>
<span class="filter-btn__arrow"></span>
</button>
</div>
<!-- 列表 -->
<div class="list-wrap" id="listWrap"></div>
<!-- 时间筛选弹窗 -->
<div class="time-filter-modal" id="timeFilterModal">
<div class="time-filter-overlay" onclick="closeTimeFilter()"></div>
<div class="time-filter-panel">
<div class="time-filter-header">
<span>选择时间</span>
<button class="time-filter-close" onclick="closeTimeFilter()"></button>
</div>
<div class="time-filter-content">
<!-- 年份选择 -->
<div class="filter-section">
<label class="filter-label">年份</label>
<select id="yearSelect" class="filter-select">
<option value="2026">2026</option>
<option value="2025">2025</option>
<option value="2024">2024</option>
</select>
</div>
<!-- 月份选择 -->
<div class="filter-section">
<label class="filter-label">月份</label>
<select id="monthSelect" class="filter-select">
<option value="01">1月</option>
<option value="02">2月</option>
<option value="03">3月</option>
<option value="04">4月</option>
<option value="05">5月</option>
<option value="06">6月</option>
<option value="07">7月</option>
<option value="08">8月</option>
<option value="09">9月</option>
<option value="10">10月</option>
<option value="11">11月</option>
<option value="12">12月</option>
</select>
</div>
</div>
<div class="time-filter-footer">
<button class="filter-btn-cancel" onclick="closeTimeFilter()">取消</button>
<button class="filter-btn-confirm" onclick="applyTimeFilter()">确定</button>
</div>
</div>
</div>
</div>
<script>
// 各 Tab 报警类型选项
const TYPE_OPTIONS = {
outdoor: ['PM2.5','PM10','温度','湿度','风速','太阳辐射','照度'],
indoor: ['PM2.5','PM10','CO₂','甲醛','温度','湿度'],
water: ['PH','电导率','盐度','TDS','电阻率','温度'],
pollen: ['花粉总数']
};
// 报警数据
const ALARM_DATA = {
outdoor: [
@@ -143,33 +310,34 @@ const ALARM_DATA = {
const params = new URLSearchParams(location.search);
const tab = params.get('tab') || 'outdoor';
const devId = params.get('id') || '';
// 初始化类型下拉
const typeOpts = TYPE_OPTIONS[tab] || [];
const typeSelect = document.getElementById('typeFilter');
typeOpts.forEach(t => {
const o = document.createElement('option');
o.value = t; o.textContent = t;
typeSelect.appendChild(o);
});
let currentYear = '2026';
let currentMonth = '05';
function applyFilter() {
const from = document.getElementById('dateFrom').value;
const to = document.getElementById('dateTo').value;
const type = typeSelect.value;
let list = ALARM_DATA[tab] || [];
if (from) list = list.filter(r => r.time.slice(0,10) >= from);
if (to) list = list.filter(r => r.time.slice(0,10) <= to);
if (type) list = list.filter(r => r.type === type);
renderList(list);
function openTimeFilter() {
document.getElementById('yearSelect').value = currentYear;
document.getElementById('monthSelect').value = currentMonth;
document.getElementById('timeFilterModal').classList.add('active');
}
function resetFilter() {
document.getElementById('dateFrom').value = '2026-05-01';
document.getElementById('dateTo').value = '2026-05-25';
typeSelect.value = '';
applyFilter();
function closeTimeFilter() {
document.getElementById('timeFilterModal').classList.remove('active');
}
function applyTimeFilter() {
currentYear = document.getElementById('yearSelect').value;
currentMonth = document.getElementById('monthSelect').value;
let list = ALARM_DATA[tab] || [];
if (currentYear) list = list.filter(r => r.time.slice(0,4) === currentYear);
if (currentMonth) list = list.filter(r => r.time.slice(5,7) === currentMonth);
renderList(list);
updateFilterLabel();
closeTimeFilter();
}
function updateFilterLabel() {
document.getElementById('filterLabel').textContent = currentYear + '-' + parseInt(currentMonth);
}
function renderList(list) {
@@ -202,8 +370,24 @@ function renderList(list) {
`).join('');
}
// 初始渲染
applyFilter();
// 初始渲染:按默认月份筛选
let list = ALARM_DATA[tab] || [];
if (currentYear) list = list.filter(r => r.time.slice(0,4) === currentYear);
if (currentMonth) list = list.filter(r => r.time.slice(5,7) === currentMonth);
renderList(list);
updateFilterLabel();
// 点击弹窗外部关闭
document.addEventListener('DOMContentLoaded', function() {
const modal = document.getElementById('timeFilterModal');
if (modal) {
modal.addEventListener('click', function(e) {
if (e.target === modal || e.target.classList.contains('time-filter-overlay')) {
closeTimeFilter();
}
});
}
});
</script>
</body>
</html>
Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

@@ -205,41 +205,22 @@ body {
/* 底部安全区 */
.bottom-safe { height: 20px; flex-shrink: 0; }
/* 右侧阈值范围 */
.alert-card__threshold {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 4px;
flex-shrink: 0;
padding-top: 4px;
}
.alert-card__threshold-item {
font-size: 11px;
color: #bbb;
}
.alert-card__threshold-item span {
font-weight: 600;
color: #666;
}
/* 筛选按钮 */
.filter-btn {
display: flex;
align-items: center;
gap: 4px;
padding: 6px 12px;
border: 1px solid #ddd;
border-radius: 6px;
background: #fff;
font-size: 12px;
color: #666;
padding: 4px 2px;
border: none;
background: transparent;
font-size: 13px;
color: #333;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
}
.filter-btn:active {
background: #f5f5f5;
border-color: #bbb;
.filter-btn__arrow {
font-size: 9px;
color: #999;
}
/* 时间筛选弹窗 */
@@ -422,12 +403,9 @@ body {
<!-- 预警记录列表标题 + 筛选按钮 -->
<div style="display: flex; align-items: center; justify-content: space-between; padding: 14px 16px 8px;">
<div class="section-title" style="margin: 0; padding: 0;">预警记录(共 1 条)</div>
<button class="filter-btn" onclick="openTimeFilter()">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="3" y="4" width="18" height="18" rx="2"/>
<path d="M16 2v4M8 2v4M3 10h18"/>
</svg>
筛选
<button class="filter-btn" id="filterBtn" onclick="openTimeFilter()">
<span id="filterLabel">2026-3</span>
<span class="filter-btn__arrow"></span>
</button>
</div>
@@ -448,11 +426,6 @@ body {
<span class="alert-card__value-unit">%</span>
</div>
</div>
<!-- 右侧阈值范围 -->
<div class="alert-card__threshold">
<div class="alert-card__threshold-item">上限 <span>100%</span></div>
<div class="alert-card__threshold-item">下限 <span>95%</span></div>
</div>
</div>
<!-- 底部安全区 -->
@@ -483,7 +456,6 @@ body {
<div class="filter-section">
<label class="filter-label">月份</label>
<select id="monthSelect" class="filter-select">
<option value="">全部</option>
<option value="01">1月</option>
<option value="02">2月</option>
<option value="03">3月</option>
@@ -511,7 +483,12 @@ body {
<script>
// 时间筛选功能
let currentYear = '2026';
let currentMonth = '03';
function openTimeFilter() {
document.getElementById('yearSelect').value = currentYear;
document.getElementById('monthSelect').value = currentMonth;
document.getElementById('timeFilterModal').classList.add('active');
}
@@ -524,29 +501,38 @@ function updateMonths() {
}
function applyTimeFilter() {
const year = document.getElementById('yearSelect').value;
const month = document.getElementById('monthSelect').value;
currentYear = document.getElementById('yearSelect').value;
currentMonth = document.getElementById('monthSelect').value;
// 获取所有预警记录卡片
const alertCards = document.querySelectorAll('.alert-card');
filterCards();
updateFilterLabel();
closeTimeFilter();
}
alertCards.forEach(card => {
const timeText = card.querySelector('.alert-card__time').textContent;
// 格式:2026-03-08 03:22
const [dateStr] = timeText.split(' ');
const [cardYear, cardMonth] = dateStr.split('-');
function filterCards() {
var alertCards = document.querySelectorAll('.alert-card');
alertCards.forEach(function(card) {
var timeText = card.querySelector('.alert-card__time').textContent;
var dateStr = timeText.split(' ')[0];
var parts = dateStr.split('-');
var cardYear = parts[0];
var cardMonth = parts[1];
// 根据筛选条件显示/隐藏
let show = true;
if (year && cardYear !== year) show = false;
if (month && cardMonth !== month) show = false;
var show = true;
if (currentYear && cardYear !== currentYear) show = false;
if (currentMonth && cardMonth !== currentMonth) show = false;
card.style.display = show ? 'flex' : 'none';
});
closeTimeFilter();
}
function updateFilterLabel() {
document.getElementById('filterLabel').textContent = currentYear + '-' + parseInt(currentMonth);
}
// 初始默认筛选
filterCards();
// 点击弹窗外部关闭
document.addEventListener('DOMContentLoaded', function() {
const modal = document.getElementById('timeFilterModal');
@@ -188,37 +188,158 @@ body {
.bottom-safe { height: 20px; flex-shrink: 0; }
/* 右侧阈值范围 */
.alert-card__threshold {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 4px;
flex-shrink: 0;
padding-top: 4px;
}
.alert-card__threshold-item {
font-size: 11px;
color: #bbb;
}
.alert-card__threshold-item span {
font-weight: 600;
color: #666;
}
.filter-btn {
display: flex;
align-items: center;
gap: 4px;
padding: 6px 12px;
border: 1px solid #ddd;
border-radius: 6px;
background: #fff;
font-size: 12px;
color: #666;
padding: 4px 2px;
border: none;
background: transparent;
font-size: 13px;
color: #333;
font-weight: 600;
cursor: pointer;
}
.filter-btn:active { background: #f5f5f5; border-color: #bbb; }
.filter-btn__arrow {
font-size: 9px;
color: #999;
}
/* 时间筛选弹窗 */
.time-filter-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: none;
z-index: 1000;
}
.time-filter-modal.active {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
}
.time-filter-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.4);
}
.time-filter-panel {
position: relative;
width: 100%;
max-width: 390px;
background: #fff;
border-radius: 16px 16px 0 0;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
animation: slideUp 0.3s ease-out;
}
@keyframes slideUp {
from { transform: translateY(100%); }
to { transform: translateY(0); }
}
.time-filter-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px;
border-bottom: 1px solid #f0f0f0;
font-size: 16px;
font-weight: 600;
color: #1a1a1a;
}
.time-filter-close {
width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
border: none;
background: none;
font-size: 20px;
color: #999;
cursor: pointer;
}
.time-filter-content {
padding: 16px;
display: flex;
flex-direction: column;
gap: 16px;
}
.filter-section {
display: flex;
flex-direction: column;
gap: 8px;
}
.filter-label {
font-size: 13px;
font-weight: 600;
color: #333;
}
.filter-select {
padding: 10px 12px;
border: 1px solid #ddd;
border-radius: 8px;
font-size: 14px;
color: #333;
background: #fff;
cursor: pointer;
appearance: none;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%23666' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 10px center;
padding-right: 32px;
}
.time-filter-footer {
display: flex;
gap: 12px;
padding: 16px;
border-top: 1px solid #f0f0f0;
}
.filter-btn-cancel,
.filter-btn-confirm {
flex: 1;
padding: 12px;
border: none;
border-radius: 8px;
font-size: 14px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
}
.filter-btn-cancel {
background: #f5f5f5;
color: #666;
}
.filter-btn-cancel:active {
background: #e8e8e8;
}
.filter-btn-confirm {
background: #ff7a8a;
color: #fff;
}
.filter-btn-confirm:active {
background: #ff5a7a;
}
</style>
</head>
@@ -255,12 +376,9 @@ body {
<div style="display: flex; align-items: center; justify-content: space-between; padding: 14px 16px 8px;">
<div class="section-title" style="margin: 0; padding: 0;">预警记录(共 4 条)</div>
<button class="filter-btn">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="3" y="4" width="18" height="18" rx="2"/>
<path d="M16 2v4M8 2v4M3 10h18"/>
</svg>
筛选
<button class="filter-btn" id="filterBtn" onclick="openTimeFilter()">
<span id="filterLabel">2026-5</span>
<span class="filter-btn__arrow"></span>
</button>
</div>
@@ -278,10 +396,6 @@ body {
<span class="alert-card__value-unit">mmHg</span>
</div>
</div>
<div class="alert-card__threshold">
<div class="alert-card__threshold-item">上限 <span>140/90</span></div>
<div class="alert-card__threshold-item">下限 <span>90/60</span></div>
</div>
</div>
<!-- 预警记录 2:警告 -->
@@ -298,10 +412,6 @@ body {
<span class="alert-card__value-unit">mmHg</span>
</div>
</div>
<div class="alert-card__threshold">
<div class="alert-card__threshold-item">上限 <span>140/90</span></div>
<div class="alert-card__threshold-item">下限 <span>90/60</span></div>
</div>
</div>
<!-- 预警记录 3:警告 -->
@@ -318,10 +428,6 @@ body {
<span class="alert-card__value-unit">mmHg</span>
</div>
</div>
<div class="alert-card__threshold">
<div class="alert-card__threshold-item">上限 <span>140/90</span></div>
<div class="alert-card__threshold-item">下限 <span>90/60</span></div>
</div>
</div>
<!-- 预警记录 4:警告 -->
@@ -338,15 +444,117 @@ body {
<span class="alert-card__value-unit">mmHg</span>
</div>
</div>
<div class="alert-card__threshold">
<div class="alert-card__threshold-item">上限 <span>140/90</span></div>
<div class="alert-card__threshold-item">下限 <span>90/60</span></div>
</div>
</div>
<div class="bottom-safe"></div>
</div>
<!-- 时间筛选弹窗 -->
<div class="time-filter-modal" id="timeFilterModal">
<div class="time-filter-overlay" onclick="closeTimeFilter()"></div>
<div class="time-filter-panel">
<div class="time-filter-header">
<span>选择时间</span>
<button class="time-filter-close" onclick="closeTimeFilter()"></button>
</div>
<div class="time-filter-content">
<div class="filter-section">
<label class="filter-label">年份</label>
<select id="yearSelect" class="filter-select">
<option value="2026">2026</option>
<option value="2025">2025</option>
<option value="2024">2024</option>
</select>
</div>
<div class="filter-section">
<label class="filter-label">月份</label>
<select id="monthSelect" class="filter-select">
<option value="01">1月</option>
<option value="02">2月</option>
<option value="03">3月</option>
<option value="04">4月</option>
<option value="05">5月</option>
<option value="06">6月</option>
<option value="07">7月</option>
<option value="08">8月</option>
<option value="09">9月</option>
<option value="10">10月</option>
<option value="11">11月</option>
<option value="12">12月</option>
</select>
</div>
</div>
<div class="time-filter-footer">
<button class="filter-btn-cancel" onclick="closeTimeFilter()">取消</button>
<button class="filter-btn-confirm" onclick="applyTimeFilter()">确定</button>
</div>
</div>
</div>
</div>
<script>
// 时间筛选功能
let currentYear = '2026';
let currentMonth = '05';
function openTimeFilter() {
document.getElementById('yearSelect').value = currentYear;
document.getElementById('monthSelect').value = currentMonth;
document.getElementById('timeFilterModal').classList.add('active');
}
function closeTimeFilter() {
document.getElementById('timeFilterModal').classList.remove('active');
}
function applyTimeFilter() {
currentYear = document.getElementById('yearSelect').value;
currentMonth = document.getElementById('monthSelect').value;
filterCards();
updateFilterLabel();
closeTimeFilter();
}
function filterCards() {
var alertCards = document.querySelectorAll('.alert-card');
alertCards.forEach(function(card) {
var timeText = card.querySelector('.alert-card__time').textContent;
var dateStr = timeText.split(' ')[0];
var parts = dateStr.split('-');
var cardYear = parts[0];
var cardMonth = parts[1];
var show = true;
if (currentYear && cardYear !== currentYear) show = false;
if (currentMonth && cardMonth !== currentMonth) show = false;
card.style.display = show ? 'flex' : 'none';
});
}
function updateFilterLabel() {
document.getElementById('filterLabel').textContent = currentYear + '-' + parseInt(currentMonth);
}
// 初始默认筛选
filterCards();
// 点击弹窗外部关闭
document.addEventListener('DOMContentLoaded', function() {
const modal = document.getElementById('timeFilterModal');
if (modal) {
modal.addEventListener('click', function(e) {
if (e.target === modal || e.target.classList.contains('time-filter-overlay')) {
closeTimeFilter();
}
});
}
});
</script>
</body>
</html>
@@ -204,41 +204,22 @@ body {
/* 底部安全区 */
.bottom-safe { height: 20px; flex-shrink: 0; }
/* 右侧阈值范围 */
.alert-card__threshold {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 4px;
flex-shrink: 0;
padding-top: 4px;
}
.alert-card__threshold-item {
font-size: 11px;
color: #bbb;
}
.alert-card__threshold-item span {
font-weight: 600;
color: #666;
}
/* 筛选按钮 */
.filter-btn {
display: flex;
align-items: center;
gap: 4px;
padding: 6px 12px;
border: 1px solid #ddd;
border-radius: 6px;
background: #fff;
font-size: 12px;
color: #666;
padding: 4px 2px;
border: none;
background: transparent;
font-size: 13px;
color: #333;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
}
.filter-btn:active {
background: #f5f5f5;
border-color: #bbb;
.filter-btn__arrow {
font-size: 9px;
color: #999;
}
/* 时间筛选弹窗 */
@@ -421,12 +402,9 @@ body {
<!-- 预警记录列表标题 + 筛选按钮 -->
<div style="display: flex; align-items: center; justify-content: space-between; padding: 14px 16px 8px;">
<div class="section-title" style="margin: 0; padding: 0;">预警记录(共 3 条)</div>
<button class="filter-btn" onclick="openTimeFilter()">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="3" y="4" width="18" height="18" rx="2"/>
<path d="M16 2v4M8 2v4M3 10h18"/>
</svg>
筛选
<button class="filter-btn" id="filterBtn" onclick="openTimeFilter()">
<span id="filterLabel">2026-4</span>
<span class="filter-btn__arrow"></span>
</button>
</div>
@@ -447,11 +425,6 @@ body {
<span class="alert-card__value-unit">次/分钟</span>
</div>
</div>
<!-- 右侧阈值范围 -->
<div class="alert-card__threshold">
<div class="alert-card__threshold-item">上限 <span>140 次/分钟</span></div>
<div class="alert-card__threshold-item">下限 <span>50 次/分钟</span></div>
</div>
</div>
<!-- 预警记录 2:警告 - 2026-04-25 -->
@@ -471,11 +444,6 @@ body {
<span class="alert-card__value-unit">次/分钟</span>
</div>
</div>
<!-- 右侧阈值范围 -->
<div class="alert-card__threshold">
<div class="alert-card__threshold-item">上限 <span>120 次/分钟</span></div>
<div class="alert-card__threshold-item">下限 <span>50 次/分钟</span></div>
</div>
</div>
<!-- 预警记录 3:警告 - 2026-04-20 -->
@@ -495,11 +463,6 @@ body {
<span class="alert-card__value-unit">次/分钟</span>
</div>
</div>
<!-- 右侧阈值范围 -->
<div class="alert-card__threshold">
<div class="alert-card__threshold-item">上限 <span>120 次/分钟</span></div>
<div class="alert-card__threshold-item">下限 <span>50 次/分钟</span></div>
</div>
</div>
<!-- 底部安全区 -->
@@ -530,7 +493,6 @@ body {
<div class="filter-section">
<label class="filter-label">月份</label>
<select id="monthSelect" class="filter-select">
<option value="">全部</option>
<option value="01">1月</option>
<option value="02">2月</option>
<option value="03">3月</option>
@@ -558,7 +520,12 @@ body {
<script>
// 时间筛选功能
let currentYear = '2026';
let currentMonth = '04';
function openTimeFilter() {
document.getElementById('yearSelect').value = currentYear;
document.getElementById('monthSelect').value = currentMonth;
document.getElementById('timeFilterModal').classList.add('active');
}
@@ -571,29 +538,38 @@ function updateMonths() {
}
function applyTimeFilter() {
const year = document.getElementById('yearSelect').value;
const month = document.getElementById('monthSelect').value;
currentYear = document.getElementById('yearSelect').value;
currentMonth = document.getElementById('monthSelect').value;
// 获取所有预警记录卡片
const alertCards = document.querySelectorAll('.alert-card');
filterCards();
updateFilterLabel();
closeTimeFilter();
}
alertCards.forEach(card => {
const timeText = card.querySelector('.alert-card__time').textContent;
// 格式:2026-04-28 16:32
const [dateStr] = timeText.split(' ');
const [cardYear, cardMonth] = dateStr.split('-');
function filterCards() {
var alertCards = document.querySelectorAll('.alert-card');
alertCards.forEach(function(card) {
var timeText = card.querySelector('.alert-card__time').textContent;
var dateStr = timeText.split(' ')[0];
var parts = dateStr.split('-');
var cardYear = parts[0];
var cardMonth = parts[1];
// 根据筛选条件显示/隐藏
let show = true;
if (year && cardYear !== year) show = false;
if (month && cardMonth !== month) show = false;
var show = true;
if (currentYear && cardYear !== currentYear) show = false;
if (currentMonth && cardMonth !== currentMonth) show = false;
card.style.display = show ? 'flex' : 'none';
});
closeTimeFilter();
}
function updateFilterLabel() {
document.getElementById('filterLabel').textContent = currentYear + '-' + parseInt(currentMonth);
}
// 初始默认筛选
filterCards();
// 点击弹窗外部关闭
document.addEventListener('DOMContentLoaded', function() {
const modal = document.getElementById('timeFilterModal');
@@ -95,7 +95,7 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
<div class="device-icon"></div>
<div class="device-info">
<div class="device-name">华为 WATCH GT5 Pro</div>
<div class="device-meta">SF55996622586 · 已连接</div>
<div class="device-meta">SF55996622586</div>
</div>
<!-- <div class="device-battery">-->
<!-- <div class="battery-icon"><div class="battery-fill" style="width:72%"></div></div>-->
@@ -209,41 +209,22 @@ body {
/* 底部安全区 */
.bottom-safe { height: 20px; flex-shrink: 0; }
/* 右侧阈值范围 */
.alert-card__threshold {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 4px;
flex-shrink: 0;
padding-top: 4px;
}
.alert-card__threshold-item {
font-size: 11px;
color: #bbb;
}
.alert-card__threshold-item span {
font-weight: 600;
color: #666;
}
/* 筛选按钮 */
.filter-btn {
display: flex;
align-items: center;
gap: 4px;
padding: 6px 12px;
border: 1px solid #ddd;
border-radius: 6px;
background: #fff;
font-size: 12px;
color: #666;
padding: 4px 2px;
border: none;
background: transparent;
font-size: 13px;
color: #333;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
}
.filter-btn:active {
background: #f5f5f5;
border-color: #bbb;
.filter-btn__arrow {
font-size: 9px;
color: #999;
}
/* 时间筛选弹窗 */
@@ -426,12 +407,9 @@ body {
<!-- 预警记录列表标题 + 筛选按钮 -->
<div style="display: flex; align-items: center; justify-content: space-between; padding: 14px 16px 8px;">
<div class="section-title" style="margin: 0; padding: 0;">预警记录(共 2 条)</div>
<button class="filter-btn" onclick="openTimeFilter()">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="3" y="4" width="18" height="18" rx="2"/>
<path d="M16 2v4M8 2v4M3 10h18"/>
</svg>
筛选
<button class="filter-btn" id="filterBtn" onclick="openTimeFilter()">
<span id="filterLabel">2026-4</span>
<span class="filter-btn__arrow"></span>
</button>
</div>
@@ -452,11 +430,6 @@ body {
<span class="alert-card__value-unit">压力值</span>
</div>
</div>
<!-- 右侧阈值范围 -->
<div class="alert-card__threshold">
<div class="alert-card__threshold-item">上限 <span>80</span></div>
<div class="alert-card__threshold-item">下限 <span>0</span></div>
</div>
</div>
<!-- 预警记录 2:严重 - 2026-04-22 15:10,压力值 88 -->
@@ -476,11 +449,6 @@ body {
<span class="alert-card__value-unit">压力值</span>
</div>
</div>
<!-- 右侧阈值范围 -->
<div class="alert-card__threshold">
<div class="alert-card__threshold-item">上限 <span>85</span></div>
<div class="alert-card__threshold-item">下限 <span>0</span></div>
</div>
</div>
<!-- 底部安全区 -->
@@ -511,7 +479,6 @@ body {
<div class="filter-section">
<label class="filter-label">月份</label>
<select id="monthSelect" class="filter-select">
<option value="">全部</option>
<option value="01">1月</option>
<option value="02">2月</option>
<option value="03">3月</option>
@@ -539,7 +506,12 @@ body {
<script>
// 时间筛选功能
let currentYear = '2026';
let currentMonth = '04';
function openTimeFilter() {
document.getElementById('yearSelect').value = currentYear;
document.getElementById('monthSelect').value = currentMonth;
document.getElementById('timeFilterModal').classList.add('active');
}
@@ -552,29 +524,38 @@ function updateMonths() {
}
function applyTimeFilter() {
const year = document.getElementById('yearSelect').value;
const month = document.getElementById('monthSelect').value;
currentYear = document.getElementById('yearSelect').value;
currentMonth = document.getElementById('monthSelect').value;
// 获取所有预警记录卡片
const alertCards = document.querySelectorAll('.alert-card');
filterCards();
updateFilterLabel();
closeTimeFilter();
}
alertCards.forEach(card => {
const timeText = card.querySelector('.alert-card__time').textContent;
// 格式:2026-04-30 16:30
const [dateStr] = timeText.split(' ');
const [cardYear, cardMonth] = dateStr.split('-');
function filterCards() {
var alertCards = document.querySelectorAll('.alert-card');
alertCards.forEach(function(card) {
var timeText = card.querySelector('.alert-card__time').textContent;
var dateStr = timeText.split(' ')[0];
var parts = dateStr.split('-');
var cardYear = parts[0];
var cardMonth = parts[1];
// 根据筛选条件显示/隐藏
let show = true;
if (year && cardYear !== year) show = false;
if (month && cardMonth !== month) show = false;
var show = true;
if (currentYear && cardYear !== currentYear) show = false;
if (currentMonth && cardMonth !== currentMonth) show = false;
card.style.display = show ? 'flex' : 'none';
});
closeTimeFilter();
}
function updateFilterLabel() {
document.getElementById('filterLabel').textContent = currentYear + '-' + parseInt(currentMonth);
}
// 初始默认筛选
filterCards();
// 点击弹窗外部关闭
document.addEventListener('DOMContentLoaded', function() {
const modal = document.getElementById('timeFilterModal');
@@ -204,41 +204,22 @@ body {
/* 底部安全区 */
.bottom-safe { height: 20px; flex-shrink: 0; }
/* 右侧阈值范围 */
.alert-card__threshold {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 4px;
flex-shrink: 0;
padding-top: 4px;
}
.alert-card__threshold-item {
font-size: 11px;
color: #bbb;
}
.alert-card__threshold-item span {
font-weight: 600;
color: #666;
}
/* 筛选按钮 */
.filter-btn {
display: flex;
align-items: center;
gap: 4px;
padding: 6px 12px;
border: 1px solid #ddd;
border-radius: 6px;
background: #fff;
font-size: 12px;
color: #666;
padding: 4px 2px;
border: none;
background: transparent;
font-size: 13px;
color: #333;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
}
.filter-btn:active {
background: #f5f5f5;
border-color: #bbb;
.filter-btn__arrow {
font-size: 9px;
color: #999;
}
/* 时间筛选弹窗 */
@@ -421,12 +402,9 @@ body {
<!-- 预警记录列表标题 + 筛选按钮 -->
<div style="display: flex; align-items: center; justify-content: space-between; padding: 14px 16px 8px;">
<div class="section-title" style="margin: 0; padding: 0;">预警记录(共 1 条)</div>
<button class="filter-btn" onclick="openTimeFilter()">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<rect x="3" y="4" width="18" height="18" rx="2"/>
<path d="M16 2v4M8 2v4M3 10h18"/>
</svg>
筛选
<button class="filter-btn" id="filterBtn" onclick="openTimeFilter()">
<span id="filterLabel">2026-4</span>
<span class="filter-btn__arrow"></span>
</button>
</div>
@@ -447,11 +425,6 @@ body {
<span class="alert-card__value-unit">°C</span>
</div>
</div>
<!-- 右侧阈值范围 -->
<div class="alert-card__threshold">
<div class="alert-card__threshold-item">上限 <span>37.3°C</span></div>
<div class="alert-card__threshold-item">下限 <span>35.0°C</span></div>
</div>
</div>
<!-- 底部安全区 -->
@@ -482,7 +455,6 @@ body {
<div class="filter-section">
<label class="filter-label">月份</label>
<select id="monthSelect" class="filter-select">
<option value="">全部</option>
<option value="01">1月</option>
<option value="02">2月</option>
<option value="03">3月</option>
@@ -510,7 +482,12 @@ body {
<script>
// 时间筛选功能
let currentYear = '2026';
let currentMonth = '04';
function openTimeFilter() {
document.getElementById('yearSelect').value = currentYear;
document.getElementById('monthSelect').value = currentMonth;
document.getElementById('timeFilterModal').classList.add('active');
}
@@ -523,29 +500,38 @@ function updateMonths() {
}
function applyTimeFilter() {
const year = document.getElementById('yearSelect').value;
const month = document.getElementById('monthSelect').value;
currentYear = document.getElementById('yearSelect').value;
currentMonth = document.getElementById('monthSelect').value;
// 获取所有预警记录卡片
const alertCards = document.querySelectorAll('.alert-card');
filterCards();
updateFilterLabel();
closeTimeFilter();
}
alertCards.forEach(card => {
const timeText = card.querySelector('.alert-card__time').textContent;
// 格式:2026-04-15 13:28
const [dateStr] = timeText.split(' ');
const [cardYear, cardMonth] = dateStr.split('-');
function filterCards() {
var alertCards = document.querySelectorAll('.alert-card');
alertCards.forEach(function(card) {
var timeText = card.querySelector('.alert-card__time').textContent;
var dateStr = timeText.split(' ')[0];
var parts = dateStr.split('-');
var cardYear = parts[0];
var cardMonth = parts[1];
// 根据筛选条件显示/隐藏
let show = true;
if (year && cardYear !== year) show = false;
if (month && cardMonth !== month) show = false;
var show = true;
if (currentYear && cardYear !== currentYear) show = false;
if (currentMonth && cardMonth !== currentMonth) show = false;
card.style.display = show ? 'flex' : 'none';
});
closeTimeFilter();
}
function updateFilterLabel() {
document.getElementById('filterLabel').textContent = currentYear + '-' + parseInt(currentMonth);
}
// 初始默认筛选
filterCards();
// 点击弹窗外部关闭
document.addEventListener('DOMContentLoaded', function() {
const modal = document.getElementById('timeFilterModal');
@@ -709,10 +709,10 @@ body {
</div>
<!-- 今日三餐推荐 -->
<div class="meal-card" id="mealCard">
<div class="meal-card__header-row">
<div class="meal-card__title">今日三餐推荐</div>
<!-- 今日食谱推荐 -->
<div class="meal-card" id="mealCard">
<div class="meal-card__header-row">
<div class="meal-card__title">今日食谱推荐</div>
<span class="meal-card__ai-reason" id="mealReason">根据你的偏好与健康目标推荐</span>
</div>
<div class="meal-card__tabs">