feat: 新增健康排查活动列表页面+主页入口卡片

- 员工端健康监测主页新增健康排查入口(已参加/待参加次数统计)
- 活动列表页支持待参加/已参加Tab切换
- 活动卡片展示:活动名称/日期/组织单位/状态/参加人数进度条
- 已参加显示参加时间,待参加显示去填写按钮

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
liuyunqin
2026-06-05 09:22:49 +08:00
co-authored by Claude Opus 4.8
parent 1a121017e5
commit 27f72d8049
4 changed files with 321 additions and 0 deletions
@@ -4,6 +4,23 @@
---
## [2026-06-05] feat: 新增健康排查活动列表页面+主页入口卡片
**涉及文件(3个新增、1个修改):**
- `index.html` — 主页底部新增"健康排查"入口卡片,显示已参加/待参加活动次数
- `health-checkup/index.html` — 健康排查活动列表页(新增)
- 根目录 `index.html` — SITE_MAP 新增健康排查活动列表页条目
**变更说明:**
- 员工端健康监测主页最底部新增"健康排查"模块入口(紫色渐变图标)
- 显示"已参加活动 X 次"和"待参加活动 X 次",待参加次数标红
- 点击跳转至健康排查活动列表页
- 活动列表页包含"待参加"和"已参加"两个 Tab 切换
- 活动卡片展示:活动名称、起止日期、组织单位、活动状态、应参加人数、已参加人数(含进度条)
- 已参加卡片显示参加时间,待参加卡片显示"去填写"按钮
---
## [2026-06-04] feat: 设备详情页变化趋势改造+新增空气质量指数
**涉及文件(1个修改):**
@@ -0,0 +1,284 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>健康排查活动 - 员工端 | 健康CQ原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #f5f7fa; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; }
.status-bar { height: 44px; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; background: #fff; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #333; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; }
.nav-bar { height: 44px; background: #fff; display: flex; align-items: center; padding: 0 16px; flex-shrink: 0; border-bottom: 1px solid #f0f0f0; }
.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; }
.scroll-content { flex: 1; overflow-y: auto; background: #f5f7fa; }
.scroll-content::-webkit-scrollbar { display: none; }
/* Tab 切换 */
.tab-bar { background: #fff; padding: 12px 16px 0; border-bottom: 1px solid #f0f0f0; }
.tab-list { display: flex; gap: 0; }
.tab-item { flex: 1; text-align: center; padding: 10px 0 12px; font-size: 14px; color: #999; cursor: pointer; position: relative; font-weight: 500; transition: color 0.2s; }
.tab-item.active { color: #667eea; font-weight: 600; }
.tab-item.active::after { content: ''; position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); width: 24px; height: 3px; background: #667eea; border-radius: 2px; }
/* 活动列表 */
.activity-section { padding: 12px; }
.activity-list { display: flex; flex-direction: column; gap: 12px; }
/* 活动卡片 */
.activity-card { background: #fff; border-radius: 14px; padding: 16px; cursor: pointer; transition: transform 0.15s; text-decoration: none; display: block; position: relative; overflow: hidden; }
.activity-card:active { transform: scale(0.985); }
/* 状态标签 - 左侧色条 */
.activity-card--pending { border-left: 3px solid #faad14; }
.activity-card--done { border-left: 3px solid #52c41a; }
.activity-card__header { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 10px; }
.activity-card__name { font-size: 15px; font-weight: 600; color: #1a1a1a; flex: 1; }
.activity-card__status { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 20px; white-space: nowrap; flex-shrink: 0; margin-left: 10px; }
.status--pending { color: #faad14; background: #fffbe6; border: 1px solid #ffe58f; }
.status--ongoing { color: #1890ff; background: #e6f7ff; border: 1px solid #91d5ff; }
.status--ended { color: #999; background: #fafafa; border: 1px solid #d9d9d9; }
.status--done { color: #52c41a; background: #f6ffed; border: 1px solid #b7eb8f; }
.activity-card__rows { display: flex; flex-direction: column; gap: 6px; }
.activity-card__row { display: flex; align-items: center; font-size: 12px; color: #999; }
.activity-card__row svg { flex-shrink: 0; margin-right: 6px; }
.activity-card__row span { color: #666; }
/* 参加状态标识 */
.activity-card__participate { margin-top: 10px; padding-top: 10px; border-top: 1px dashed #f0f0f0; display: flex; align-items: center; justify-content: space-between; }
.participate--done { color: #52c41a; font-size: 12px; font-weight: 500; }
.participate--pending { color: #faad14; font-size: 12px; font-weight: 500; }
.participate-btn { font-size: 12px; color: #fff; background: #667eea; border-radius: 14px; padding: 4px 12px; text-decoration: none; font-weight: 500; }
.participate-btn:active { opacity: 0.85; }
/* 人数进度条 */
.attendance-bar { margin-top: 10px; }
.attendance-bar__text { display: flex; justify-content: space-between; font-size: 12px; color: #999; margin-bottom: 4px; }
.attendance-bar__text span { color: #666; }
.attendance-bar__track { height: 6px; background: #f5f5f5; border-radius: 3px; overflow: hidden; }
.attendance-bar__fill { height: 100%; border-radius: 3px; background: linear-gradient(90deg, #667eea, #764ba2); transition: width 0.3s; }
/* 空状态 */
.empty-state { text-align: center; padding: 60px 20px; color: #ccc; }
.empty-state svg { margin-bottom: 12px; }
.empty-state__text { font-size: 14px; }
/* 底部安全区 */
.bottom-safe { height: 20px; flex-shrink: 0; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<span class="icons">
<svg width="16" height="16" fill="none"><rect x="1" y="4" width="3" height="8" rx="1" fill="#333"/><rect x="5" y="3" width="3" height="9" rx="1" fill="#333"/><rect x="9" y="1" width="3" height="11" rx="1" fill="#333"/><rect x="13" y="0" width="3" height="12" rx="1" fill="#333" opacity=".3"/></svg>
<svg width="16" height="16" fill="none"><path d="M8 3C5.5 3 3.2 4 1.5 5.5l1.4 1.4C4.3 5.5 6.1 5 8 5s3.7.5 5.1 1.9l1.4-1.4C12.8 4 10.5 3 8 3zm0 4c-1.4 0-2.6.5-3.5 1.3L6 9.8c.6-.5 1.3-.8 2-.8s1.4.3 2 .8l1.5-1.5C10.6 7.5 9.4 7 8 7zm0 4c-.6 0-1 .4-1 1s.4 1 1 1 1-.4 1-1-.4-1-1-1z" fill="#333"/></svg>
<svg width="22" height="12" fill="none"><rect x=".5" y=".5" width="19" height="11" rx="2" stroke="#333"/><rect x="20" y="3.5" width="1.5" height="5" rx=".75" fill="#333"/><rect x="2" y="2" width="14" height="8" rx="1" fill="#333"/></svg>
</span>
</div>
<div class="nav-bar">
<div class="nav-back" onclick="location.href='../index.html'">
<svg width="12" height="20" fill="none"><path d="M10 2L2 10l8 8" stroke="#1a1a1a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
</div>
<div class="nav-title">健康排查</div>
</div>
<!-- Tab 切换 -->
<div class="tab-bar">
<div class="tab-list">
<div class="tab-item active" data-tab="pending" onclick="switchTab(this)">待参加</div>
<div class="tab-item" data-tab="done" onclick="switchTab(this)">已参加</div>
</div>
</div>
<div class="scroll-content">
<div class="activity-section">
<!-- 待参加列表 -->
<div class="activity-list" id="tab-pending">
<!-- 活动1:待参加 -->
<a class="activity-card activity-card--pending" href="activity-detail.html?id=1">
<div class="activity-card__header">
<div class="activity-card__name">2026年第二季度健康排查</div>
<div class="activity-card__status status--ongoing">进行中</div>
</div>
<div class="activity-card__rows">
<div class="activity-card__row">
<svg width="14" height="14" fill="none"><rect x="2" y="2" width="10" height="11" rx="1.5" stroke="#999" stroke-width="1.2"/><path d="M1 6h12M6 1v3M8 1v3" stroke="#999" stroke-width="1.2" stroke-linecap="round"/></svg>
2026-06-01 ~ 2026-06-30
</div>
<div class="activity-card__row">
<svg width="14" height="14" fill="none"><path d="M7 1a3.5 3.5 0 013.5 3.5c0 2.5-3.5 6-3.5 6S3.5 7 3.5 4.5A3.5 3.5 0 017 1z" stroke="#999" stroke-width="1.2"/><circle cx="7" cy="4.5" r="1.2" stroke="#999" stroke-width="1.2"/></svg>
<span>工会办公室</span>
</div>
</div>
<div class="attendance-bar">
<div class="attendance-bar__text">
<span>应参加 <strong>356</strong></span>
<span>已参加 <strong>128</strong></span>
</div>
<div class="attendance-bar__track">
<div class="attendance-bar__fill" style="width: 36%;"></div>
</div>
</div>
<div class="activity-card__participate">
<span class="participate--pending">⏰ 尚未参加</span>
<a class="participate-btn" href="activity-fill.html?id=1">去填写</a>
</div>
</a>
<!-- 活动2:待参加 -->
<a class="activity-card activity-card--pending" href="activity-detail.html?id=2">
<div class="activity-card__header">
<div class="activity-card__name">2026年第三季度健康排查</div>
<div class="activity-card__status status--pending">未开始</div>
</div>
<div class="activity-card__rows">
<div class="activity-card__row">
<svg width="14" height="14" fill="none"><rect x="2" y="2" width="10" height="11" rx="1.5" stroke="#999" stroke-width="1.2"/><path d="M1 6h12M6 1v3M8 1v3" stroke="#999" stroke-width="1.2" stroke-linecap="round"/></svg>
2026-09-01 ~ 2026-09-30
</div>
<div class="activity-card__row">
<svg width="14" height="14" fill="none"><path d="M7 1a3.5 3.5 0 013.5 3.5c0 2.5-3.5 6-3.5 6S3.5 7 3.5 4.5A3.5 3.5 0 017 1z" stroke="#999" stroke-width="1.2"/><circle cx="7" cy="4.5" r="1.2" stroke="#999" stroke-width="1.2"/></svg>
<span>人力资源部</span>
</div>
</div>
<div class="attendance-bar">
<div class="attendance-bar__text">
<span>应参加 <strong>380</strong></span>
<span>已参加 <strong>0</strong></span>
</div>
<div class="attendance-bar__track">
<div class="attendance-bar__fill" style="width: 0%;"></div>
</div>
</div>
<div class="activity-card__participate">
<span class="participate--pending">⏰ 尚未开始</span>
</div>
</a>
</div>
<!-- 已参加列表 -->
<div class="activity-list" id="tab-done" style="display:none;">
<!-- 活动3:已参加 -->
<a class="activity-card activity-card--done" href="activity-detail.html?id=3">
<div class="activity-card__header">
<div class="activity-card__name">2026年第一季度健康排查</div>
<div class="activity-card__status status--ended">已结束</div>
</div>
<div class="activity-card__rows">
<div class="activity-card__row">
<svg width="14" height="14" fill="none"><rect x="2" y="2" width="10" height="11" rx="1.5" stroke="#999" stroke-width="1.2"/><path d="M1 6h12M6 1v3M8 1v3" stroke="#999" stroke-width="1.2" stroke-linecap="round"/></svg>
2026-03-01 ~ 2026-03-31
</div>
<div class="activity-card__row">
<svg width="14" height="14" fill="none"><path d="M7 1a3.5 3.5 0 013.5 3.5c0 2.5-3.5 6-3.5 6S3.5 7 3.5 4.5A3.5 3.5 0 017 1z" stroke="#999" stroke-width="1.2"/><circle cx="7" cy="4.5" r="1.2" stroke="#999" stroke-width="1.2"/></svg>
<span>工会办公室</span>
</div>
</div>
<div class="attendance-bar">
<div class="attendance-bar__text">
<span>应参加 <strong>340</strong></span>
<span>已参加 <strong>335</strong></span>
</div>
<div class="attendance-bar__track">
<div class="attendance-bar__fill" style="width: 98%;"></div>
</div>
</div>
<div class="activity-card__participate">
<span class="participate--done">✓ 已参加 &nbsp;2026-03-15 09:20</span>
</div>
</a>
<!-- 活动4:已参加 -->
<a class="activity-card activity-card--done" href="activity-detail.html?id=4">
<div class="activity-card__header">
<div class="activity-card__name">2025年第四季度健康排查</div>
<div class="activity-card__status status--ended">已结束</div>
</div>
<div class="activity-card__rows">
<div class="activity-card__row">
<svg width="14" height="14" fill="none"><rect x="2" y="2" width="10" height="11" rx="1.5" stroke="#999" stroke-width="1.2"/><path d="M1 6h12M6 1v3M8 1v3" stroke="#999" stroke-width="1.2" stroke-linecap="round"/></svg>
2025-12-01 ~ 2025-12-31
</div>
<div class="activity-card__row">
<svg width="14" height="14" fill="none"><path d="M7 1a3.5 3.5 0 013.5 3.5c0 2.5-3.5 6-3.5 6S3.5 7 3.5 4.5A3.5 3.5 0 017 1z" stroke="#999" stroke-width="1.2"/><circle cx="7" cy="4.5" r="1.2" stroke="#999" stroke-width="1.2"/></svg>
<span>人力资源部</span>
</div>
</div>
<div class="attendance-bar">
<div class="attendance-bar__text">
<span>应参加 <strong>320</strong></span>
<span>已参加 <strong>318</strong></span>
</div>
<div class="attendance-bar__track">
<div class="attendance-bar__fill" style="width: 99%;"></div>
</div>
</div>
<div class="activity-card__participate">
<span class="participate--done">✓ 已参加 &nbsp;2025-12-10 14:35</span>
</div>
</a>
<!-- 活动5:已参加 -->
<a class="activity-card activity-card--done" href="activity-detail.html?id=5">
<div class="activity-card__header">
<div class="activity-card__name">2025年第三季度健康排查</div>
<div class="activity-card__status status--ended">已结束</div>
</div>
<div class="activity-card__rows">
<div class="activity-card__row">
<svg width="14" height="14" fill="none"><rect x="2" y="2" width="10" height="11" rx="1.5" stroke="#999" stroke-width="1.2"/><path d="M1 6h12M6 1v3M8 1v3" stroke="#999" stroke-width="1.2" stroke-linecap="round"/></svg>
2025-09-01 ~ 2025-09-30
</div>
<div class="activity-card__row">
<svg width="14" height="14" fill="none"><path d="M7 1a3.5 3.5 0 013.5 3.5c0 2.5-3.5 6-3.5 6S3.5 7 3.5 4.5A3.5 3.5 0 017 1z" stroke="#999" stroke-width="1.2"/><circle cx="7" cy="4.5" r="1.2" stroke="#999" stroke-width="1.2"/></svg>
<span>工会办公室</span>
</div>
</div>
<div class="attendance-bar">
<div class="attendance-bar__text">
<span>应参加 <strong>310</strong></span>
<span>已参加 <strong>305</strong></span>
</div>
<div class="attendance-bar__track">
<div class="attendance-bar__fill" style="width: 98%;"></div>
</div>
</div>
<div class="activity-card__participate">
<span class="participate--done">✓ 已参加 &nbsp;2025-09-08 10:12</span>
</div>
</a>
</div>
</div>
<div class="bottom-safe"></div>
</div>
</div>
<script>
function switchTab(el) {
var tab = el.getAttribute('data-tab');
// 切换 tab 样式
document.querySelectorAll('.tab-item').forEach(function(item) {
item.classList.remove('active');
});
el.classList.add('active');
// 切换列表显示
document.querySelectorAll('.activity-list').forEach(function(list) {
list.style.display = 'none';
});
document.getElementById('tab-' + tab).style.display = '';
}
</script>
</body>
</html>
+13
View File
@@ -183,6 +183,19 @@ body { background: #f0f2f5; display: flex; justify-content: center; align-items:
<div class="entry-arrow"><svg width="7" height="12" fill="none"><path d="M1 1l5 5-5 5" stroke="#ccc" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
</a>
<!-- 健康排查 V2 -->
<a class="entry-card" href="health-checkup/index.html">
<div class="entry-icon" style="background: linear-gradient(135deg, #f9f0ff 0%, #d3adf7 100%);">📋</div>
<div class="entry-info">
<div class="entry-name">健康排查</div>
<div class="entry-metrics">
<span class="entry-metric">已参加活动 <strong>3</strong></span>
<span class="entry-metric">待参加活动 <strong style="color: #ff4d4f;">2</strong></span>
</div>
</div>
<div class="entry-arrow"><svg width="7" height="12" fill="none"><path d="M1 1l5 5-5 5" stroke="#ccc" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg></div>
</a>
</div>
</div>
<div class="bottom-safe"></div>
+7
View File
@@ -339,6 +339,12 @@ const SITE_MAP = [
{ file:'health-checkup/survey-score.html', label:'排查问卷-积分规则' },
{ file:'health-checkup/survey-template.html', label:'排查问卷-模板信息' },
{ file:'health-checkup/survey-question.html', label:'排查问卷-问题管理' },
{ file:'health-checkup/survey-manage.html', label:'问卷管理' },
{ file:'health-checkup/survey-edit.html', label:'新增/编辑问卷', dialog:true },
{ file:'health-checkup/activity-manage.html', label:'活动管理' },
{ file:'health-checkup/activity-stat.html', label:'活动统计' },
{ file:'health-checkup/activity-edit.html', label:'新增/编辑活动', dialog:true },
{ file:'health-checkup/activity-detail.html', label:'活动详情', dialog:true },
{ file:'health-checkup/maxim.html', label:'格言管理' },
{ file:'health-checkup/record-user.html', label:'排查记录-用户排查' },
{ file:'health-checkup/record-dept.html', label:'排查记录-部门排查' },
@@ -576,6 +582,7 @@ const SITE_MAP = [
{ file:'health-screening/questionnaire-setting.html', label:'题目设置' },
{ file:'health-screening/checkin-record.html', label:'打卡记录' },
{ file:'health-screening/questionnaire-detail.html', label:'问卷详情' },
{ file:'health-checkup/index.html', label:'健康排查活动列表' },
{ file:'weight/index.html', label:'体重监测首页' },
{ file:'weight/history.html', label:'体重历史数据' },
{ file:'weight/report-detail.html', label:'体重详细报告' },