fix: 更新健康监测文档和页面,删除活动统计页
@@ -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%(严重)。
|
||||
|
||||

|
||||

|
||||
@@ -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)** 的页面结构与心率一致。
|
||||
|
||||

|
||||

|
||||
@@ -317,7 +316,7 @@
|
||||
|
||||
### 16-17. 压力详情与预警历史
|
||||
|
||||
**压力详情(wearable/stress.html)** 和 **压力预警历史(wearable/stress-alerts.html)** 的页面结构与心率一致,额外显示压力等级评估徽章,预警历史页面每条卡片右侧显示正常阈值范围。
|
||||
**压力详情(wearable/stress.html)** 和 **压力预警历史(wearable/stress-alerts.html)** 的页面结构与心率一致。压力详情额外显示压力等级评估徽章。
|
||||
|
||||

|
||||

|
||||
@@ -452,9 +451,6 @@
|
||||
|
||||
**典型设备:** 空气质量监测站、PM10检测仪、臭氧检测仪、气象参数监测仪、VOC检测仪(共6台示例)
|
||||
|
||||
**等级描述(示例):**
|
||||
- 优:空气质量令人满意,基本无污染
|
||||
- 严重污染:健康人群运动耐受力降低,有明显强烈症状,提前出现某些疾病
|
||||
|
||||
##### 23.1.1 设备底部弹窗
|
||||
|
||||
@@ -609,47 +605,47 @@
|
||||
|
||||

|
||||
|
||||
**功能说明:** 展示环境监测设备的报警记录,支持按日期范围和报警类型筛选。页面根据 URL 参数 `tab` 决定可选报警类型与展示的报警列表。
|
||||
**功能说明:** 展示环境监测设备的报警记录,支持按时间筛选。页面根据 URL 参数 `tab`(outdoor/indoor/water/pollen)决定展示的报警类型与数据列表。
|
||||
|
||||
**通用 UI 元素:**
|
||||
- 筛选区:日期范围(起始/结束日期选择器)、类型下拉、重置按钮、查询按钮
|
||||
- 统计条:报警总条数(红色突出)
|
||||
- 报警卡片列表:左侧红色边条,顶部"{指标} 超标报警" + 时间,中部报警值(红底)→ 阈值范围(灰底),底部设备名称/位置
|
||||
- 筛选按钮(显示当前年月,如"2026-5")
|
||||
- 报警卡片列表:左侧红色边条,顶部"{指标} 超标报警" + 时间,中部"报警值(数值+单位)› 阈值范围(min~max+单位)"
|
||||
- 数据通过 JavaScript 动态渲染
|
||||
|
||||
**通用交互说明:**
|
||||
- 设置日期范围和类型后点击"查询"筛选
|
||||
- 点击"重置"恢复默认日期与类型筛选条件
|
||||
- 点击筛选按钮打开时间筛选弹窗,选择年月后确定
|
||||
- 列表为空时显示"暂无报警数据"占位
|
||||
|
||||
**业务规则:**
|
||||
- 报警值高于阈值上限或低于阈值下限时进入报警列表
|
||||
- 报警卡片同时呈现实际值与允许阈值范围(min~max),便于直观判断超标幅度
|
||||
- 报警卡片同时呈现实际值与允许阈值范围(min~max),直观判断超标幅度
|
||||
|
||||
#### 25.1 室外空气
|
||||
|
||||

|
||||
|
||||
**可选报警类型:** PM2.5、PM10、温度、湿度、风速、太阳辐射、照度
|
||||
**示例数据(8条,2026年5月):** PM2.5(156 μg/m³,阈值 0~75)、PM10(218 μg/m³,阈值 0~150)、风速(13.5 m/s,阈值 0~10)、太阳辐射(1180 W/m²,阈值 0~1000)、温度(42.3℃,阈值 -10~40)、PM2.5(195 μg/m³)、PM10(285 μg/m³)、照度(98500 lm/m²,阈值 0~95000)
|
||||
|
||||
|
||||
#### 25.2 室内空气
|
||||
|
||||

|
||||
|
||||
**可选报警类型:** PM2.5、PM10、CO₂、甲醛、温度、湿度
|
||||
**示例数据(6条,2026年5月):** CO₂(1250 ppm,阈值 400~1000)、甲醛(0.15 mg/m³,阈值 0~0.10)、PM2.5(135 μg/m³,阈值 0~75)、CO₂(980 ppm,敏感场所阈值 400~800)、湿度(85%,阈值 30~80)、甲醛(0.12 mg/m³)
|
||||
|
||||
|
||||
#### 25.3 水质监测
|
||||
|
||||

|
||||
|
||||
**可选报警类型:** PH、电导率、盐度、TDS、电阻率、温度
|
||||
**示例数据(6条,2026年5月):** 电导率(1250 μS/cm,阈值 50~1000)、PH(8.5,阈值 6.5~8.0)、TDS(840 mg/L,阈值 0~500)、盐度(920 mg/L,阈值 0~500)、电导率(1680 μS/cm)、PH(9.2)
|
||||
|
||||
|
||||
#### 25.4 花粉监测
|
||||
|
||||

|
||||
|
||||
**可选报警类型:** 花粉总数
|
||||
**示例数据(3条,2026年5月):** 花粉总数(1098、924、860 粒/千mm²,阈值 0~800)
|
||||
|
||||
> 备注:花粉监测仅对"花粉总数"设置统一报警阈值,各属/科单一指标暂不单独报警。
|
||||
|
||||
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 13 KiB |
|
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>
|
||||
|
||||
|
After Width: | Height: | Size: 113 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 91 KiB |
|
After Width: | Height: | Size: 115 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 115 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
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">
|
||||
|
||||