feat: 健康体检精简页面并统一术语为已参检

- 删除到院体检(hospital-checkin)与未开展计划(index-inactive)页面及对应截图
- 术语统一:已体检→已参检,操作流程讲解→操作说明
- 选择体检类型页优化:移除体检状态徽标,字段改为计划起止日期/预约开放日期/当前所属群体
- 补充预约项目AI解读、提交及胃肠镜预选/问卷相关截图
- 同步更新PRD文档与全站导航配置
This commit is contained in:
liuyunqin
2026-09-15 14:51:00 +08:00
parent bdc44daf24
commit d5756021b6
36 changed files with 436 additions and 1063 deletions
@@ -275,7 +275,7 @@
<!-- [交互] 预约状态与可预约日期范围,日期范围由脚本按「近30天」规则动态生成 -->
<div class="status-card">
<div class="status-row">
<span class="status-badge status-badge--open"><span class="status-badge__dot"></span>预约</span>
<span class="status-badge status-badge--open"><span class="status-badge__dot"></span>已开启预约</span>
<span class="status-range" id="rangeText"></span>
</div>
<div class="status-tip">
+10 -21
View File
@@ -146,7 +146,7 @@
margin-top: 6px;
flex-wrap: wrap;
}
/* 状态徽标:体检状态三态 + 预约状态两态,演示卡片统一取「进行中 + 已开启预约 */
/* 状态徽标:预约状态两态(已开启预约 / 未开启预约 */
.status-badge {
display: inline-flex;
align-items: center;
@@ -268,7 +268,6 @@
<div class="type-card__main">
<div class="type-card__name">常规体检</div>
<div class="type-card__badges">
<span class="status-badge status-badge--ongoing">进行中</span>
<span class="status-badge status-badge--appt-open">已开启预约</span>
</div>
</div>
@@ -276,15 +275,15 @@
</div>
<div class="type-card__info">
<div class="info-row">
<span class="info-row__label">体检时间</span>
<span class="info-row__label">计划起止日期</span>
<span class="info-row__value">2026-06-23 至 2026-08-31</span>
</div>
<div class="info-row">
<span class="info-row__label">预约时间</span>
<span class="info-row__label">预约开放日期</span>
<span class="info-row__value">2026-06-01 至 2026-08-20</span>
</div>
<div class="info-row">
<span class="info-row__label">所属人群</span>
<span class="info-row__label">当前所属群体</span>
<span class="info-row__value">35岁及以下-女</span>
</div>
<div class="info-row info-row--quota">
@@ -300,24 +299,19 @@
<div class="type-card__main">
<div class="type-card__name">胃肠镜体检</div>
<div class="type-card__badges">
<span class="status-badge status-badge--ongoing">进行中</span>
<span class="status-badge status-badge--appt-open">已开启预约</span>
<span class="status-badge status-badge--appt-pending">未开启预约</span>
</div>
</div>
<div class="radio-dot"></div>
</div>
<div class="type-card__info">
<div class="info-row">
<span class="info-row__label">体检时间</span>
<span class="info-row__label">计划起止日期</span>
<span class="info-row__value">2026-06-23 至 2026-08-31</span>
</div>
<div class="info-row">
<span class="info-row__label">预约时间</span>
<span class="info-row__value">2026-06-01 至 2026-08-20</span>
</div>
<div class="info-row">
<span class="info-row__label">所属人群</span>
<span class="info-row__value">35岁及以下-女</span>
<span class="info-row__label">预约开放日期</span>
<span class="info-row__value">-</span>
</div>
</div>
</div>
@@ -328,7 +322,6 @@
<div class="type-card__main">
<div class="type-card__name">冠脉CTA体检</div>
<div class="type-card__badges">
<span class="status-badge status-badge--ongoing">进行中</span>
<span class="status-badge status-badge--appt-open">已开启预约</span>
</div>
</div>
@@ -336,17 +329,13 @@
</div>
<div class="type-card__info">
<div class="info-row">
<span class="info-row__label">体检时间</span>
<span class="info-row__label">计划起止日期</span>
<span class="info-row__value">2026-06-23 至 2026-08-31</span>
</div>
<div class="info-row">
<span class="info-row__label">预约时间</span>
<span class="info-row__label">预约开放日期</span>
<span class="info-row__value">2026-06-01 至 2026-08-20</span>
</div>
<div class="info-row">
<span class="info-row__label">所属人群</span>
<span class="info-row__value">35岁及以下-女</span>
</div>
</div>
</div>
</div>
+1 -1
View File
@@ -196,7 +196,7 @@
<!-- [交互] 预约状态与可预约日期范围,日期范围由脚本按「最早7天后」规则动态生成 -->
<div class="status-card">
<div class="status-row">
<span class="status-badge status-badge--open"><span class="status-badge__dot"></span>预约</span>
<span class="status-badge status-badge--open"><span class="status-badge__dot"></span>已开启预约</span>
<span class="status-range" id="rangeText"></span>
</div>
<div class="status-tip">
File diff suppressed because it is too large Load Diff
@@ -18,7 +18,6 @@ const root = path.resolve(__dirname, '..');
const tasks = [
// ========== 模块主页 ==========
{ html: 'index.html', out: 'index' },
{ html: 'index-inactive.html', out: 'index-inactive' },
// ========== 体检预约(通用 + 常规体检流程) ==========
{ html: 'booking-type.html', out: 'booking-type' },
@@ -52,7 +51,6 @@ const tasks = [
{ html: 'my-appointments-all.html', out: 'my-appointments-all' },
{ html: 'my-appointments-all.html', out: 'my-appointments-all-gastro', query: '?type=gastro&status=pending' },
{ html: 'my-appointments-all.html', out: 'my-appointments-all-cta', query: '?type=cta&status=pending' },
{ html: 'hospital-checkin.html', out: 'hospital-checkin' },
// ========== 体检报告 ==========
{ html: 'reports.html', out: 'reports' },
Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 KiB

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 KiB

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 53 KiB

+1 -1
View File
@@ -199,7 +199,7 @@
<!-- [交互] 预约状态与可预约日期范围,日期范围由脚本按「最早7天后」规则动态生成 -->
<div class="status-card">
<div class="status-row">
<span class="status-badge status-badge--open"><span class="status-badge__dot"></span>预约</span>
<span class="status-badge status-badge--open"><span class="status-badge__dot"></span>已开启预约</span>
<span class="status-range" id="rangeText"></span>
</div>
<div class="status-tip">
@@ -1,253 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>到院体检</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--primary: #13c2c2;
--primary-dark: #0f9b9b;
--primary-light: #e6fffb;
--text-primary: #1a1a1a;
--text-secondary: #666666;
--text-muted: #8c8c8c;
--bg-page: #f0f2f5;
--bg-content: #f7f9fb;
--shadow: 0 10px 26px rgba(19, 194, 194, 0.08);
}
body {
background: var(--bg-page);
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;
color: var(--text-primary);
}
.phone-shell {
width: 390px;
min-height: 844px;
background: var(--bg-content);
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;
}
.phone-status-bar {
height: 44px;
background: #fff;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
font-size: 12px;
font-weight: 600;
flex-shrink: 0;
}
.phone-status-bar .time { font-size: 15px; font-weight: 700; }
.phone-status-bar .icons { display: flex; gap: 6px; align-items: center; }
.nav-bar {
height: 44px;
display: flex;
align-items: center;
padding: 0 16px;
background: #fff;
border-bottom: 1px solid #f0f0f0;
flex-shrink: 0;
position: relative;
}
.nav-back {
font-size: 18px;
color: var(--text-primary);
cursor: pointer;
line-height: 1;
text-decoration: none;
}
.nav-title {
position: absolute;
left: 50%;
transform: translateX(-50%);
font-size: 17px;
font-weight: 600;
color: var(--text-primary);
}
.scroll-content {
flex: 1;
overflow-y: auto;
background: linear-gradient(180deg, #effbfb 0%, #f7f9fb 160px, #f7f9fb 100%);
padding: 16px;
padding-bottom: 110px;
}
.scroll-content::-webkit-scrollbar { display: none; }
.hero-card {
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
border-radius: 24px;
padding: 22px 18px;
color: #fff;
box-shadow: 0 12px 28px rgba(19, 194, 194, 0.22);
}
.hero-card__badge {
display: inline-flex;
align-items: center;
padding: 6px 12px;
border-radius: 999px;
background: rgba(255,255,255,0.18);
font-size: 12px;
font-weight: 600;
margin-bottom: 14px;
}
.hero-card__title {
font-size: 24px;
font-weight: 700;
margin-bottom: 8px;
}
.hero-card__desc {
font-size: 13px;
line-height: 1.7;
opacity: 0.92;
}
.detail-card,
.notice-card {
margin-top: 14px;
background: #fff;
border-radius: 20px;
padding: 18px 16px;
box-shadow: var(--shadow);
border: 1px solid rgba(19, 194, 194, 0.06);
}
.section-title {
font-size: 16px;
font-weight: 700;
margin-bottom: 14px;
}
.detail-list {
display: flex;
flex-direction: column;
gap: 14px;
}
.detail-item {
display: flex;
justify-content: space-between;
gap: 12px;
align-items: flex-start;
}
.detail-item__label {
font-size: 13px;
color: var(--text-muted);
flex-shrink: 0;
}
.detail-item__value {
font-size: 14px;
color: var(--text-primary);
font-weight: 600;
text-align: right;
line-height: 1.6;
}
.notice-card__text {
font-size: 14px;
line-height: 1.9;
color: var(--text-secondary);
}
.route-card {
margin-top: 14px;
padding: 16px;
border-radius: 20px;
background: linear-gradient(135deg, #ffffff 0%, #f5fffe 100%);
border: 1px solid #e3f7f5;
box-shadow: var(--shadow);
}
.route-card__title {
font-size: 15px;
font-weight: 700;
margin-bottom: 8px;
}
.route-card__desc {
font-size: 13px;
line-height: 1.7;
color: var(--text-secondary);
}
.bottom-action {
position: absolute;
left: 16px;
right: 16px;
bottom: 18px;
padding-bottom: 16px;
}
.bottom-action__btn {
width: 100%;
height: 48px;
border: none;
border-radius: 24px;
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
color: #fff;
font-size: 15px;
font-weight: 600;
box-shadow: 0 10px 20px rgba(19, 194, 194, 0.22);
cursor: pointer;
}
</style>
</head>
<body>
<div class="phone-shell">
<div class="phone-status-bar">
<span class="time">12:00</span>
<div class="icons">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 6l5 5 5-5"/><path d="M4 9l3 3 3-3" opacity="0.5"/></svg>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="1" y="6" width="18" height="12" rx="2"/><path d="M21 10v4"/></svg>
</div>
</div>
<div class="nav-bar">
<!-- [交互] 点击返回至: my-appointments-all.html -->
<a class="nav-back" href="my-appointments-all.html"></a>
<span class="nav-title">到院体检</span>
</div>
<div class="scroll-content">
<div class="hero-card">
<div class="hero-card__badge">到院签到提醒</div>
<div class="hero-card__title">常规体检</div>
<div class="hero-card__desc">请根据预约信息前往对应医院,完成签到后按体检单顺序进行检查,异常情况可联系导检台。</div>
</div>
<div class="detail-card">
<div class="section-title">预约详情</div>
<div class="detail-list">
<div class="detail-item">
<div class="detail-item__label">体检医院</div>
<div class="detail-item__value">宁夏宝石花医院</div>
</div>
<div class="detail-item">
<div class="detail-item__label">预约日期</div>
<div class="detail-item__value">2026-03-23</div>
</div>
<div class="detail-item">
<div class="detail-item__label">体检地址</div>
<div class="detail-item__value">凤城五路与开元路十字东南角</div>
</div>
</div>
</div>
<div class="notice-card">
<div class="section-title">体检须知</div>
<div class="notice-card__text">体检前一天请清淡饮食,勿饮酒,勿劳累;体检当天请空腹,禁食。</div>
</div>
<div class="route-card">
<div class="route-card__title">到院建议</div>
<div class="route-card__desc">建议您提前 15 分钟到院,便于完成签到、核验身份与领取体检单,避免高峰时段排队等待。</div>
</div>
</div>
<div class="bottom-action">
<!-- [交互] 点击跳转至: my-appointments-all.html -->
<button class="bottom-action__btn" onclick="window.location.href='my-appointments-all.html'">返回现场体检</button>
</div>
</div>
</body>
</html>
@@ -1,280 +0,0 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>健康体检</title>
<style>
* { 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;
min-height: 844px;
background: #f7f9fb;
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;
}
.phone-status-bar {
height: 44px;
background: #fff;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 24px;
font-size: 12px;
font-weight: 600;
flex-shrink: 0;
}
.phone-status-bar .time { font-size: 15px; font-weight: 700; }
.phone-status-bar .icons { display: flex; gap: 6px; align-items: center; }
.nav-bar {
height: 44px;
display: flex;
align-items: center;
padding: 0 16px;
background: #fff;
border-bottom: 1px solid #f0f0f0;
flex-shrink: 0;
position: relative;
}
.nav-back {
font-size: 18px;
color: #1a1a1a;
cursor: pointer;
line-height: 1;
text-decoration: none;
}
.nav-title {
position: absolute;
left: 50%;
transform: translateX(-50%);
font-size: 17px;
font-weight: 600;
color: #1a1a1a;
}
.scroll-content {
flex: 1;
overflow-y: auto;
background: linear-gradient(180deg, #f3fbfb 0%, #f7f9fb 180px, #f7f9fb 100%);
}
.scroll-content::-webkit-scrollbar { display: none; }
.page-body { padding: 16px; }
.hero-card {
background: linear-gradient(135deg, #ffffff 0%, #f3fffe 100%);
border: 1px solid #d9f7f3;
border-radius: 20px;
padding: 18px 16px;
box-shadow: 0 6px 18px rgba(20, 180, 176, 0.08);
position: relative;
overflow: hidden;
}
.hero-card::after {
content: '';
position: absolute;
right: -36px;
top: -36px;
width: 120px;
height: 120px;
border-radius: 50%;
background: rgba(19, 194, 194, 0.08);
}
.hero-card__badge {
display: inline-flex;
align-items: center;
gap: 6px;
height: 28px;
padding: 0 10px;
border-radius: 14px;
background: rgba(250, 173, 20, 0.12);
color: #d48806;
font-size: 12px;
font-weight: 600;
margin-bottom: 12px;
position: relative;
z-index: 1;
}
.hero-card__title {
font-size: 22px;
line-height: 1.2;
font-weight: 700;
color: #1a1a1a;
margin-bottom: 10px;
position: relative;
z-index: 1;
}
.hero-card__desc {
font-size: 14px;
line-height: 1.7;
color: #666;
position: relative;
z-index: 1;
}
.pending-card {
margin-top: 14px;
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
border-radius: 18px;
padding: 16px;
color: #fff;
box-shadow: 0 10px 24px rgba(19, 194, 194, 0.22);
}
.pending-card__label { font-size: 13px; opacity: 0.9; margin-bottom: 8px; }
.pending-card__value { font-size: 28px; font-weight: 800; line-height: 1; }
.pending-card__meta { margin-top: 10px; font-size: 12px; opacity: 0.86; }
.section-title { font-size: 16px; font-weight: 700; color: #1a1a1a; margin: 22px 2px 12px; }
.feature-list { display: flex; flex-direction: column; gap: 12px; }
.feature-card {
background: #fff; border-radius: 18px; padding: 16px; display: flex; align-items: center; gap: 14px;
box-shadow: 0 4px 14px rgba(0,0,0,0.05); border: 1px solid #f0f0f0; cursor: pointer;
transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.feature-card:active { transform: scale(0.985); }
.feature-card__icon {
width: 52px; height: 52px; border-radius: 16px; display: flex; align-items: center;
justify-content: center; flex-shrink: 0;
}
.feature-card__content { flex: 1; min-width: 0; }
.feature-card__title { font-size: 16px; font-weight: 700; color: #1a1a1a; margin-bottom: 4px; }
.feature-card__desc { font-size: 12px; line-height: 1.6; color: #8c8c8c; }
.feature-card__action {
margin-top: 10px; display: inline-flex; align-items: center; justify-content: center; height: 28px;
padding: 0 12px; border-radius: 14px; background: #f5f7fa; color: #13c2c2; font-size: 12px; font-weight: 600;
}
.feature-card__arrow { font-size: 18px; color: #c6c6c6; flex-shrink: 0; }
.quick-grid {
display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin-top: 12px;
}
.quick-card {
background: #fff; border-radius: 16px; padding: 16px 14px; min-height: 118px;
box-shadow: 0 4px 14px rgba(0,0,0,0.05); border: 1px solid #f0f0f0;
position: relative; overflow: hidden;
}
.quick-card::after {
content: ''; position: absolute; right: -20px; bottom: -20px; width: 72px; height: 72px;
border-radius: 50%; background: rgba(19, 194, 194, 0.08);
}
.quick-card__icon {
width: 40px; height: 40px; border-radius: 12px; display: flex; align-items: center;
justify-content: center; margin-bottom: 12px;
}
.quick-card__title {
font-size: 15px; font-weight: 700; color: #1a1a1a; margin-bottom: 6px; position: relative; z-index: 1;
}
.quick-card__desc {
font-size: 12px; line-height: 1.6; color: #8c8c8c; position: relative; z-index: 1;
}
.bottom-spacer { height: 28px; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="phone-status-bar">
<span class="time">12:00</span>
<div class="icons">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 6l5 5 5-5"/><path d="M4 9l3 3 3-3" opacity="0.5"/></svg>
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="1" y="6" width="18" height="12" rx="2"/><path d="M21 10v4"/></svg>
</div>
</div>
<div class="nav-bar">
<span class="nav-back" onclick="history.back()"></span>
<span class="nav-title">健康体检</span>
</div>
<div class="scroll-content">
<div class="page-body">
<div class="hero-card">
<div class="hero-card__badge">
<span>📋</span>
<span>年度体检计划</span>
</div>
<div class="hero-card__title">健康体检</div>
<div class="hero-card__desc">本年度暂未开展体检计划,请耐心等待</div>
<div class="pending-card">
<div class="pending-card__label">待查看的体检报告</div>
<div class="pending-card__value">2 份</div>
<div class="pending-card__meta">历史报告已生成,可前往体检报告查看既往体检记录与指标摘要。</div>
</div>
</div>
<div class="section-title">体检服务</div>
<div class="feature-list">
<!-- [交互] 点击跳转至: booking-type.html -->
<div class="feature-card" onclick="location.href='booking-type.html'">
<div class="feature-card__icon" style="background:#e6fffb; color:#13c2c2;">
<svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="17" rx="2"/><line x1="16" y1="2.5" x2="16" y2="6"/><line x1="8" y1="2.5" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/><path d="M8 14h3"/><path d="M8 17h5"/></svg>
</div>
<div class="feature-card__content">
<div class="feature-card__title">体检预约</div>
<div class="feature-card__desc">查看预约入口与年度体检开放状态</div>
<span class="feature-card__action">体检预约</span>
</div>
<span class="feature-card__arrow"></span>
</div>
<!-- [交互] 点击跳转至: my-appointments-all.html -->
<div class="feature-card" onclick="location.href='my-appointments-all.html'">
<div class="feature-card__icon" style="background:#f6ffed; color:#52c41a;">
<svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11l3 3L22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg>
</div>
<div class="feature-card__content">
<div class="feature-card__title">现场体检</div>
<div class="feature-card__desc">到院体检扫码/体检进度查询</div>
<span class="feature-card__action">查看体检</span>
</div>
<span class="feature-card__arrow"></span>
</div>
<!-- [交互] 点击跳转至: reports.html -->
<div class="feature-card" onclick="location.href='reports.html'">
<div class="feature-card__icon" style="background:#fff7e6; color:#fa8c16;">
<svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/><line x1="8" y1="13" x2="16" y2="13"/><line x1="8" y1="17" x2="14" y2="17"/></svg>
</div>
<div class="feature-card__content">
<div class="feature-card__title">体检报告</div>
<div class="feature-card__desc">查看历年体检报告与 AI 解读入口</div>
<span class="feature-card__action">查看报告</span>
</div>
<span class="feature-card__arrow"></span>
</div>
</div>
<div class="section-title">辅助入口</div>
<div class="quick-grid">
<!-- [交互] 操作流程讲解入口,当前为静态说明卡片 -->
<div class="quick-card">
<div class="quick-card__icon" style="background:#eef9ff; color:#1677ff;">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 8v4l2.5 2.5"/></svg>
</div>
<div class="quick-card__title">操作流程讲解</div>
<div class="quick-card__desc">查看体检计划开放后,预约、到院、报告查询等关键流程说明。</div>
</div>
<!-- [交互] 一键咨询入口,当前为静态说明卡片 -->
<div class="quick-card">
<div class="quick-card__icon" style="background:#f9f0ff; color:#722ed1;">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/><path d="M8 9h8"/><path d="M8 13h5"/></svg>
</div>
<div class="quick-card__title">一键咨询</div>
<div class="quick-card__desc">对体检开放时间、项目内容和报告指标进行咨询。</div>
</div>
</div>
<div class="bottom-spacer"></div>
</div>
</div>
</div>
</body>
</html>
+7 -7
View File
@@ -158,7 +158,7 @@
position: relative;
z-index: 1;
}
/* 圆圈进度:固定右下角,按状态推进(已选项目20%→已预约60%→体检中80%→已检100% */
/* 圆圈进度:固定右下角,按状态推进(已选项目20%→已预约60%→体检中80%→已检100% */
.banner-progress {
position: absolute;
right: 14px;
@@ -459,7 +459,7 @@
<!-- [交互] 左右滑动切换四张计划 Banner,点击圆点跳转到对应张 -->
<div class="banner">
<div class="banner__track" id="bannerTrack">
<!-- 第一张:常规体检 | [交互] 点击进入: reports.html(已检,查看报告) -->
<!-- 第一张:常规体检 | [交互] 点击进入: reports.html(已检,查看报告) -->
<div class="banner-slide banner-slide--routine" onclick="location.href='reports.html'">
<span class="banner-slide__ring"></span>
<span class="banner-slide__deco">🩺</span>
@@ -468,13 +468,13 @@
<div class="banner-slide__fee">
<span class="banner-chip">💰 体检费用额度 <b>¥1500.00</b></span>
</div>
<!-- 圆圈进度(右下角):已检 = 满环 -->
<!-- 圆圈进度(右下角):已检 = 满环 -->
<div class="banner-progress">
<svg width="52" height="52" viewBox="0 0 52 52" fill="none">
<circle cx="26" cy="26" r="21" stroke="rgba(255,255,255,0.35)" stroke-width="4"/>
<circle cx="26" cy="26" r="21" stroke="#ffffff" stroke-width="4" stroke-linecap="round" stroke-dasharray="131.9" stroke-dashoffset="0" transform="rotate(-90 26 26)"/>
</svg>
<span class="banner-progress__text"></span>
<span class="banner-progress__text"></span>
</div>
</div>
@@ -484,7 +484,7 @@
<span class="banner-slide__deco">🔬</span>
<div class="banner-slide__title">单位已拟定2026年度胃肠镜体检计划</div>
<div class="banner-slide__date">🗓 体检日期:2026-10-08 至 2026-12-20</div>
<!-- 圆圈进度(右下角):已预约 = 60%(已选项目20%→已预约60%→体检中80%→已检100%),dashoffset = 131.9 × 40% ≈ 52.8 -->
<!-- 圆圈进度(右下角):已预约 = 60%(已选项目20%→已预约60%→体检中80%→已检100%),dashoffset = 131.9 × 40% ≈ 52.8 -->
<div class="banner-progress">
<svg width="52" height="52" viewBox="0 0 52 52" fill="none">
<circle cx="26" cy="26" r="21" stroke="rgba(255,255,255,0.35)" stroke-width="4"/>
@@ -500,7 +500,7 @@
<span class="banner-slide__deco">🫀</span>
<div class="banner-slide__title">单位已拟定2026年度冠脉CTA体检计划</div>
<div class="banner-slide__date">🗓 体检日期:2026-10-08 至 2026-12-20</div>
<!-- 圆圈进度(右下角):已预约 = 60%(已选项目20%→已预约60%→体检中80%→已检100%),dashoffset = 131.9 × 40% ≈ 52.8 -->
<!-- 圆圈进度(右下角):已预约 = 60%(已选项目20%→已预约60%→体检中80%→已检100%),dashoffset = 131.9 × 40% ≈ 52.8 -->
<div class="banner-progress">
<svg width="52" height="52" viewBox="0 0 52 52" fill="none">
<circle cx="26" cy="26" r="21" stroke="rgba(255,255,255,0.35)" stroke-width="4"/>
@@ -588,7 +588,7 @@
<div class="quick-card__icon" style="background:#eef9ff; color:#1677ff;">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 8v4l2.5 2.5"/></svg>
</div>
<div class="quick-card__title">操作流程讲解</div>
<div class="quick-card__title">操作说明</div>
<div class="quick-card__desc">查看预约、到院、报告查询等关键流程说明。</div>
</div>
@@ -142,23 +142,6 @@
box-shadow: var(--paper-shadow);
}
.year-bar__label { font-size: 12px; font-weight: 700; color: var(--text-secondary); }
.hero-stats {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 8px;
padding: 10px 14px 2px;
}
.hero-stat {
background: var(--primary-light);
border-radius: 12px;
padding: 8px 4px;
text-align: center;
}
.hero-stat__value { font-size: 17px; font-weight: 800; color: var(--primary-dark); line-height: 1.2; }
.hero-stat__label { font-size: 10px; color: var(--text-muted); margin-top: 2px; }
.hero-stat--danger .hero-stat__value { color: var(--danger); }
.hero-stat--warn .hero-stat__value { color: var(--warning); }
.hero-stat--success .hero-stat__value { color: var(--success); }
.hero-card__text {
padding: 10px 14px 12px;
font-size: 12px;
@@ -358,24 +341,6 @@
<span class="hero-card__title" id="heroTitle">五年纵向对比总结</span>
</div>
<div class="hero-card__range" id="heroRangeMeta" style="margin-left:0;padding:8px 14px 0;"></div>
<div class="hero-stats">
<div class="hero-stat hero-stat--danger">
<div class="hero-stat__value" id="statAbn">5</div>
<div class="hero-stat__label">期末异常</div>
</div>
<div class="hero-stat hero-stat--warn">
<div class="hero-stat__value" id="statWorse">3</div>
<div class="hero-stat__label">变化趋势</div>
</div>
<div class="hero-stat hero-stat--danger">
<div class="hero-stat__value" id="statNew">1</div>
<div class="hero-stat__label">新增异常</div>
</div>
<div class="hero-stat hero-stat--success">
<div class="hero-stat__value" id="statBetter">2</div>
<div class="hero-stat__label">转好恢复</div>
</div>
</div>
<!-- [交互] 总结文案随所选年份区间由脚本按区间数据重新生成 -->
<div class="hero-card__text">
<p id="heroLead"></p>
@@ -422,23 +387,23 @@
{ name: '血常规', keys: ['hgb', 'wbc', 'plt'] }
];
var NUM = {
bmi: { name: 'BMI', unit: 'kg/m²', ref: [18.5, 23.9], v: [23.1, 23.8, 24.5, 25.2, 25.8], badge: ['变化趋势', 'worse'] },
sbp: { name: '收缩压', unit: 'mmHg', ref: [90, 139], v: [112, 115, 118, 116, 120], badge: ['平稳', 'stable'] },
dbp: { name: '舒张压', unit: 'mmHg', ref: [60, 89], v: [72, 74, 73, 76, 78], badge: ['平稳', 'stable'] },
tc: { name: '总胆固醇 TC', unit: 'mmol/L', ref: [3.1, 5.7], v: [4.62, 4.95, 5.36, 5.78, 6.10], badge: ['变化趋势', 'worse'] },
tg: { name: '甘油三酯 TG', unit: 'mmol/L', ref: [0.4, 1.7], v: [1.20, 1.35, 1.55, 1.72, 2.08], badge: ['变化趋势', 'worse'] },
hdl: { name: '高密度脂蛋白 HDL-C', unit: 'mmol/L', ref: [1.04, 1.55], v: [1.35, 1.30, 1.26, 1.22, 1.18], badge: ['平稳', 'stable'] },
ldl: { name: '低密度脂蛋白 LDL-C', unit: 'mmol/L', ref: [0, 3.4], v: [2.80, 3.00, 3.10, 3.35, 3.92], badge: ['新增异常', 'new'] },
glu: { name: '空腹血糖 GLU', unit: 'mmol/L', ref: [3.9, 6.1], v: [5.0, 5.1, 4.9, 5.3, 5.2], badge: ['平稳', 'stable'] },
hba1c:{ name: '糖化血红蛋白 HbA1c', unit: '%', ref: [4.0, 6.0], v: [5.2, 5.3, 5.1, 5.4, 5.6], badge: ['平稳', 'stable'] },
ua: { name: '尿酸 UA', unit: 'μmol/L', ref: [155, 357], v: [330, 362, 371, 380, 389], badge: ['连续异常', 'keep'] },
crea: { name: '肌酐 CREA', unit: 'μmol/L', ref: [41, 73], v: [66, 68, 69, 70, 71], badge: ['平稳', 'stable'] },
urea: { name: '尿素 UREA', unit: 'mmol/L', ref: [2.8, 7.2], v: [4.5, 5.0, 4.6, 5.2, 4.8], badge: ['平稳', 'stable'] },
alt: { name: '丙氨酸氨基转移酶 ALT', unit: 'U/L', ref: [7, 40], v: [28, 31, 35, 42, 24.6], badge: ['转好', 'better'] },
ast: { name: '天门冬氨酸氨基转移酶 AST', unit: 'U/L', ref: [13, 35], v: [24, 26, 28, 38, 22.4], badge: ['转好', 'better'] },
hgb: { name: '血红蛋白 HGB', unit: 'g/L', ref: [115, 150], v: [140, 138, 141, 139, 136], badge: ['平稳', 'stable'] },
wbc: { name: '白细胞计数 WBC', unit: '10^9/L', ref: [3.5, 9.5], v: [6.2, 6.5, 6.1, 6.9, 6.8], badge: ['平稳', 'stable'] },
plt: { name: '血小板计数 PLT', unit: '10^9/L', ref: [125, 350], v: [220, 235, 240, 252, 248], badge: ['平稳', 'stable'] }
bmi: { name: 'BMI', unit: 'kg/m²', ref: [18.5, 23.9], v: [23.1, 23.8, 24.5, 25.2, 25.8] },
sbp: { name: '收缩压', unit: 'mmHg', ref: [90, 139], v: [112, 115, 118, 116, 120] },
dbp: { name: '舒张压', unit: 'mmHg', ref: [60, 89], v: [72, 74, 73, 76, 78] },
tc: { name: '总胆固醇 TC', unit: 'mmol/L', ref: [3.1, 5.7], v: [4.62, 4.95, 5.36, 5.78, 6.10] },
tg: { name: '甘油三酯 TG', unit: 'mmol/L', ref: [0.4, 1.7], v: [1.20, 1.35, 1.55, 1.72, 2.08] },
hdl: { name: '高密度脂蛋白 HDL-C', unit: 'mmol/L', ref: [1.04, 1.55], v: [1.35, 1.30, 1.26, 1.22, 1.18] },
ldl: { name: '低密度脂蛋白 LDL-C', unit: 'mmol/L', ref: [0, 3.4], v: [2.80, 3.00, 3.10, 3.35, 3.92] },
glu: { name: '空腹血糖 GLU', unit: 'mmol/L', ref: [3.9, 6.1], v: [5.0, 5.1, 4.9, 5.3, 5.2] },
hba1c:{ name: '糖化血红蛋白 HbA1c', unit: '%', ref: [4.0, 6.0], v: [5.2, 5.3, 5.1, 5.4, 5.6] },
ua: { name: '尿酸 UA', unit: 'μmol/L', ref: [155, 357], v: [360, 362, 371, 380, 389] },
crea: { name: '肌酐 CREA', unit: 'μmol/L', ref: [41, 73], v: [66, 68, 69, 70, 71] },
urea: { name: '尿素 UREA', unit: 'mmol/L', ref: [2.8, 7.2], v: [4.5, 5.0, 4.6, 5.2, 4.8] },
alt: { name: '丙氨酸氨基转移酶 ALT', unit: 'U/L', ref: [7, 40], v: [28, 31, 35, 42, 24.6] },
ast: { name: '天门冬氨酸氨基转移酶 AST', unit: 'U/L', ref: [13, 35], v: [24, 26, 28, 38, 22.4] },
hgb: { name: '血红蛋白 HGB', unit: 'g/L', ref: [115, 150], v: [140, 138, 141, 139, 136] },
wbc: { name: '白细胞计数 WBC', unit: '10^9/L', ref: [3.5, 9.5], v: [6.2, 6.5, 6.1, 6.9, 6.8] },
plt: { name: '血小板计数 PLT', unit: '10^9/L', ref: [125, 350], v: [220, 235, 240, 252, 248] }
};
// 定性项目:statuses 五年逐项状态(n 正常 / a 异常 / m 未检)
var QUAL = [
@@ -459,27 +424,39 @@
}
// 取指标在当前区间内的数值序列
function vals(it) { var r = range(); return it.v.slice(r.a, r.b + 1); }
// 区间内是否呈不利走向(端点对比方向性变化),随所选区间动态计算
function deltaWorse(key) {
var it = NUM[key], vv = vals(it);
if (vv.length < 2) return false;
var first = vv[0], last = vv[vv.length - 1];
var hi = it.ref[1], lo = it.ref[0];
if (hi < Infinity && last > hi) return last > first;
return last < lo ? last < first : false;
// 指标轨迹分类(唯一口径,同时用于指标卡徽章与总结卡统计)
// worse=异常趋势 new=新增异常 keep=持续异常 better=转好 stable=平稳
function classify(key) {
var it = NUM[key], vv = vals(it), n = vv.length;
var lo = it.ref[0], hi = it.ref[1];
var abn = vv.map(function (v) { return v < lo || v > hi; });
var lastAbn = abn[n - 1], firstAbn = abn[0];
if (!lastAbn) {
return abn.some(function (x) { return x; }) ? 'better' : 'stable';
}
// 末年异常
var tail = 0;
for (var i = n - 1; i >= 0 && abn[i]; i--) tail++;
if (tail === 1) return 'new'; // 仅末年越限:今年首次异常
if (firstAbn) return 'keep'; // 区间起点已异常:老问题持续
var first = vv[0], last = vv[n - 1];
if (last > hi) return last > first ? 'worse' : 'keep';
return last < first ? 'worse' : 'keep';
}
// 组内排序权重:期末异常在前;区间内不利走向 > 期末新增 > 区间内全程异常 > 区间内转好 > 静态分级兜底
var BADGE = {
worse: { label: '异常趋势', cls: 'worse' },
new: { label: '新增异常', cls: 'new' },
keep: { label: '持续异常', cls: 'keep' },
better: { label: '转好', cls: 'better' },
stable: { label: '平稳', cls: 'stable' }
};
function badgeOf(key) { return BADGE[classify(key)]; }
// 组内排序权重:期末异常在前;异常 > 新增 > 持续 > 转好 > 平稳
function weight(key) {
var it = NUM[key], r = range(), e = r.b, s = r.a;
var lastAbn = isAbn(it, e), firstAbn = isAbn(it, s);
var abn = lastAbn ? 0 : 1;
var order;
if (deltaWorse(key)) order = 0;
else if (lastAbn && !firstAbn) order = 1;
else if (lastAbn) order = 2;
else if (!lastAbn && firstAbn) order = 3;
else order = 4 + ({ worse: 0, new: 1, keep: 2, better: 3, stable: 4 }[it.badge[1]] || 4);
return abn * 10 + order;
var it = NUM[key], r = range(), e = r.b;
var lastAbn = isAbn(it, e);
var order = { worse: 0, new: 1, keep: 2, better: 3, stable: 4 }[classify(key)];
return (lastAbn ? 0 : 1) * 10 + order;
}
// 缩略趋势线(纯内联 SVG,按所选区间取点,异常点标红)
function sparkline(item) {
@@ -497,20 +474,6 @@
return '<svg width="' + w + '" height="' + h + '" viewBox="0 0 ' + w + ' ' + h + '"><polyline points="' + pts.join(' ') + '" fill="none" stroke="#13c2c2" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>' + dots + '</svg>';
}
function fmtV(v) { return v >= 100 ? String(Math.round(v)) : String(v); }
// 区间端点对比:返回 {last, delta, worse, newAbn, keepAbn, better, n}
function endCompare(it) {
var r = range(), vv = vals(it);
var first = vv[0], last = vv[vv.length - 1];
var hi = it.ref[1], lo = it.ref[0];
var lastAbn = last < lo || last > hi, firstAbn = first < lo || first > hi;
var worse = (hi < Infinity && last > hi) ? last > first : (last < lo ? last < first : false);
var allAbn = vv.every(function (v) { return v < lo || v > hi; });
return { r: r, last: last, delta: last - first, worse: worse, newAbn: lastAbn && !firstAbn, keepAbn: lastAbn && firstAbn && allAbn, better: !lastAbn && firstAbn };
}
function fmtDelta(it, d) {
var dec = it.v[0] >= 100 || Math.abs(d) >= 10 ? 0 : (Math.abs(d) >= 1 ? 1 : 2);
return (d > 0 ? '+' : '') + d.toFixed(dec);
}
// ===== 渲染数值指标分组(大类折叠卡,默认全部展开;点击大类头可收起)=====
var filter = 'all';
@@ -530,9 +493,10 @@
if (!show) return;
shown++;
var arrow = abn ? (last > it.ref[1] ? ' ↑' : ' ↓') : '';
var badge = badgeOf(key);
cards += '<div class="metric-card" data-key="' + key + '" onclick="goDetail(\'' + key + '\')">'
+ '<div class="metric-card__top"><span class="metric-card__name">' + it.name + '</span>'
+ '<span class="badge badge--' + it.badge[1] + '">' + it.badge[0] + '</span></div>'
+ '<span class="badge badge--' + badge.cls + '">' + badge.label + '</span></div>'
+ '<div class="metric-card__bottom"><div>'
+ '<div class="metric-card__value' + (abn ? ' is-abn' : '') + '">' + fmtV(last) + arrow + '<span class="metric-card__unit">' + it.unit + '</span></div>'
+ '<div class="metric-card__ref">参考 ' + it.ref[0] + '-' + it.ref[1] + '</div></div>'
@@ -598,32 +562,29 @@
document.getElementById('qualBody').innerHTML = html || '<div class="metric-card__ref" style="text-align:center;padding:16px 0">该筛选条件下暂无定性项目</div>';
}
// ===== AI 总结文案(按所选区间数据生成,模拟端点对比口径=====
// ===== AI 总结文案(按所选区间 + classify 轨迹分类生成=====
function buildSummary() {
var r = range();
var nums = Object.keys(NUM).map(function (k) {
var it = NUM[k];
return { key: k, it: it, cmp: endCompare(it) };
var items = Object.keys(NUM).map(function (k) {
return { name: NUM[k].name, cls: classify(k) };
});
var abnNums = nums.filter(function (x) { var l = x.cmp.last; return l < x.it.ref[0] || l > x.it.ref[1]; });
var lead;
function by(cls) { return items.filter(function (x) { return x.cls === cls; }).map(function (x) { return x.name; }); }
var worse = by('worse'), added = by('new'), keep = by('keep'), better = by('better'), stable = by('stable');
var abnCount = worse.length + added.length + keep.length;
var lead, notes = [];
if (r.n === 1) {
// 单年度:只报当年结果,不做趋势对比
lead = r.ys[0] + ' 年度体检共 ' + abnNums.length + ' 项指标处于参考范围之外' +
(abnNums.length ? '' + abnNums.map(function (x) { return x.it.name; }).join('、') + '。' : '。');
lead = r.ys[0] + ' 年度体检共 ' + abnCount + ' 项指标处于参考范围之外' +
(abnCount ? '' + worse.concat(added, keep).join('、') + '。' : '。');
} else {
lead = '在 ' + r.ys[0] + '' + r.ys[r.n - 1] + ' 共 ' + r.n + ' 次体检中,您的多项指标呈持续上行趋势:' +
nums.filter(function (x) { return x.cmp.worse; }).map(function (x) { return x.it.name; }).join('、') +
' 较 ' + r.ys[0] + ' 年分别升高 ' +
nums.filter(function (x) { return x.cmp.worse; }).map(function (x) { return fmtDelta(x.it, x.cmp.delta); }).join(' / ') +
';期末共 ' + abnNums.length + ' 项指标处于参考范围之外。';
var parts = [];
if (worse.length) parts.push(worse.join('、') + ' 较 ' + r.ys[0] + ' 年呈持续升高趋势');
if (added.length) parts.push(added.join('、') + ' 于 ' + r.ys[r.n - 1] + ' 年首次超出参考范围');
if (keep.length) parts.push(keep.join('') + ' 多年持续偏高');
lead = '在 ' + r.ys[0] + '' + r.ys[r.n - 1] + ' 共 ' + r.n + ' 次体检中,' + parts.join('') +
'。期末共 ' + abnCount + ' 项指标处于参考范围之外。';
if (better.length) notes.push(better.join('、') + ' 已恢复至正常范围');
if (stable.length) notes.push('其余 ' + stable.length + ' 项指标持续平稳');
}
var notes = r.n > 1 ? nums.filter(function (x) { return x.cmp.newAbn || x.cmp.keepAbn || x.cmp.better; }).map(function (x) {
var y = r.n + ' 年间';
if (x.cmp.newAbn) return x.it.name + y + '首次越限';
if (x.cmp.keepAbn) return x.it.name + y + '持续高于正常范围';
return x.it.name + y + '回归正常范围';
}) : [];
var qualNotes = QUAL.map(function (q) {
var st = q.st.slice(r.a, r.b + 1);
var n = st.length, tail = 0, head = -1;
@@ -647,13 +608,6 @@
document.getElementById('heroTitle').textContent = r.n + ' 年纵向对比总结';
document.getElementById('heroRangeMeta').textContent =
r.ys[0] + ' - ' + r.ys[r.n - 1] + ' · 覆盖 ' + r.n + ' 次体检';
var nums = Object.keys(NUM).map(function (k) { return { it: NUM[k], cmp: endCompare(NUM[k]) }; });
document.getElementById('statAbn').textContent = nums.filter(function (x) {
return x.cmp.last < x.it.ref[0] || x.cmp.last > x.it.ref[1];
}).length;
document.getElementById('statWorse').textContent = nums.filter(function (x) { return x.cmp.worse; }).length;
document.getElementById('statNew').textContent = nums.filter(function (x) { return x.cmp.newAbn; }).length;
document.getElementById('statBetter').textContent = nums.filter(function (x) { return x.cmp.better; }).length;
var sum = buildSummary();
document.getElementById('heroLead').textContent = sum.lead;
document.getElementById('heroNotes').textContent = sum.notes;
@@ -463,7 +463,7 @@
<div class="summary-item"><div class="summary-item__label">预约日期</div><div class="summary-item__value">2026-03-23</div></div>
<div class="summary-item"><div class="summary-item__label">体检员工</div><div class="summary-item__value">张旭</div></div>
<div class="summary-item"><div class="summary-item__label">单位部门</div><div class="summary-item__value">采油一厂·xx作业区</div></div>
<div class="summary-item"><div class="summary-item__label">状态</div><div class="summary-item__value" style="color:#52c41a;"></div></div>
<div class="summary-item"><div class="summary-item__label">状态</div><div class="summary-item__value" style="color:#52c41a;"></div></div>
</div>
</div>
<div class="progress-card">
@@ -512,13 +512,6 @@
<div class="tips-card__item"><span class="tips-card__dot"></span><span>若选择无痛胃肠镜,检查后24小时内请勿驾车。</span></div>
<div class="tips-card__item"><span class="tips-card__dot"></span><span>若需取消预约,请至少提前一天操作。</span></div>
</div>
<div class="progress-card">
<div class="section-title">项目列表</div>
<div class="project-list">
<div class="project-item"><div class="project-item__icon project-item__icon--pending">&#9679;</div><div class="project-item__name">胃镜检查</div><div class="project-item__status project-item__status--pending">未检</div></div>
<div class="project-item"><div class="project-item__icon project-item__icon--pending">&#9679;</div><div class="project-item__name">肠镜检查</div><div class="project-item__status project-item__status--pending">未检</div></div>
</div>
</div>
</div>
<!-- ======================= 胃肠镜体检 · 已完成 ======================= -->
@@ -531,14 +524,7 @@
<div class="summary-item"><div class="summary-item__label">体检地址</div><div class="summary-item__value">银川市西夏区怀远路148号</div></div>
<div class="summary-item"><div class="summary-item__label">体检日期</div><div class="summary-item__value">2026年3月23日</div></div>
<div class="summary-item"><div class="summary-item__label">体检项目</div><div class="summary-item__value">胃肠镜体检</div></div>
<div class="summary-item"><div class="summary-item__label">状态</div><div class="summary-item__value" style="color:#52c41a;"></div></div>
</div>
</div>
<div class="progress-card">
<div class="section-title">项目列表</div>
<div class="project-list">
<div class="project-item"><div class="project-item__icon project-item__icon--done">&#10003;</div><div class="project-item__name">胃镜检查</div><div class="project-item__status project-item__status--done">已体检</div></div>
<div class="project-item"><div class="project-item__icon project-item__icon--done">&#10003;</div><div class="project-item__name">肠镜检查</div><div class="project-item__status project-item__status--done">已体检</div></div>
<div class="summary-item"><div class="summary-item__label">状态</div><div class="summary-item__value" style="color:#52c41a;"></div></div>
</div>
</div>
</div>
@@ -578,13 +564,6 @@
<div class="tips-card__item"><span class="tips-card__dot"></span><span>请携带本人身份证件按时前往医院。</span></div>
<div class="tips-card__item"><span class="tips-card__dot"></span><span>若需取消预约,请至少提前一天操作。</span></div>
</div>
<div class="progress-card">
<div class="section-title">项目列表</div>
<div class="project-list">
<div class="project-item"><div class="project-item__icon project-item__icon--pending">&#9679;</div><div class="project-item__name">冠脉钙化积分扫描</div><div class="project-item__status project-item__status--pending">未检</div></div>
<div class="project-item"><div class="project-item__icon project-item__icon--pending">&#9679;</div><div class="project-item__name">冠脉CTA成像</div><div class="project-item__status project-item__status--pending">未检</div></div>
</div>
</div>
</div>
<!-- ======================= 冠脉CTA体检 · 已完成 ======================= -->
@@ -597,14 +576,7 @@
<div class="summary-item"><div class="summary-item__label">体检地址</div><div class="summary-item__value">银川市西夏区怀远路148号</div></div>
<div class="summary-item"><div class="summary-item__label">体检日期</div><div class="summary-item__value">2026年3月23日</div></div>
<div class="summary-item"><div class="summary-item__label">体检项目</div><div class="summary-item__value">冠脉CTA体检</div></div>
<div class="summary-item"><div class="summary-item__label">状态</div><div class="summary-item__value" style="color:#52c41a;"></div></div>
</div>
</div>
<div class="progress-card">
<div class="section-title">项目列表</div>
<div class="project-list">
<div class="project-item"><div class="project-item__icon project-item__icon--done">&#10003;</div><div class="project-item__name">冠脉钙化积分扫描</div><div class="project-item__status project-item__status--done">已体检</div></div>
<div class="project-item"><div class="project-item__icon project-item__icon--done">&#10003;</div><div class="project-item__name">冠脉CTA成像</div><div class="project-item__status project-item__status--done">已体检</div></div>
<div class="summary-item"><div class="summary-item__label">状态</div><div class="summary-item__value" style="color:#52c41a;"></div></div>
</div>
</div>
</div>
@@ -727,7 +699,7 @@
(isDone ? '&#10003;' : '&#9679;') + '</div>' +
'<div class="project-item__name">' + name + '</div>' +
'<div class="project-item__status project-item__status--' + (isDone ? 'done' : 'pending') + '">' +
(isDone ? '已检' : '未检') + '</div></div>';
(isDone ? '已检' : '未检') + '</div></div>';
}
// 按前缀填充某面板的已检/未检列表
+35 -35
View File
@@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>操作流程讲解</title>
<title>操作说明</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
:root {
@@ -85,33 +85,32 @@
.scroll-content::-webkit-scrollbar { display: none; }
.page-body { padding: 14px 16px 28px; }
/* 分段筛选 */
.seg-tabs {
display: flex;
background: #fff;
border-radius: 12px;
padding: 4px;
/* 搜索框 */
.search-bar {
position: relative;
margin-bottom: 14px;
box-shadow: 0 4px 14px rgba(0,0,0,0.05);
}
.search-input {
width: 100%;
height: 40px;
border-radius: 20px;
background: #fff;
border: 1px solid #f0f0f0;
}
.seg-tab {
flex: 1;
height: 36px;
border-radius: 9px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 42px 0 16px;
font-size: 14px;
font-weight: 600;
color: var(--text-secondary);
cursor: pointer;
transition: all 0.2s;
color: var(--text-primary);
outline: none;
box-shadow: 0 4px 14px rgba(0,0,0,0.05);
}
.seg-tab.active {
background: var(--primary);
color: #fff;
box-shadow: 0 4px 10px rgba(19, 194, 194, 0.25);
.search-input::placeholder { color: var(--text-muted); }
.search-bar .search-icon {
position: absolute;
right: 14px;
top: 50%;
transform: translateY(-50%);
color: var(--text-muted);
pointer-events: none;
display: flex;
}
/* 讲解列表 */
@@ -213,16 +212,17 @@
<div class="nav-bar">
<a class="nav-back" href="index.html">&#8249;</a>
<span class="nav-title">操作流程讲解</span>
<span class="nav-title">操作说明</span>
</div>
<div class="scroll-content">
<div class="page-body">
<!-- 分段筛选 -->
<div class="seg-tabs">
<div class="seg-tab active" data-filter="all" onclick="filterGuides('all', this)">全部</div>
<div class="seg-tab" data-filter="video" onclick="filterGuides('video', this)">视频讲解</div>
<div class="seg-tab" data-filter="image" onclick="filterGuides('image', this)">图文讲解</div>
<!-- 搜索框 -->
<div class="search-bar">
<input class="search-input" type="text" placeholder="标题搜索" oninput="searchGuides(this.value)">
<span class="search-icon">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><circle cx="11" cy="11" r="7"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg>
</span>
</div>
<!-- 讲解列表 -->
@@ -316,12 +316,12 @@
</div>
<script>
// 分段筛选
function filterGuides(type, el) {
document.querySelectorAll('.seg-tab').forEach(function(t){ t.classList.remove('active'); });
el.classList.add('active');
// 搜索讲解:按标题/描述过滤列表
function searchGuides(keyword) {
keyword = keyword.trim().toLowerCase();
document.querySelectorAll('.guide-card').forEach(function(card){
if (type === 'all' || card.dataset.type === type) {
var text = card.textContent.toLowerCase();
if (!keyword || text.indexOf(keyword) !== -1) {
card.removeAttribute('hidden');
} else {
card.setAttribute('hidden', '');
+94 -5
View File
@@ -316,6 +316,72 @@
cursor: pointer;
padding: 0;
}
.insight-card__body {
position: relative;
}
.insight-card__body .insight-card__fade {
left: 0;
right: 0;
}
.interpret-subhead {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
margin-bottom: 8px;
}
.interpret-subhead__label {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 13px;
font-weight: 700;
color: #0d7878;
}
.interpret-subhead__label::before {
content: '';
width: 3px;
height: 13px;
border-radius: 2px;
background: var(--primary);
}
.interpret-meta {
margin-top: 12px;
padding-top: 10px;
border-top: 1px dashed var(--line);
display: flex;
flex-direction: column;
gap: 8px;
}
.interpret-meta__row {
display: flex;
align-items: center;
gap: 12px;
font-size: 12px;
line-height: 1.5;
}
.interpret-meta__label {
color: var(--text-muted);
white-space: nowrap;
flex-shrink: 0;
min-width: 84px;
}
.interpret-meta__value {
color: var(--text-primary);
font-weight: 600;
}
.interpret-meta__tag {
display: inline-flex;
align-items: center;
height: 22px;
padding: 0 10px;
border-radius: 11px;
font-size: 11px;
font-weight: 700;
background: #fff7e6;
color: #d46b08;
border: 1px solid #ffd591;
}
.report-table {
width: 100%;
border-collapse: collapse;
@@ -464,12 +530,35 @@
<div class="insight-card__title">体检报告解读</div>
</div>
<div class="insight-card__content">
<div class="insight-card__text">
本次体检整体完成度较高,绝大多数基础指标处于可接受范围。报告中主要需要关注的是体重管理、血脂水平、尿酸结果以及影像检查中提示的轻度脂肪肝和颈椎生理曲度变化。当前结果更偏向生活方式相关问题,暂未见需要立即进一步处置的急性风险信号。建议重点围绕饮食结构优化、规律运动、减少久坐、保证睡眠进行持续干预,并结合 3 个月后复查结果判断改善效果。
<div class="insight-card__body">
<div class="interpret-subhead">
<span class="interpret-subhead__label">综合解读结论</span>
<!-- [交互] 点击切换语音播报按钮状态 -->
<button class="insight-card__voice" type="button" onclick="toggleVoice(this)">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"/><path d="M15.54 8.46a5 5 0 0 1 0 7.07"/><path d="M19.07 4.93a10 10 0 0 1 0 14.14"/></svg>
</button>
</div>
<div class="insight-card__text">
本次体检整体完成度较高,绝大多数基础指标处于可接受范围。报告中主要需要关注的是体重管理、血脂水平、尿酸结果以及影像检查中提示的轻度脂肪肝和颈椎生理曲度变化。当前结果更偏向生活方式相关问题,暂未见需要立即进一步处置的急性风险信号。建议重点围绕饮食结构优化、规律运动、减少久坐、保证睡眠进行持续干预,并结合 3 个月后复查结果判断改善效果。
</div>
<div class="insight-card__fade"></div>
<!-- [交互] 点击展开/收起综合解读结论 -->
<button class="insight-card__toggle" type="button" onclick="toggleInsight('reportInterpretationCard', this)">展开</button>
</div>
<div class="interpret-meta">
<div class="interpret-meta__row">
<span class="interpret-meta__label">重新划分人群</span>
<span class="interpret-meta__tag">A类-大病人群</span>
</div>
<div class="interpret-meta__row">
<span class="interpret-meta__label">解读时间</span>
<span class="interpret-meta__value">2025-03-22</span>
</div>
<div class="interpret-meta__row">
<span class="interpret-meta__label">解读医生</span>
<span class="interpret-meta__value">王建国</span>
</div>
</div>
<div class="insight-card__fade"></div>
<!-- [交互] 点击展开/收起体检报告解读 -->
<button class="insight-card__toggle" type="button" onclick="toggleInsight('reportInterpretationCard', this)">展开</button>
</div>
</div>
+3 -3
View File
@@ -59,7 +59,7 @@
.sum-card__meta .k { opacity: 0.75; margin-right: 8px; }
.sum-card__meta .v { font-weight: 700; }
.sum-card__timeline { margin-left: auto; flex-shrink: 0; position: relative; z-index: 1; }
/* 五年趋势分析入口(精简条卡) */
/* 历年体检趋势分析入口(精简条卡) */
.trend-entry {
margin-top: 10px;
display: flex; align-items: center; gap: 10px;
@@ -155,8 +155,8 @@
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><polyline points="3 17 9 11 13 15 21 7"/><polyline points="15 7 21 7 21 13"/></svg>
</div>
<div class="trend-entry__main">
<div class="trend-entry__title">五年趋势分析</div>
<div class="trend-entry__desc">17 项重点指标 · 较2024新增异常 1 / 改善 2</div>
<div class="trend-entry__title">历年体检趋势分析</div>
<div class="trend-entry__desc">17 项重点指标 · 纵向对比历年体检数据</div>
</div>
<span class="trend-entry__go">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>
-2
View File
@@ -661,7 +661,6 @@ const SITE_MAP = [
] },
{ name:'健康体检', dir:'employee-app/health-checkup', entry:'index.html', prd:'employee-app/health-checkup/doc/PRD.md', pages:[
{ file:'index.html', label:'健康体检主页' },
{ file:'index-inactive.html', label:'健康体检-未开展' },
{ file:'booking-type.html', label:'选择体检类型' },
{ file:'booking-hospital.html', label:'预约-选择医院' },
{ file:'booking-project.html', label:'预约-选择项目' },
@@ -671,7 +670,6 @@ const SITE_MAP = [
{ file:'gastro-preselect.html', label:'胃肠镜医院预选' },
{ file:'gastro-preselect-done.html', label:'胃肠镜预选-已提交' },
{ file:'my-appointments-all.html', label:'现场体检' },
{ file:'hospital-checkin.html', label:'到院体检' },
{ file:'reports.html', label:'体检报告' },
{ file:'report-query.html', label:'报告查询详情' },
{ file:'indicator-compare.html', label:'指标纵向对比总览' },