refactor: 统一四个预警历史页面布局结构
- blood-oxygen-alerts.html:更新 stats-card 结构,添加最近预警时间显示 - temperature-alerts.html:完全重构为标准格式,采用与 heart-rate-alerts.html 相同的结构 - stress-alerts.html:已符合标准格式 - 四个页面现采用统一的 stats-card + alert-card 布局,保持各自的颜色主题 - 新增 health-monitor 模块 CHANGELOG.md 文档 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
<!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;
|
||||
--danger: #ff4d4f; --danger-light: #fff1f0;
|
||||
--text-primary: #1a1a1a; --text-secondary: #666666; --text-muted: #8c8c8c;
|
||||
--bg-page: #f0f2f5; --bg-content: #f7f9fb;
|
||||
--shadow: 0 10px 30px 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; }
|
||||
.scroll-content {
|
||||
flex: 1; overflow-y: auto;
|
||||
background: linear-gradient(180deg, #effbfb 0%, #f7f9fb 180px, #f7f9fb 100%);
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.page-body { padding: 16px; }
|
||||
/* 步骤条 */
|
||||
.stepper { display: flex; align-items: center; justify-content: center; margin-bottom: 18px; padding: 16px 0; }
|
||||
.stepper__item { display: flex; flex-direction: column; align-items: center; gap: 6px; cursor: pointer; text-decoration: none; }
|
||||
.stepper__item--future { cursor: default; pointer-events: none; opacity: 0.45; }
|
||||
.stepper__dot {
|
||||
width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
|
||||
font-size: 12px; font-weight: 700; background: #e8e8e8; color: #bfbfbf; transition: all 0.25s;
|
||||
}
|
||||
.stepper__item--done .stepper__dot { background: var(--primary); color: #fff; }
|
||||
.stepper__item--active { cursor: default; pointer-events: none; }
|
||||
.stepper__item--active .stepper__dot {
|
||||
width: 34px; height: 34px; font-size: 14px;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%); color: #fff;
|
||||
box-shadow: 0 0 0 6px rgba(19,194,194,0.2);
|
||||
}
|
||||
.stepper__label { font-size: 12px; color: var(--text-muted); white-space: nowrap; transition: all 0.2s; }
|
||||
.stepper__item--done .stepper__label { color: var(--primary-dark); }
|
||||
.stepper__item--active .stepper__label {
|
||||
color: var(--primary-dark); font-weight: 700; font-size: 13px;
|
||||
background: var(--primary-light); padding: 2px 10px; border-radius: 10px;
|
||||
}
|
||||
.stepper__item--done:hover .stepper__dot { transform: scale(1.12); box-shadow: 0 0 0 4px rgba(19,194,194,0.15); }
|
||||
.stepper__item--done:hover .stepper__label { text-decoration: underline; text-underline-offset: 3px; }
|
||||
.stepper__line { width: 44px; height: 3px; background: #e8e8e8; margin: 0 8px; margin-bottom: 22px; border-radius: 2px; }
|
||||
.stepper__line--done { background: var(--primary); }
|
||||
.section-title { font-size: 16px; font-weight: 700; margin-bottom: 14px; }
|
||||
/* 信息卡片 */
|
||||
.info-card {
|
||||
background: #fff; border-radius: 20px; padding: 18px 16px; margin-bottom: 14px;
|
||||
box-shadow: var(--shadow); border: 1px solid rgba(19,194,194,0.06);
|
||||
}
|
||||
.info-card__row {
|
||||
display: flex; justify-content: space-between; align-items: center;
|
||||
padding: 12px 0; border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
.info-card__row:first-child { padding-top: 0; }
|
||||
.info-card__row:last-child { border-bottom: none; padding-bottom: 0; }
|
||||
.info-card__label { font-size: 13px; color: var(--text-muted); }
|
||||
.info-card__value { font-size: 14px; font-weight: 600; color: var(--text-primary); text-align: right; }
|
||||
.info-card__value--highlight { color: var(--primary-dark); }
|
||||
/* 须知卡片 */
|
||||
.tips-card {
|
||||
background: #fff; border-radius: 20px; padding: 16px; margin-bottom: 14px;
|
||||
border: 1px solid #eef5f5; box-shadow: 0 8px 24px rgba(0,0,0,0.04);
|
||||
}
|
||||
.tips-card__title { font-size: 15px; font-weight: 700; margin-bottom: 10px; }
|
||||
.tips-card__item {
|
||||
display: flex; gap: 8px; font-size: 13px; line-height: 1.7;
|
||||
color: var(--text-secondary); margin-bottom: 8px;
|
||||
}
|
||||
.tips-card__item:last-child { margin-bottom: 0; }
|
||||
.tips-card__dot {
|
||||
width: 6px; height: 6px; border-radius: 50%; background: var(--primary);
|
||||
margin-top: 8px; flex-shrink: 0;
|
||||
}
|
||||
/* 底部按钮 */
|
||||
.bottom-actions {
|
||||
position: absolute; left: 16px; right: 16px; bottom: 18px;
|
||||
display: flex; gap: 12px; padding-bottom: 16px;
|
||||
}
|
||||
.bottom-actions__btn {
|
||||
flex: 1; height: 48px; border-radius: 24px; font-size: 15px; font-weight: 600; border: none; cursor: pointer;
|
||||
}
|
||||
.bottom-actions__btn--ghost {
|
||||
background: var(--danger-light); color: var(--danger); border: 1px solid rgba(255,77,79,0.2);
|
||||
}
|
||||
.bottom-actions__btn--primary {
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff; box-shadow: 0 10px 20px rgba(19,194,194,0.22);
|
||||
}
|
||||
/* Toast */
|
||||
.toast {
|
||||
position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%) scale(0.9);
|
||||
background: rgba(0,0,0,0.75); color: #fff; padding: 14px 22px; border-radius: 12px;
|
||||
font-size: 13px; line-height: 1.6; text-align: center; z-index: 200;
|
||||
opacity: 0; pointer-events: none; transition: all 0.25s ease; max-width: 280px;
|
||||
}
|
||||
.toast.show { opacity: 1; transform: translate(-50%, -50%) scale(1); }
|
||||
</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">
|
||||
<a class="nav-back" href="index.html">‹</a>
|
||||
<span class="nav-title">体检预约</span>
|
||||
</div>
|
||||
<div class="scroll-content">
|
||||
<div class="page-body">
|
||||
<!-- [交互] 步骤条可点击跳转 -->
|
||||
<div class="stepper">
|
||||
<!-- [交互] 已提交项目,点击步骤一弹提示,不跳转 -->
|
||||
<div class="stepper__item stepper__item--done" onclick="showToast()"><div class="stepper__dot">✓</div><div class="stepper__label">选择医院</div></div>
|
||||
<div class="stepper__line stepper__line--done"></div>
|
||||
<div class="stepper__item stepper__item--done" onclick="showToast()"><div class="stepper__dot">✓</div><div class="stepper__label">选择项目</div></div>
|
||||
<div class="stepper__line stepper__line--done"></div>
|
||||
<div class="stepper__item stepper__item--active"><div class="stepper__dot">✓</div><div class="stepper__label">预约日期</div></div>
|
||||
</div>
|
||||
|
||||
<!-- 预约成功信息 -->
|
||||
<div class="info-card">
|
||||
<div class="section-title">预约信息</div>
|
||||
<div class="info-card__row">
|
||||
<span class="info-card__label">体检医院</span>
|
||||
<span class="info-card__value">宁夏宝石花医院</span>
|
||||
</div>
|
||||
<div class="info-card__row">
|
||||
<span class="info-card__label">体检员工</span>
|
||||
<span class="info-card__value">刘韵琴</span>
|
||||
</div>
|
||||
<div class="info-card__row">
|
||||
<span class="info-card__label">体检地址</span>
|
||||
<span class="info-card__value">银川市西夏区怀远路148号</span>
|
||||
</div>
|
||||
<div class="info-card__row">
|
||||
<span class="info-card__label">体检日期</span>
|
||||
<span class="info-card__value info-card__value--highlight">2026年3月23日</span>
|
||||
</div>
|
||||
<div class="info-card__row">
|
||||
<span class="info-card__label">体检项目数</span>
|
||||
<span class="info-card__value info-card__value--highlight">9 项</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 体检须知 -->
|
||||
<div class="tips-card">
|
||||
<div class="tips-card__title">体检须知</div>
|
||||
<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 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>
|
||||
</div>
|
||||
|
||||
<div class="bottom-actions">
|
||||
<!-- [交互] 取消预约 -->
|
||||
<button class="bottom-actions__btn bottom-actions__btn--ghost" onclick="window.location.href='booking-date.html'">取消预约</button>
|
||||
<!-- [交互] 查看预约详情,跳转至 my-appointments-detail.html -->
|
||||
<button class="bottom-actions__btn bottom-actions__btn--primary" onclick="window.location.href='my-appointments-detail.html?done=0&total=9'">查看预约详情</button>
|
||||
</div>
|
||||
<div class="toast" id="stepToast">当前已预约体检,无法重新选择,请先取消预约</div>
|
||||
</div>
|
||||
<script>
|
||||
let toastTimer = null;
|
||||
function showToast() {
|
||||
const toast = document.getElementById('stepToast');
|
||||
toast.classList.add('show');
|
||||
clearTimeout(toastTimer);
|
||||
toastTimer = setTimeout(() => { toast.classList.remove('show'); }, 2200);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,417 @@
|
||||
<!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 30px 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; }
|
||||
.scroll-content {
|
||||
flex: 1; overflow-y: auto;
|
||||
background: linear-gradient(180deg, #effbfb 0%, #f7f9fb 180px, #f7f9fb 100%);
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.page-body { padding: 16px; }
|
||||
/* 步骤条 */
|
||||
.stepper { display: flex; align-items: center; justify-content: center; margin-bottom: 18px; padding: 16px 0; }
|
||||
.stepper__item { display: flex; flex-direction: column; align-items: center; gap: 6px; cursor: pointer; text-decoration: none; }
|
||||
.stepper__item--future { cursor: default; pointer-events: none; opacity: 0.45; }
|
||||
.stepper__dot {
|
||||
width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
|
||||
font-size: 12px; font-weight: 700; background: #e8e8e8; color: #bfbfbf; transition: all 0.25s;
|
||||
}
|
||||
.stepper__item--done .stepper__dot { background: var(--primary); color: #fff; }
|
||||
.stepper__item--active { cursor: default; pointer-events: none; }
|
||||
.stepper__item--active .stepper__dot {
|
||||
width: 34px; height: 34px; font-size: 14px;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%); color: #fff;
|
||||
box-shadow: 0 0 0 6px rgba(19,194,194,0.2);
|
||||
}
|
||||
.stepper__label { font-size: 12px; color: var(--text-muted); white-space: nowrap; transition: all 0.2s; }
|
||||
.stepper__item--done .stepper__label { color: var(--primary-dark); }
|
||||
.stepper__item--active .stepper__label {
|
||||
color: var(--primary-dark); font-weight: 700; font-size: 13px;
|
||||
background: var(--primary-light); padding: 2px 10px; border-radius: 10px;
|
||||
}
|
||||
.stepper__item--done:hover .stepper__dot { transform: scale(1.12); box-shadow: 0 0 0 4px rgba(19,194,194,0.15); }
|
||||
.stepper__item--done:hover .stepper__label { text-decoration: underline; text-underline-offset: 3px; }
|
||||
.stepper__line { width: 44px; height: 3px; background: #e8e8e8; margin: 0 8px; margin-bottom: 22px; border-radius: 2px; }
|
||||
.stepper__line--done { background: var(--primary); }
|
||||
.fee-banner {
|
||||
background: linear-gradient(135deg, #f0fffe 0%, #f7fffd 100%);
|
||||
border: 1px solid #d7f5f3; border-radius: 18px; padding: 14px 16px;
|
||||
display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px;
|
||||
}
|
||||
.fee-banner__label { font-size: 13px; color: var(--primary-dark); font-weight: 600; }
|
||||
.fee-banner__value { font-size: 24px; font-weight: 800; color: var(--primary-dark); }
|
||||
.section-title { font-size: 16px; font-weight: 700; margin-bottom: 14px; }
|
||||
.date-card {
|
||||
background: #fff; border-radius: 20px; padding: 18px 16px; margin-bottom: 14px;
|
||||
box-shadow: var(--shadow); border: 1px solid rgba(19,194,194,0.06);
|
||||
}
|
||||
.calendar-header {
|
||||
display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px;
|
||||
}
|
||||
.calendar-header__month { font-size: 17px; font-weight: 700; color: var(--text-primary); }
|
||||
.calendar-header__nav {
|
||||
display: flex; gap: 8px;
|
||||
}
|
||||
.calendar-header__btn {
|
||||
width: 32px; height: 32px; border-radius: 10px; border: 1px solid #e8e8e8;
|
||||
background: #fff; display: flex; align-items: center; justify-content: center;
|
||||
cursor: pointer; font-size: 14px; color: var(--text-secondary); transition: all 0.2s;
|
||||
}
|
||||
.calendar-header__btn:hover { border-color: var(--primary); color: var(--primary); }
|
||||
.calendar-header__btn:disabled { opacity: 0.3; pointer-events: none; }
|
||||
.calendar-weekdays {
|
||||
display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; margin-bottom: 8px;
|
||||
}
|
||||
.calendar-weekday {
|
||||
text-align: center; font-size: 12px; font-weight: 600; color: var(--text-muted); padding: 6px 0;
|
||||
}
|
||||
.calendar-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
|
||||
.calendar-cell {
|
||||
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||||
height: 52px; border-radius: 12px; cursor: pointer; transition: all 0.2s;
|
||||
border: 2px solid transparent; background: #f9fbfb; position: relative;
|
||||
}
|
||||
.calendar-cell:hover { border-color: var(--primary); }
|
||||
.calendar-cell.selected { background: var(--primary); border-color: var(--primary); }
|
||||
.calendar-cell.selected .calendar-cell__day,
|
||||
.calendar-cell.selected .calendar-cell__slots { color: #fff; }
|
||||
.calendar-cell.disabled {
|
||||
opacity: 0.3; pointer-events: none; background: #f5f5f5;
|
||||
}
|
||||
.calendar-cell.empty { background: transparent; pointer-events: none; }
|
||||
.calendar-cell__day { font-size: 15px; font-weight: 700; color: var(--text-primary); line-height: 1; }
|
||||
.calendar-cell__slots { font-size: 10px; color: var(--primary-dark); font-weight: 600; margin-top: 2px; }
|
||||
.calendar-cell.disabled .calendar-cell__slots { display: none; }
|
||||
.calendar-cell__full {
|
||||
font-size: 10px; color: var(--text-muted); font-weight: 600; margin-top: 2px;
|
||||
}
|
||||
.calendar-cell.today .calendar-cell__day {
|
||||
color: var(--primary-dark);
|
||||
}
|
||||
.calendar-cell.today { border-color: rgba(19,194,194,0.3); }
|
||||
.summary-card {
|
||||
background: #fff; border-radius: 20px; padding: 18px 16px; margin-bottom: 14px;
|
||||
box-shadow: var(--shadow); border: 1px solid rgba(19,194,194,0.06);
|
||||
}
|
||||
.summary-list { display: flex; flex-direction: column; gap: 14px; }
|
||||
.summary-item { display: flex; justify-content: space-between; gap: 12px; }
|
||||
.summary-item__label { font-size: 13px; color: var(--text-muted); flex-shrink: 0; }
|
||||
.summary-item__value { font-size: 14px; font-weight: 600; text-align: right; line-height: 1.6; }
|
||||
.person-card {
|
||||
margin-top: 0; background: linear-gradient(135deg, #ffffff 0%, #f8fffe 100%);
|
||||
border-radius: 20px; padding: 16px; border: 1px solid #e4f7f5; box-shadow: var(--shadow);
|
||||
}
|
||||
.person-card__header { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
|
||||
.person-card__avatar {
|
||||
width: 48px; height: 48px; border-radius: 16px;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #5cdbd3 100%);
|
||||
color: #fff; display: flex; align-items: center; justify-content: center;
|
||||
font-size: 18px; font-weight: 700; flex-shrink: 0;
|
||||
}
|
||||
.person-card__name { font-size: 16px; font-weight: 700; margin-bottom: 4px; }
|
||||
.person-card__meta { font-size: 12px; color: var(--text-muted); }
|
||||
.info-list { display: flex; flex-direction: column; gap: 14px; }
|
||||
.info-item { display: flex; justify-content: space-between; gap: 12px; }
|
||||
.info-item__label { font-size: 13px; color: var(--text-muted); flex-shrink: 0; }
|
||||
.info-item__value { font-size: 14px; font-weight: 600; text-align: right; line-height: 1.6; }
|
||||
.bottom-actions {
|
||||
position: absolute; left: 16px; right: 16px; bottom: 18px;
|
||||
display: flex; gap: 12px; padding-bottom: 16px;
|
||||
}
|
||||
.bottom-actions__btn {
|
||||
flex: 1; height: 48px; border-radius: 24px; font-size: 15px; font-weight: 600; border: none; cursor: pointer;
|
||||
}
|
||||
.bottom-actions__btn--ghost {
|
||||
background: #f5f5f5; color: var(--text-secondary); border: 1px solid #e8e8e8;
|
||||
}
|
||||
.bottom-actions__btn--primary {
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff; box-shadow: 0 10px 20px rgba(19,194,194,0.22);
|
||||
}
|
||||
/* 确认弹窗 */
|
||||
.modal-overlay {
|
||||
position: absolute; inset: 0; background: rgba(0,0,0,0.42); z-index: 120;
|
||||
display: flex; align-items: center; justify-content: center; padding: 24px;
|
||||
}
|
||||
.modal-overlay.hidden { display: none; }
|
||||
.confirm-modal {
|
||||
width: 100%; background: #fff; border-radius: 24px; padding: 22px 20px 18px;
|
||||
box-shadow: 0 20px 50px rgba(0,0,0,0.16);
|
||||
}
|
||||
.confirm-modal__title {
|
||||
font-size: 18px; font-weight: 700; color: var(--text-primary); text-align: center; margin-bottom: 8px;
|
||||
}
|
||||
.confirm-modal__desc {
|
||||
font-size: 13px; color: var(--text-muted); text-align: center; line-height: 1.6; margin-bottom: 18px;
|
||||
}
|
||||
.confirm-modal__info {
|
||||
background: #f7f9fb; border-radius: 16px; padding: 14px 16px; margin-bottom: 18px;
|
||||
}
|
||||
.confirm-modal__row {
|
||||
display: flex; justify-content: space-between; align-items: center; font-size: 14px;
|
||||
color: var(--text-secondary); margin-bottom: 12px;
|
||||
}
|
||||
.confirm-modal__row:last-child { margin-bottom: 0; }
|
||||
.confirm-modal__value { font-size: 15px; font-weight: 700; color: var(--text-primary); }
|
||||
.confirm-modal__value--highlight { color: var(--primary-dark); }
|
||||
.confirm-modal__actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
|
||||
.confirm-modal__btn {
|
||||
height: 44px; border-radius: 22px; font-size: 15px; font-weight: 600; border: none; cursor: pointer;
|
||||
}
|
||||
.confirm-modal__btn--ghost { background: #f5f5f5; color: var(--text-secondary); }
|
||||
.confirm-modal__btn--primary {
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%); color: #fff;
|
||||
}
|
||||
.toast {
|
||||
position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%) scale(0.9);
|
||||
background: rgba(0,0,0,0.75); color: #fff; padding: 14px 22px; border-radius: 12px;
|
||||
font-size: 13px; line-height: 1.6; text-align: center; z-index: 200;
|
||||
opacity: 0; pointer-events: none; transition: all 0.25s ease; max-width: 280px;
|
||||
}
|
||||
.toast.show { opacity: 1; transform: translate(-50%, -50%) scale(1); }
|
||||
</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">
|
||||
<a class="nav-back" href="index.html">‹</a>
|
||||
<span class="nav-title">体检预约</span>
|
||||
</div>
|
||||
<div class="scroll-content">
|
||||
<div class="page-body">
|
||||
<!-- [交互] 步骤条可点击跳转 -->
|
||||
<div class="stepper">
|
||||
<!-- [交互] 已提交项目,点击步骤一弹提示,不跳转 -->
|
||||
<div class="stepper__item stepper__item--done" onclick="showToast()"><div class="stepper__dot">✓</div><div class="stepper__label">选择医院</div></div>
|
||||
<div class="stepper__line stepper__line--done"></div>
|
||||
<a class="stepper__item stepper__item--done" href="booking-project-selected.html"><div class="stepper__dot">✓</div><div class="stepper__label">选择项目</div></a>
|
||||
<div class="stepper__line stepper__line--done"></div>
|
||||
<a class="stepper__item stepper__item--active" href="booking-date.html"><div class="stepper__dot">3</div><div class="stepper__label">预约日期</div></a>
|
||||
</div>
|
||||
<!-- <div class="fee-banner">-->
|
||||
<!-- <span class="fee-banner__label">您本年度的体检费用(元)</span>-->
|
||||
<!-- <span class="fee-banner__value">1500.00</span>-->
|
||||
<!-- </div>-->
|
||||
<div class="summary-card">
|
||||
<div class="section-title">体检信息</div>
|
||||
<div class="summary-list">
|
||||
<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">银川市西夏区怀远路148号</div></div>
|
||||
<!-- <div class="summary-item"><div class="summary-item__label">预计费用</div><div class="summary-item__value">¥680</div></div>-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="date-card">
|
||||
<div class="calendar-header">
|
||||
<span class="calendar-header__month" id="calendarMonth"></span>
|
||||
<div class="calendar-header__nav">
|
||||
<button class="calendar-header__btn" id="prevMonth">‹</button>
|
||||
<button class="calendar-header__btn" id="nextMonth">›</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="calendar-weekdays">
|
||||
<span class="calendar-weekday">一</span>
|
||||
<span class="calendar-weekday">二</span>
|
||||
<span class="calendar-weekday">三</span>
|
||||
<span class="calendar-weekday">四</span>
|
||||
<span class="calendar-weekday">五</span>
|
||||
<span class="calendar-weekday">六</span>
|
||||
<span class="calendar-weekday">日</span>
|
||||
</div>
|
||||
<div class="calendar-grid" id="calendarGrid"></div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-actions">
|
||||
<button class="bottom-actions__btn bottom-actions__btn--ghost" onclick="window.location.href='booking-project-selected.html'">上一步</button>
|
||||
<button class="bottom-actions__btn bottom-actions__btn--primary" onclick="openConfirm()">确定预约</button>
|
||||
</div>
|
||||
|
||||
<!-- [交互] 预约二次确认弹窗 -->
|
||||
<div class="modal-overlay hidden" id="confirmModal">
|
||||
<div class="confirm-modal">
|
||||
<div class="confirm-modal__title">确认预约信息</div>
|
||||
<div class="confirm-modal__desc">请确认以下预约信息无误</div>
|
||||
<div class="confirm-modal__info">
|
||||
<div class="confirm-modal__row">
|
||||
<span>体检医院</span>
|
||||
<span class="confirm-modal__value">宁夏宝石花医院</span>
|
||||
</div>
|
||||
<div class="confirm-modal__row">
|
||||
<span>体检项目数</span>
|
||||
<span class="confirm-modal__value" id="confirmCount">9 项</span>
|
||||
</div>
|
||||
<div class="confirm-modal__row">
|
||||
<span>体检日期</span>
|
||||
<span class="confirm-modal__value confirm-modal__value--highlight" id="confirmDate">--</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="confirm-modal__actions">
|
||||
<button class="confirm-modal__btn confirm-modal__btn--ghost" onclick="closeConfirm()">取消</button>
|
||||
<button class="confirm-modal__btn confirm-modal__btn--primary" onclick="window.location.href='booking-date-selected.html'">确认预约</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="toast" id="stepToast">当前已提交项目,如需重新选择医院,请先点击下方重选项目按钮</div>
|
||||
</div>
|
||||
<script>
|
||||
const today = new Date(2026, 2, 16); // 2026-03-16
|
||||
let currentYear = today.getFullYear();
|
||||
let currentMonth = today.getMonth();
|
||||
let selectedDate = null;
|
||||
|
||||
const grid = document.getElementById('calendarGrid');
|
||||
const monthLabel = document.getElementById('calendarMonth');
|
||||
const prevBtn = document.getElementById('prevMonth');
|
||||
const nextBtn = document.getElementById('nextMonth');
|
||||
let toastTimer = null;
|
||||
|
||||
function showToast() {
|
||||
const toast = document.getElementById('stepToast');
|
||||
toast.classList.add('show');
|
||||
clearTimeout(toastTimer);
|
||||
toastTimer = setTimeout(() => {
|
||||
toast.classList.remove('show');
|
||||
}, 2200);
|
||||
}
|
||||
|
||||
// 模拟可约数据:工作日可约,周末和已过日期不可约
|
||||
function getSlots(year, month, day) {
|
||||
const d = new Date(year, month, day);
|
||||
const dow = d.getDay();
|
||||
// 已过日期
|
||||
if (d < new Date(today.getFullYear(), today.getMonth(), today.getDate())) return -1;
|
||||
// 周末不可约
|
||||
if (dow === 0 || dow === 6) return 0;
|
||||
// 模拟剩余人数(用日期做伪随机)
|
||||
const seed = (day * 7 + month * 13) % 20;
|
||||
if (seed < 3) return 0; // 约满
|
||||
return seed + 2;
|
||||
}
|
||||
|
||||
function renderCalendar() {
|
||||
grid.innerHTML = '';
|
||||
monthLabel.textContent = `${currentYear}年${currentMonth + 1}月`;
|
||||
// 不允许切换到当月之前
|
||||
prevBtn.disabled = (currentYear === today.getFullYear() && currentMonth <= today.getMonth());
|
||||
|
||||
const firstDay = new Date(currentYear, currentMonth, 1);
|
||||
// 周一为起始(getDay: 0=周日,转为周一起始)
|
||||
let startDow = firstDay.getDay();
|
||||
startDow = startDow === 0 ? 6 : startDow - 1;
|
||||
const daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate();
|
||||
|
||||
// 填充前置空格
|
||||
for (let i = 0; i < startDow; i++) {
|
||||
const empty = document.createElement('div');
|
||||
empty.className = 'calendar-cell empty';
|
||||
grid.appendChild(empty);
|
||||
}
|
||||
|
||||
for (let day = 1; day <= daysInMonth; day++) {
|
||||
const cell = document.createElement('div');
|
||||
const slots = getSlots(currentYear, currentMonth, day);
|
||||
const isToday = (currentYear === today.getFullYear() && currentMonth === today.getMonth() && day === today.getDate());
|
||||
const isDisabled = slots <= 0;
|
||||
const isFull = slots === 0;
|
||||
const isPast = slots === -1;
|
||||
|
||||
let cls = 'calendar-cell';
|
||||
if (isToday) cls += ' today';
|
||||
if (isDisabled) cls += ' disabled';
|
||||
if (selectedDate && selectedDate.y === currentYear && selectedDate.m === currentMonth && selectedDate.d === day) {
|
||||
cls += ' selected';
|
||||
}
|
||||
cell.className = cls;
|
||||
|
||||
let slotsHtml = '';
|
||||
if (isPast) {
|
||||
slotsHtml = '';
|
||||
} else if (isFull) {
|
||||
slotsHtml = '<span class="calendar-cell__full">不可约</span>';
|
||||
} else if (slots > 0) {
|
||||
slotsHtml = `<span class="calendar-cell__slots">余${slots}</span>`;
|
||||
}
|
||||
|
||||
cell.innerHTML = `<span class="calendar-cell__day">${day}</span>${slotsHtml}`;
|
||||
|
||||
if (!isDisabled) {
|
||||
cell.addEventListener('click', () => {
|
||||
selectedDate = { y: currentYear, m: currentMonth, d: day };
|
||||
renderCalendar();
|
||||
});
|
||||
}
|
||||
|
||||
grid.appendChild(cell);
|
||||
}
|
||||
}
|
||||
|
||||
prevBtn.addEventListener('click', () => {
|
||||
currentMonth--;
|
||||
if (currentMonth < 0) { currentMonth = 11; currentYear--; }
|
||||
renderCalendar();
|
||||
});
|
||||
nextBtn.addEventListener('click', () => {
|
||||
currentMonth++;
|
||||
if (currentMonth > 11) { currentMonth = 0; currentYear++; }
|
||||
renderCalendar();
|
||||
});
|
||||
|
||||
// 默认选中今天
|
||||
selectedDate = { y: today.getFullYear(), m: today.getMonth(), d: today.getDate() };
|
||||
renderCalendar();
|
||||
|
||||
function openConfirm() {
|
||||
if (!selectedDate) return;
|
||||
const dateStr = `${selectedDate.y}年${selectedDate.m + 1}月${selectedDate.d}日`;
|
||||
document.getElementById('confirmDate').textContent = dateStr;
|
||||
document.getElementById('confirmModal').classList.remove('hidden');
|
||||
}
|
||||
function closeConfirm() {
|
||||
document.getElementById('confirmModal').classList.add('hidden');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,442 @@
|
||||
<!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;
|
||||
--border: #e8f3f3;
|
||||
--bg-page: #f0f2f5;
|
||||
--bg-content: #f7f9fb;
|
||||
--shadow: 0 10px 30px 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 180px, #f7f9fb 100%);
|
||||
padding-bottom: 120px;
|
||||
}
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.page-body { padding: 16px; }
|
||||
/* 步骤条 */
|
||||
.stepper { display: flex; align-items: center; justify-content: center; margin-bottom: 18px; padding: 16px 0; }
|
||||
.stepper__item { display: flex; flex-direction: column; align-items: center; gap: 6px; cursor: pointer; text-decoration: none; }
|
||||
.stepper__item--future { cursor: default; pointer-events: none; opacity: 0.45; }
|
||||
.stepper__dot {
|
||||
width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
|
||||
font-size: 12px; font-weight: 700; background: #e8e8e8; color: #bfbfbf; transition: all 0.25s;
|
||||
}
|
||||
.stepper__item--done .stepper__dot { background: var(--primary); color: #fff; }
|
||||
.stepper__item--active { cursor: default; pointer-events: none; }
|
||||
.stepper__item--active .stepper__dot {
|
||||
width: 34px; height: 34px; font-size: 14px;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%); color: #fff;
|
||||
box-shadow: 0 0 0 6px rgba(19,194,194,0.2);
|
||||
}
|
||||
.stepper__label { font-size: 12px; color: var(--text-muted); white-space: nowrap; transition: all 0.2s; }
|
||||
.stepper__item--done .stepper__label { color: var(--primary-dark); }
|
||||
.stepper__item--active .stepper__label {
|
||||
color: var(--primary-dark); font-weight: 700; font-size: 13px;
|
||||
background: var(--primary-light); padding: 2px 10px; border-radius: 10px;
|
||||
}
|
||||
.stepper__item--done:hover .stepper__dot { transform: scale(1.12); box-shadow: 0 0 0 4px rgba(19,194,194,0.15); }
|
||||
.stepper__item--done:hover .stepper__label { text-decoration: underline; text-underline-offset: 3px; }
|
||||
.stepper__line { width: 44px; height: 3px; background: #e8e8e8; margin: 0 8px; margin-bottom: 22px; border-radius: 2px; }
|
||||
.stepper__line--done { background: var(--primary); }
|
||||
.fee-card {
|
||||
background: linear-gradient(135deg, #f0fffe 0%, #f7fffd 100%);
|
||||
border: 1px solid #d7f5f3;
|
||||
border-radius: 18px;
|
||||
padding: 16px 18px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.fee-card__label {
|
||||
font-size: 13px;
|
||||
color: var(--primary-dark);
|
||||
font-weight: 600;
|
||||
}
|
||||
.fee-card__amount {
|
||||
font-size: 26px;
|
||||
font-weight: 800;
|
||||
color: var(--primary-dark);
|
||||
}
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 14px;
|
||||
margin-top: 6px;
|
||||
}
|
||||
.hospital-card {
|
||||
background: #fff;
|
||||
border-radius: 18px;
|
||||
padding: 16px;
|
||||
margin-bottom: 12px;
|
||||
border: 2px solid transparent;
|
||||
box-shadow: var(--shadow);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
transition: all 0.25s ease;
|
||||
}
|
||||
.hospital-card.active {
|
||||
border-color: var(--primary);
|
||||
background: var(--primary-light);
|
||||
}
|
||||
.hospital-card__info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
.hospital-card__icon {
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
border-radius: 14px;
|
||||
background: linear-gradient(135deg, #e6fffb 0%, #b5f5ec 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.hospital-card__name {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.hospital-card__addr {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.radio-dot {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #d9d9d9;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.25s ease;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.hospital-card.active .radio-dot {
|
||||
border-color: var(--primary);
|
||||
background: var(--primary);
|
||||
}
|
||||
.radio-dot::after {
|
||||
content: '';
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
opacity: 0;
|
||||
transition: opacity 0.25s ease;
|
||||
}
|
||||
.hospital-card.active .radio-dot::after { opacity: 1; }
|
||||
.person-card {
|
||||
margin-top: 20px;
|
||||
background: linear-gradient(135deg, #ffffff 0%, #f8fffe 100%);
|
||||
border-radius: 20px;
|
||||
padding: 16px;
|
||||
border: 1px solid #e4f7f5;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
.person-card__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.person-card__avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 16px;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #5cdbd3 100%);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.person-card__name {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.person-card__meta {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.info-list { display: flex; flex-direction: column; gap: 14px; }
|
||||
.info-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.info-item__label { font-size: 13px; color: var(--text-muted); }
|
||||
.info-item__value { font-size: 14px; color: var(--text-primary); font-weight: 600; }
|
||||
.bottom-actions {
|
||||
position: absolute;
|
||||
left: 16px;
|
||||
right: 16px;
|
||||
bottom: 18px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
.bottom-actions__btn {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
border-radius: 24px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 10px 20px rgba(19, 194, 194, 0.22);
|
||||
}
|
||||
.nav-right {
|
||||
position: absolute; right: 16px; font-size: 13px; color: var(--primary);
|
||||
font-weight: 600; cursor: pointer; display: flex; align-items: center; gap: 4px;
|
||||
}
|
||||
/* 弹窗 */
|
||||
.modal-overlay {
|
||||
position: absolute; inset: 0; background: rgba(0,0,0,0.45); z-index: 100;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
transition: opacity 0.25s ease;
|
||||
}
|
||||
.modal-overlay.hidden { display: none; }
|
||||
.modal-card {
|
||||
width: 340px; background: #fff; border-radius: 24px; padding: 24px 20px;
|
||||
box-shadow: 0 20px 60px rgba(0,0,0,0.18); position: relative;
|
||||
}
|
||||
.modal-card__title {
|
||||
font-size: 18px; font-weight: 700; color: var(--text-primary);
|
||||
text-align: center; margin-bottom: 6px;
|
||||
}
|
||||
.modal-card__sub {
|
||||
font-size: 13px; color: var(--text-muted); text-align: center; margin-bottom: 20px;
|
||||
}
|
||||
.modal-field {
|
||||
display: flex; justify-content: space-between; align-items: center;
|
||||
padding: 14px 0; border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
.modal-field:last-of-type { border-bottom: none; }
|
||||
.modal-field__label { font-size: 14px; color: var(--text-muted); }
|
||||
.modal-field__value { font-size: 14px; color: var(--text-primary); font-weight: 600; }
|
||||
.marriage-toggle {
|
||||
display: inline-flex; background: #f5f5f5; border-radius: 20px; overflow: hidden;
|
||||
}
|
||||
.marriage-toggle__btn {
|
||||
padding: 6px 16px; font-size: 13px; font-weight: 600; border: none;
|
||||
background: transparent; color: var(--text-muted); cursor: pointer;
|
||||
border-radius: 20px; transition: all 0.2s ease;
|
||||
}
|
||||
.marriage-toggle__btn.active {
|
||||
background: var(--primary); color: #fff;
|
||||
}
|
||||
.modal-confirm-btn {
|
||||
margin-top: 20px; width: 100%; height: 44px; border-radius: 22px;
|
||||
font-size: 15px; font-weight: 600; border: none; cursor: pointer;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff; box-shadow: 0 8px 20px rgba(19, 194, 194, 0.2);
|
||||
}
|
||||
</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">
|
||||
<a class="nav-back" href="index.html">‹</a>
|
||||
<span class="nav-title">体检预约</span>
|
||||
<!-- [交互] 点击打开个人信息弹窗 -->
|
||||
<span class="nav-right" onclick="openModal()">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
|
||||
个人信息
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="scroll-content">
|
||||
<div class="page-body">
|
||||
<!-- 步骤条 -->
|
||||
<!-- [交互] 步骤条可点击跳转 -->
|
||||
<div class="stepper">
|
||||
<a class="stepper__item stepper__item--active" href="booking-hospital.html"><div class="stepper__dot">1</div><div class="stepper__label">选择医院</div></a>
|
||||
<div class="stepper__line"></div>
|
||||
<div class="stepper__item stepper__item--future"><div class="stepper__dot">2</div><div class="stepper__label">选择项目</div></div>
|
||||
<div class="stepper__line"></div>
|
||||
<div class="stepper__item stepper__item--future"><div class="stepper__dot">3</div><div class="stepper__label">预约日期</div></div>
|
||||
</div>
|
||||
|
||||
<!-- 费用展示 -->
|
||||
<div class="fee-card">
|
||||
<div class="fee-card__label">您本年度的体检费用(元)</div>
|
||||
<div class="fee-card__amount">1500.00</div>
|
||||
</div>
|
||||
|
||||
<!-- 医院列表 -->
|
||||
<div class="section-title">选择医院</div>
|
||||
<div class="hospital-card active" onclick="selectHospital(this)">
|
||||
<div class="hospital-card__info">
|
||||
<div class="hospital-card__icon">🏥</div>
|
||||
<div><div class="hospital-card__name">宁夏宝石花医院</div><div class="hospital-card__addr">宁夏银川市</div></div>
|
||||
</div>
|
||||
<div class="radio-dot"></div>
|
||||
</div>
|
||||
<div class="hospital-card" onclick="selectHospital(this)">
|
||||
<div class="hospital-card__info">
|
||||
<div class="hospital-card__icon">🏥</div>
|
||||
<div><div class="hospital-card__name">长庆星龙园医院</div><div class="hospital-card__addr">陕西西安市</div></div>
|
||||
</div>
|
||||
<div class="radio-dot"></div>
|
||||
</div>
|
||||
<div class="hospital-card" onclick="selectHospital(this)">
|
||||
<div class="hospital-card__info">
|
||||
<div class="hospital-card__icon">🏥</div>
|
||||
<div><div class="hospital-card__name">西安长庆医院</div><div class="hospital-card__addr">陕西西安市</div></div>
|
||||
</div>
|
||||
<div class="radio-dot"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bottom-actions">
|
||||
<button class="bottom-actions__btn" onclick="window.location.href='booking-project.html'">下一步</button>
|
||||
</div>
|
||||
|
||||
<!-- [交互] 个人信息确认弹窗,仅从 booking-type 进入时自动弹出 -->
|
||||
<div class="modal-overlay hidden" id="personModal">
|
||||
<div class="modal-card">
|
||||
<div class="modal-card__title">确认个人信息</div>
|
||||
<div class="modal-card__sub">请核对以下信息,确认无误后继续预约</div>
|
||||
<div class="modal-field">
|
||||
<span class="modal-field__label">姓名</span>
|
||||
<span class="modal-field__value">刘韵琴</span>
|
||||
</div>
|
||||
<div class="modal-field">
|
||||
<span class="modal-field__label">单位</span>
|
||||
<span class="modal-field__value">长庆油田第一采油厂</span>
|
||||
</div>
|
||||
<div class="modal-field">
|
||||
<span class="modal-field__label">身份证号</span>
|
||||
<span class="modal-field__value">6101021994********</span>
|
||||
</div>
|
||||
<div class="modal-field">
|
||||
<span class="modal-field__label">性别</span>
|
||||
<span class="modal-field__value">女</span>
|
||||
</div>
|
||||
<div class="modal-field">
|
||||
<span class="modal-field__label">婚姻状况</span>
|
||||
<div class="marriage-toggle">
|
||||
<button class="marriage-toggle__btn active" onclick="toggleMarriage(this)">已婚</button>
|
||||
<button class="marriage-toggle__btn" onclick="toggleMarriage(this)">未婚</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="modal-confirm-btn" onclick="closeModal()">确认</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// [交互] 仅从 booking-type 跳转进入时自动弹出个人信息确认弹窗
|
||||
if (new URLSearchParams(window.location.search).get('from') === 'booking-type') {
|
||||
document.getElementById('personModal').classList.remove('hidden');
|
||||
}
|
||||
function selectHospital(el) {
|
||||
document.querySelectorAll('.hospital-card').forEach(c => c.classList.remove('active'));
|
||||
el.classList.add('active');
|
||||
}
|
||||
function openModal() {
|
||||
document.getElementById('personModal').classList.remove('hidden');
|
||||
}
|
||||
function closeModal() {
|
||||
document.getElementById('personModal').classList.add('hidden');
|
||||
}
|
||||
function toggleMarriage(btn) {
|
||||
document.querySelectorAll('.marriage-toggle__btn').forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,290 @@
|
||||
<!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 30px 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; }
|
||||
.scroll-content {
|
||||
flex: 1; overflow-y: auto;
|
||||
background: linear-gradient(180deg, #effbfb 0%, #f7f9fb 180px, #f7f9fb 100%);
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.page-body { padding: 16px; }
|
||||
/* 步骤条 */
|
||||
.stepper { display: flex; align-items: center; justify-content: center; margin-bottom: 18px; padding: 16px 0; }
|
||||
.stepper__item { display: flex; flex-direction: column; align-items: center; gap: 6px; cursor: pointer; text-decoration: none; }
|
||||
.stepper__item--future { cursor: default; pointer-events: none; opacity: 0.45; }
|
||||
.stepper__dot {
|
||||
width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
|
||||
font-size: 12px; font-weight: 700; background: #e8e8e8; color: #bfbfbf; transition: all 0.25s;
|
||||
}
|
||||
.stepper__item--done .stepper__dot { background: var(--primary); color: #fff; }
|
||||
.stepper__item--active { cursor: default; pointer-events: none; }
|
||||
.stepper__item--active .stepper__dot {
|
||||
width: 34px; height: 34px; font-size: 14px;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%); color: #fff;
|
||||
box-shadow: 0 0 0 6px rgba(19,194,194,0.2);
|
||||
}
|
||||
.stepper__label { font-size: 12px; color: var(--text-muted); white-space: nowrap; transition: all 0.2s; }
|
||||
.stepper__item--done .stepper__label { color: var(--primary-dark); }
|
||||
.stepper__item--active .stepper__label {
|
||||
color: var(--primary-dark); font-weight: 700; font-size: 13px;
|
||||
background: var(--primary-light); padding: 2px 10px; border-radius: 10px;
|
||||
}
|
||||
.stepper__item--done:hover .stepper__dot { transform: scale(1.12); box-shadow: 0 0 0 4px rgba(19,194,194,0.15); }
|
||||
.stepper__item--done:hover .stepper__label { text-decoration: underline; text-underline-offset: 3px; }
|
||||
.stepper__line { width: 44px; height: 3px; background: #e8e8e8; margin: 0 8px; margin-bottom: 22px; border-radius: 2px; }
|
||||
.stepper__line--done { background: var(--primary); }
|
||||
.fee-banner {
|
||||
background: linear-gradient(135deg, #f0fffe 0%, #f7fffd 100%);
|
||||
border: 1px solid #d7f5f3; border-radius: 18px; padding: 14px 16px;
|
||||
display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px;
|
||||
}
|
||||
.fee-banner__label { font-size: 13px; color: var(--primary-dark); font-weight: 600; }
|
||||
.fee-banner__value { font-size: 24px; font-weight: 800; color: var(--primary-dark); }
|
||||
.section-title { font-size: 16px; font-weight: 700; margin-bottom: 14px; }
|
||||
/* 基本信息卡片 */
|
||||
.info-card {
|
||||
background: #fff; border-radius: 20px; padding: 18px 16px; margin-bottom: 14px;
|
||||
box-shadow: var(--shadow); border: 1px solid rgba(19,194,194,0.06);
|
||||
}
|
||||
.info-card__row {
|
||||
display: flex; justify-content: space-between; align-items: center;
|
||||
padding: 12px 0; border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
.info-card__row:first-child { padding-top: 0; }
|
||||
.info-card__row:last-child { border-bottom: none; padding-bottom: 0; }
|
||||
.info-card__label { font-size: 13px; color: var(--text-muted); }
|
||||
.info-card__value { font-size: 14px; font-weight: 600; color: var(--text-primary); text-align: right; }
|
||||
.info-card__value--highlight { color: var(--primary-dark); font-size: 18px; font-weight: 800; }
|
||||
.info-card__sub {
|
||||
display: flex; gap: 16px; justify-content: flex-end; margin-top: 4px;
|
||||
}
|
||||
.info-card__sub-item { font-size: 12px; color: var(--text-muted); }
|
||||
.info-card__sub-value { font-weight: 600; color: var(--text-secondary); }
|
||||
/* 项目列表区 */
|
||||
.project-section {
|
||||
background: #fff; border-radius: 20px; padding: 18px 16px;
|
||||
box-shadow: var(--shadow); border: 1px solid rgba(19,194,194,0.06);
|
||||
}
|
||||
.project-section__header {
|
||||
display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px;
|
||||
}
|
||||
.project-section__count { font-size: 13px; color: var(--text-muted); }
|
||||
.project-section__count em { font-style: normal; color: var(--primary-dark); font-weight: 700; }
|
||||
.project-tabs {
|
||||
display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px;
|
||||
padding: 5px; background: #f5f7f7; border-radius: 14px; margin-bottom: 14px;
|
||||
}
|
||||
.project-tab {
|
||||
height: 34px; border: none; border-radius: 10px; background: transparent;
|
||||
color: var(--text-secondary); font-size: 13px; font-weight: 600; cursor: pointer;
|
||||
}
|
||||
.project-tab--active {
|
||||
background: #fff; color: var(--primary-dark);
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
|
||||
}
|
||||
.project-list-panel {
|
||||
max-height: 280px; overflow-y: auto; padding-right: 2px;
|
||||
}
|
||||
.project-list-panel::-webkit-scrollbar { display: none; }
|
||||
.project-list { display: flex; flex-direction: column; gap: 10px; }
|
||||
.project-item {
|
||||
display: flex; align-items: center; gap: 12px; padding: 12px 14px;
|
||||
background: #f9fbfb; border-radius: 14px; border: 1px solid #eef5f5;
|
||||
}
|
||||
.project-item__dot {
|
||||
width: 8px; height: 8px; border-radius: 50%; background: var(--primary); flex-shrink: 0;
|
||||
}
|
||||
.project-item__info { flex: 1; }
|
||||
.project-item__name { font-size: 14px; font-weight: 600; margin-bottom: 2px; }
|
||||
.project-item__desc { font-size: 12px; color: var(--text-muted); }
|
||||
.project-item__price { font-size: 13px; font-weight: 700; color: var(--primary-dark); flex-shrink: 0; }
|
||||
.project-item__badge {
|
||||
display: inline-flex; align-items: center; height: 20px; padding: 0 8px;
|
||||
border-radius: 10px; font-size: 10px; font-weight: 600; flex-shrink: 0;
|
||||
}
|
||||
.project-item__badge--normal { background: #f5f5f5; color: var(--text-muted); }
|
||||
.project-item__badge--key { background: #fff1f0; color: #ff4d4f; }
|
||||
.bottom-actions {
|
||||
position: absolute; left: 16px; right: 16px; bottom: 18px;
|
||||
display: flex; gap: 12px; padding-bottom: 16px;
|
||||
}
|
||||
.bottom-actions__btn {
|
||||
flex: 1; height: 48px; border-radius: 24px; font-size: 15px; font-weight: 600; border: none; cursor: pointer;
|
||||
}
|
||||
.bottom-actions__btn--ghost {
|
||||
background: #f5f5f5; color: var(--text-secondary); border: 1px solid #e8e8e8;
|
||||
}
|
||||
.bottom-actions__btn--primary {
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff; box-shadow: 0 10px 20px rgba(19,194,194,0.22);
|
||||
}
|
||||
/* Toast 提示 */
|
||||
.toast {
|
||||
position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%) scale(0.9);
|
||||
background: rgba(0,0,0,0.75); color: #fff; padding: 14px 22px; border-radius: 12px;
|
||||
font-size: 13px; line-height: 1.6; text-align: center; z-index: 200;
|
||||
opacity: 0; pointer-events: none; transition: all 0.25s ease; max-width: 280px;
|
||||
}
|
||||
.toast.show { opacity: 1; transform: translate(-50%, -50%) scale(1); }
|
||||
</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">
|
||||
<a class="nav-back" href="index.html">‹</a>
|
||||
<span class="nav-title">体检预约</span>
|
||||
</div>
|
||||
<div class="scroll-content">
|
||||
<div class="page-body">
|
||||
<!-- [交互] 步骤条可点击跳转 -->
|
||||
<div class="stepper">
|
||||
<!-- [交互] 已提交项目,点击步骤一弹提示,不跳转 -->
|
||||
<div class="stepper__item stepper__item--done" onclick="showToast()"><div class="stepper__dot">✓</div><div class="stepper__label">选择医院</div></div>
|
||||
<div class="stepper__line stepper__line--done"></div>
|
||||
<a class="stepper__item stepper__item--active" href="booking-project.html"><div class="stepper__dot">✓</div><div class="stepper__label">选择项目</div></a>
|
||||
<div class="stepper__line"></div>
|
||||
<div class="stepper__item stepper__item--future"><div class="stepper__dot">3</div><div class="stepper__label">预约日期</div></div>
|
||||
</div>
|
||||
<!-- 基本信息卡片 -->
|
||||
<div class="info-card">
|
||||
<div class="info-card__row">
|
||||
<span class="info-card__label">承检医院</span>
|
||||
<span class="info-card__value">宁夏宝石花医院</span>
|
||||
</div>
|
||||
<div class="info-card__row">
|
||||
<span class="info-card__label">体检额度</span>
|
||||
<span class="info-card__value info-card__value--highlight" >¥1500.00</span>
|
||||
</div>
|
||||
<div class="info-card__row">
|
||||
<span class="info-card__label">已选费用合计</span>
|
||||
<span class="info-card__value info-card__value--highlight" id="totalFeeDisplay">¥860.00</span>
|
||||
</div>
|
||||
<div class="info-card__row" style="flex-wrap:wrap">
|
||||
<span class="info-card__label">费用包含</span>
|
||||
<div class="info-card__sub">
|
||||
<span class="info-card__sub-item">必检 <span class="info-card__sub-value" id="requiredFeeDisplay">¥720.00</span></span>
|
||||
<span class="info-card__sub-item">选检 <span class="info-card__sub-value" id="optionalFeeDisplay">¥140.00</span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 体检项目列表 -->
|
||||
<div class="project-section">
|
||||
<div class="project-section__header">
|
||||
<div class="section-title" style="margin-bottom:0">已选体检项目</div>
|
||||
<span class="project-section__count">共 <em id="totalCount">9</em> 项</span>
|
||||
</div>
|
||||
<!-- [交互] 点击切换自选项目/必检项目 -->
|
||||
<div class="project-tabs">
|
||||
<button class="project-tab project-tab--active" type="button" data-tab="optional">自选项目(1)</button>
|
||||
<button class="project-tab" type="button" data-tab="required">必检项目(8)</button>
|
||||
</div>
|
||||
<div class="project-list-panel">
|
||||
<div class="project-list" id="projectList"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-actions">
|
||||
<button class="bottom-actions__btn bottom-actions__btn--ghost" onclick="window.location.href='booking-project.html'">重选项目</button>
|
||||
<button class="bottom-actions__btn bottom-actions__btn--primary" onclick="window.location.href='booking-date.html'">下一步</button>
|
||||
</div>
|
||||
<div class="toast" id="stepToast">当前已提交项目,如需重新选择医院,请先点击下方重选项目按钮</div>
|
||||
</div>
|
||||
<script>
|
||||
const projects = [
|
||||
{ name: '一般检查', desc: '身高、体重、血压、视力', price: 120, type: 'required', level: 'normal' },
|
||||
{ name: '血常规', desc: '血红蛋白、白细胞、血小板等', price: 80, type: 'required', level: 'normal' },
|
||||
{ name: '尿常规', desc: '尿蛋白、尿糖、尿潜血等', price: 45, type: 'required', level: 'normal' },
|
||||
{ name: '肝功能', desc: 'ALT、AST、总胆红素等', price: 160, type: 'required', level: 'key' },
|
||||
{ name: '肾功能', desc: '肌酐、尿素氮、尿酸等', price: 110, type: 'required', level: 'key' },
|
||||
{ name: '血脂四项', desc: '总胆固醇、甘油三酯、HDL、LDL', price: 90, type: 'required', level: 'normal' },
|
||||
{ name: '空腹血糖', desc: '空腹静脉血糖检测', price: 40, type: 'required', level: 'normal' },
|
||||
{ name: '心电图', desc: '十二导联心电图检查', price: 75, type: 'required', level: 'key' },
|
||||
{ name: '胸部X光', desc: '胸部正位X线摄影', price: 140, type: 'optional', level: 'normal' }
|
||||
];
|
||||
|
||||
let activeTab = 'optional';
|
||||
const listEl = document.getElementById('projectList');
|
||||
const tabButtons = document.querySelectorAll('.project-tab');
|
||||
let toastTimer = null;
|
||||
|
||||
function showToast() {
|
||||
const toast = document.getElementById('stepToast');
|
||||
toast.classList.add('show');
|
||||
clearTimeout(toastTimer);
|
||||
toastTimer = setTimeout(() => {
|
||||
toast.classList.remove('show');
|
||||
}, 2200);
|
||||
}
|
||||
|
||||
function renderList() {
|
||||
const items = projects.filter(p => p.type === activeTab);
|
||||
listEl.innerHTML = items.map(p => `
|
||||
<div class="project-item">
|
||||
<div class="project-item__dot"></div>
|
||||
<div class="project-item__info">
|
||||
<div class="project-item__name">${p.name}</div>
|
||||
<div class="project-item__desc">${p.desc}</div>
|
||||
</div>
|
||||
<span class="project-item__badge project-item__badge--${p.level === 'key' ? 'key' : 'normal'}">${p.level === 'key' ? '重点' : '一般'}</span>
|
||||
<span class="project-item__price">¥${p.price.toFixed(2)}</span>
|
||||
</div>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
tabButtons.forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
activeTab = btn.dataset.tab;
|
||||
tabButtons.forEach(b => b.classList.remove('project-tab--active'));
|
||||
btn.classList.add('project-tab--active');
|
||||
renderList();
|
||||
});
|
||||
});
|
||||
|
||||
renderList();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,453 @@
|
||||
<!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;
|
||||
--success-light: #f6ffed;
|
||||
--success-text: #52c41a;
|
||||
--danger: #ff4d4f;
|
||||
--danger-light: #fff1f0;
|
||||
--text-primary: #1a1a1a;
|
||||
--text-secondary: #666666;
|
||||
--text-muted: #8c8c8c;
|
||||
--border: #e8f3f3;
|
||||
--bg-page: #f0f2f5;
|
||||
--bg-content: #f7f9fb;
|
||||
--shadow: 0 10px 30px 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 180px, #f7f9fb 100%);
|
||||
padding-bottom: 112px;
|
||||
}
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.page-body { padding: 16px; }
|
||||
/* 步骤条 */
|
||||
.stepper { display: flex; align-items: center; justify-content: center; margin-bottom: 18px; padding: 16px 0; }
|
||||
.stepper__item { display: flex; flex-direction: column; align-items: center; gap: 6px; cursor: pointer; text-decoration: none; }
|
||||
.stepper__item--future { cursor: default; pointer-events: none; opacity: 0.45; }
|
||||
.stepper__dot {
|
||||
width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
|
||||
font-size: 12px; font-weight: 700; background: #e8e8e8; color: #bfbfbf; transition: all 0.25s;
|
||||
}
|
||||
.stepper__item--done .stepper__dot { background: var(--primary); color: #fff; }
|
||||
.stepper__item--active { cursor: default; pointer-events: none; }
|
||||
.stepper__item--active .stepper__dot {
|
||||
width: 34px; height: 34px; font-size: 14px;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%); color: #fff;
|
||||
box-shadow: 0 0 0 6px rgba(19,194,194,0.2);
|
||||
}
|
||||
.stepper__label { font-size: 12px; color: var(--text-muted); white-space: nowrap; transition: all 0.2s; }
|
||||
.stepper__item--done .stepper__label { color: var(--primary-dark); }
|
||||
.stepper__item--active .stepper__label {
|
||||
color: var(--primary-dark); font-weight: 700; font-size: 13px;
|
||||
background: var(--primary-light); padding: 2px 10px; border-radius: 10px;
|
||||
}
|
||||
.stepper__item--done:hover .stepper__dot { transform: scale(1.12); box-shadow: 0 0 0 4px rgba(19,194,194,0.15); }
|
||||
.stepper__item--done:hover .stepper__label { text-decoration: underline; text-underline-offset: 3px; }
|
||||
.stepper__line { width: 44px; height: 3px; background: #e8e8e8; margin: 0 8px; margin-bottom: 22px; border-radius: 2px; }
|
||||
.stepper__line--done { background: var(--primary); }
|
||||
/* 费用卡片 */
|
||||
.fee-banner {
|
||||
background: linear-gradient(135deg, #f0fffe 0%, #f7fffd 100%);
|
||||
border: 1px solid #d7f5f3; border-radius: 18px; padding: 14px 16px;
|
||||
display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px;
|
||||
}
|
||||
.fee-banner__label { font-size: 13px; color: var(--primary-dark); font-weight: 600; }
|
||||
.fee-banner__value { font-size: 24px; font-weight: 800; color: var(--primary-dark); }
|
||||
/* 项目列表 */
|
||||
.section-title { font-size: 16px; font-weight: 700; margin-bottom: 14px; }
|
||||
.project-tabs {
|
||||
display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px;
|
||||
padding: 6px; background: rgba(255,255,255,0.92); border-radius: 18px;
|
||||
box-shadow: 0 8px 20px rgba(19, 194, 194, 0.08); margin-bottom: 14px;
|
||||
}
|
||||
.project-tab {
|
||||
height: 36px; border: none; border-radius: 14px; background: transparent;
|
||||
color: var(--text-secondary); font-size: 13px; font-weight: 600; cursor: pointer;
|
||||
}
|
||||
.project-tab--active {
|
||||
background: var(--primary-light); color: var(--primary-dark);
|
||||
box-shadow: inset 0 0 0 1px rgba(19, 194, 194, 0.16);
|
||||
}
|
||||
.project-list-panel {
|
||||
max-height: 432px; overflow-y: auto; padding-right: 2px; margin-bottom: 12px;
|
||||
}
|
||||
.project-list-panel::-webkit-scrollbar { display: none; }
|
||||
.project-grid { display: flex; flex-direction: column; gap: 10px; }
|
||||
.project-card {
|
||||
background: #fff; border-radius: 14px; padding: 14px 16px; border: 2px solid #eef5f5;
|
||||
cursor: pointer; transition: all 0.2s; display: flex; align-items: center; gap: 12px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.03);
|
||||
}
|
||||
.project-card:hover { border-color: var(--primary); }
|
||||
.project-card.selected { border-color: var(--primary); background: var(--primary-light); }
|
||||
.project-card.project-card--readonly {
|
||||
cursor: default; background: #fff; border-color: #eef5f5;
|
||||
}
|
||||
.project-card.project-card--readonly:hover { border-color: #eef5f5; }
|
||||
.project-card__check {
|
||||
width: 22px; height: 22px; border-radius: 6px; border: 2px solid #d9d9d9;
|
||||
display: flex; align-items: center; justify-content: center; flex-shrink: 0; transition: all 0.2s;
|
||||
}
|
||||
.project-card__check--hidden { visibility: hidden; }
|
||||
.project-card__check::after {
|
||||
content: ''; width: 8px; height: 8px; border-radius: 2px; background: #fff; opacity: 0;
|
||||
}
|
||||
.project-card.selected .project-card__check { background: var(--primary); border-color: var(--primary); }
|
||||
.project-card.selected .project-card__check::after { opacity: 1; }
|
||||
.project-card__info { flex: 1; min-width: 0; }
|
||||
.project-card__name { font-size: 14px; font-weight: 600; margin-bottom: 2px; }
|
||||
.project-card__desc { font-size: 12px; color: var(--text-muted); }
|
||||
.project-card__side {
|
||||
flex-shrink: 0; display: flex; align-items: center; gap: 10px;
|
||||
margin-left: auto; padding-left: 8px;
|
||||
}
|
||||
.project-card__tags {
|
||||
display: flex; flex-direction: column; align-items: flex-end; gap: 6px;
|
||||
}
|
||||
.project-card__price { font-size: 13px; color: var(--primary-dark); font-weight: 700; }
|
||||
.project-card__badge {
|
||||
display: inline-flex; align-items: center; justify-content: center; height: 22px;
|
||||
padding: 0 10px; border-radius: 11px; background: #f5f5f5;
|
||||
color: var(--text-muted); font-size: 11px; font-weight: 600;
|
||||
}
|
||||
.project-card__badge--key {
|
||||
background: #fff1f0; color: #ff4d4f;
|
||||
}
|
||||
.project-card__arrow {
|
||||
flex-shrink: 0; color: #d0d0d0; font-size: 16px; cursor: pointer;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
.project-card__arrow:hover { color: var(--primary); }
|
||||
/* 底部按钮 */
|
||||
.bottom-actions {
|
||||
position: absolute; left: 16px; right: 16px; bottom: 18px;
|
||||
display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding-bottom: 16px;
|
||||
}
|
||||
.summary-card {
|
||||
background: #fff; border-radius: 18px; padding: 12px 14px;
|
||||
box-shadow: 0 10px 24px rgba(19, 194, 194, 0.10); border: 1px solid rgba(19, 194, 194, 0.08);
|
||||
display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 12px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.summary-card__title {
|
||||
display: none;
|
||||
}
|
||||
.summary-row {
|
||||
display: flex; justify-content: space-between; align-items: center;
|
||||
font-size: 11px; color: var(--text-secondary); margin-bottom: 0; gap: 8px;
|
||||
}
|
||||
.summary-row:last-child { margin-bottom: 0; }
|
||||
.summary-row__value { font-weight: 700; color: var(--text-primary); white-space: nowrap; }
|
||||
.summary-row__value--highlight { color: var(--primary-dark); font-size: 13px; }
|
||||
.summary-row__value--danger { color: var(--danger); }
|
||||
.bottom-actions__btn {
|
||||
width: 100%; height: 56px; border-radius: 18px; font-size: 15px; font-weight: 600; border: none; cursor: pointer;
|
||||
}
|
||||
.bottom-actions__btn--ghost {
|
||||
background: #fff; color: var(--text-secondary); border: 1px solid #d9e8e8;
|
||||
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
.bottom-actions__btn--primary {
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff; box-shadow: 0 10px 20px rgba(19, 194, 194, 0.22);
|
||||
}
|
||||
/* 提交确认弹窗 */
|
||||
.modal-overlay {
|
||||
position: absolute; inset: 0; background: rgba(0,0,0,0.42); z-index: 120;
|
||||
display: flex; align-items: center; justify-content: center; padding: 24px;
|
||||
}
|
||||
.modal-overlay.hidden { display: none; }
|
||||
.confirm-modal {
|
||||
width: 100%; background: #fff; border-radius: 24px; padding: 22px 20px 18px;
|
||||
box-shadow: 0 20px 50px rgba(0,0,0,0.16);
|
||||
}
|
||||
.confirm-modal__title {
|
||||
font-size: 18px; font-weight: 700; color: var(--text-primary); text-align: center; margin-bottom: 8px;
|
||||
}
|
||||
.confirm-modal__desc {
|
||||
font-size: 13px; color: var(--text-muted); text-align: center; line-height: 1.6; margin-bottom: 18px;
|
||||
}
|
||||
.confirm-modal__info {
|
||||
background: #f7f9fb; border-radius: 16px; padding: 14px 16px; margin-bottom: 18px;
|
||||
}
|
||||
.confirm-modal__row {
|
||||
display: flex; justify-content: space-between; align-items: center; font-size: 14px;
|
||||
color: var(--text-secondary); margin-bottom: 12px;
|
||||
}
|
||||
.confirm-modal__row:last-child { margin-bottom: 0; }
|
||||
.confirm-modal__value { font-size: 16px; font-weight: 700; color: var(--text-primary); }
|
||||
.confirm-modal__value--highlight { color: var(--primary-dark); }
|
||||
.confirm-modal__actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
|
||||
.confirm-modal__btn {
|
||||
height: 44px; border-radius: 22px; font-size: 15px; font-weight: 600; border: none; cursor: pointer;
|
||||
}
|
||||
.confirm-modal__btn--ghost { background: #f5f5f5; color: var(--text-secondary); }
|
||||
.confirm-modal__btn--primary {
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%); color: #fff;
|
||||
}
|
||||
</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">
|
||||
<a class="nav-back" href="index.html">‹</a>
|
||||
<span class="nav-title">体检预约</span>
|
||||
</div>
|
||||
<div class="scroll-content">
|
||||
<div class="page-body">
|
||||
<!-- [交互] 步骤条可点击跳转 -->
|
||||
<div class="stepper">
|
||||
<a class="stepper__item stepper__item--done" href="booking-hospital.html?from=stepper"><div class="stepper__dot">✓</div><div class="stepper__label">选择医院</div></a>
|
||||
<div class="stepper__line stepper__line--done"></div>
|
||||
<a class="stepper__item stepper__item--active" href="booking-project.html"><div class="stepper__dot">2</div><div class="stepper__label">选择项目</div></a>
|
||||
<div class="stepper__line"></div>
|
||||
<div class="stepper__item stepper__item--future"><div class="stepper__dot">3</div><div class="stepper__label">预约日期</div></div>
|
||||
</div>
|
||||
<!-- 费用 -->
|
||||
<div class="fee-banner">
|
||||
<span class="fee-banner__label">您本年度的体检费用(元)</span>
|
||||
<span class="fee-banner__value">1500.00</span>
|
||||
</div>
|
||||
<div class="summary-card">
|
||||
<div class="summary-card__title">费用汇总</div>
|
||||
<div class="summary-row">
|
||||
<span>已选</span>
|
||||
<span class="summary-row__value summary-row__value--highlight" id="totalFee">¥0.00</span>
|
||||
</div>
|
||||
<div class="summary-row">
|
||||
<span>必检项目</span>
|
||||
<span class="summary-row__value" id="requiredFee">¥0.00</span>
|
||||
</div>
|
||||
<div class="summary-row">
|
||||
<span>选检项目</span>
|
||||
<span class="summary-row__value" id="optionalFee">¥0.00</span>
|
||||
</div>
|
||||
<div class="summary-row">
|
||||
<span>可用额度</span>
|
||||
<span class="summary-row__value" id="availableFee">¥0.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 项目列表 -->
|
||||
<div class="section-title">选择体检项目</div>
|
||||
<!-- [交互] 点击切换必检项目/选检项目 -->
|
||||
<div class="project-tabs" id="projectTabs">
|
||||
<button class="project-tab project-tab--active" type="button" data-tab="optional">选检项目</button>
|
||||
<button class="project-tab" type="button" data-tab="required">必检项目</button>
|
||||
</div>
|
||||
<div class="project-list-panel">
|
||||
<div class="project-grid" id="projectGrid"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-actions">
|
||||
<button class="bottom-actions__btn bottom-actions__btn--ghost" type="button" onclick="goPrevStep()">上一步</button>
|
||||
<button class="bottom-actions__btn bottom-actions__btn--primary" type="button" onclick="openSubmitConfirm()">提交项目</button>
|
||||
</div>
|
||||
|
||||
<!-- [交互] 提交二次确认弹窗 -->
|
||||
<div class="modal-overlay hidden" id="submitModal">
|
||||
<div class="confirm-modal">
|
||||
<div class="confirm-modal__title">确认提交</div>
|
||||
<div class="confirm-modal__desc">请确认以下体检项目信息无误</div>
|
||||
<div class="confirm-modal__info">
|
||||
<div class="confirm-modal__row">
|
||||
<span>体检项目数</span>
|
||||
<span class="confirm-modal__value" id="confirmCount">0 项</span>
|
||||
</div>
|
||||
<div class="confirm-modal__row">
|
||||
<span>总体检费用</span>
|
||||
<span class="confirm-modal__value confirm-modal__value--highlight" id="confirmFee">¥0.00</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="confirm-modal__actions">
|
||||
<button class="confirm-modal__btn confirm-modal__btn--ghost" onclick="closeSubmitConfirm()">取消</button>
|
||||
<button class="confirm-modal__btn confirm-modal__btn--primary" onclick="confirmSubmit()">确认提交</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
const annualLimit = 1500;
|
||||
const projects = [
|
||||
{ id: 'general', name: '一般检查', desc: '身高、体重、血压、视力', price: 120, type: 'required', level: 'normal' },
|
||||
{ id: 'blood', name: '血常规', desc: '血红蛋白、白细胞、血小板等', price: 80, type: 'required', level: 'normal' },
|
||||
{ id: 'urine', name: '尿常规', desc: '尿蛋白、尿糖、尿潜血等', price: 45, type: 'required', level: 'normal' },
|
||||
{ id: 'liver', name: '肝功能', desc: 'ALT、AST、总胆红素等', price: 160, type: 'required', level: 'key' },
|
||||
{ id: 'kidney', name: '肾功能', desc: '肌酐、尿素氮、尿酸等', price: 110, type: 'required', level: 'key' },
|
||||
{ id: 'lipid', name: '血脂四项', desc: '总胆固醇、甘油三酯、HDL、LDL', price: 90, type: 'required', level: 'normal' },
|
||||
{ id: 'glucose', name: '空腹血糖', desc: '空腹静脉血糖检测', price: 40, type: 'required', level: 'normal' },
|
||||
{ id: 'ecg', name: '心电图', desc: '十二导联心电图检查', price: 75, type: 'required', level: 'key' },
|
||||
{ id: 'xray', name: '胸部X光', desc: '胸部正位X线摄影', price: 140, type: 'optional', level: 'normal' },
|
||||
{ id: 'ultrasound', name: '腹部B超', desc: '肝胆脾胰肾超声检查', price: 180, type: 'optional', level: 'key' },
|
||||
{ id: 'thyroid', name: '甲状腺彩超', desc: '甲状腺结构与结节筛查', price: 160, type: 'optional', level: 'key' },
|
||||
{ id: 'tumor', name: '肿瘤标志物', desc: '基础肿瘤风险筛查', price: 220, type: 'optional', level: 'key' }
|
||||
];
|
||||
|
||||
let activeTab = 'optional';
|
||||
const selectedOptionalIds = new Set(['xray']);
|
||||
|
||||
const grid = document.getElementById('projectGrid');
|
||||
const tabButtons = document.querySelectorAll('.project-tab');
|
||||
const totalFeeEl = document.getElementById('totalFee');
|
||||
const requiredFeeEl = document.getElementById('requiredFee');
|
||||
const optionalFeeEl = document.getElementById('optionalFee');
|
||||
const availableFeeEl = document.getElementById('availableFee');
|
||||
|
||||
function formatPrice(value) {
|
||||
return `¥${value.toFixed(2)}`;
|
||||
}
|
||||
|
||||
function getRequiredProjects() {
|
||||
return projects.filter(project => project.type === 'required');
|
||||
}
|
||||
|
||||
function getOptionalProjects() {
|
||||
return projects.filter(project => project.type === 'optional');
|
||||
}
|
||||
|
||||
function getRequiredFee() {
|
||||
return getRequiredProjects().reduce((sum, project) => sum + project.price, 0);
|
||||
}
|
||||
|
||||
function getOptionalFee() {
|
||||
return getOptionalProjects()
|
||||
.filter(project => selectedOptionalIds.has(project.id))
|
||||
.reduce((sum, project) => sum + project.price, 0);
|
||||
}
|
||||
|
||||
function updateSummary() {
|
||||
const requiredFee = getRequiredFee();
|
||||
const optionalFee = getOptionalFee();
|
||||
const totalFee = requiredFee + optionalFee;
|
||||
const availableFee = annualLimit - totalFee;
|
||||
|
||||
requiredFeeEl.textContent = formatPrice(requiredFee);
|
||||
optionalFeeEl.textContent = formatPrice(optionalFee);
|
||||
totalFeeEl.textContent = formatPrice(totalFee);
|
||||
availableFeeEl.textContent = formatPrice(Math.max(availableFee, 0));
|
||||
availableFeeEl.classList.toggle('summary-row__value--danger', availableFee < 0);
|
||||
}
|
||||
|
||||
function renderProjects() {
|
||||
const currentProjects = activeTab === 'required' ? getRequiredProjects() : getOptionalProjects();
|
||||
grid.innerHTML = '';
|
||||
|
||||
currentProjects.forEach(project => {
|
||||
const card = document.createElement('div');
|
||||
const isReadonly = project.type === 'required';
|
||||
const isSelected = selectedOptionalIds.has(project.id);
|
||||
const projectLevelText = project.level === 'key' ? '重点项目' : '一般项目';
|
||||
card.className = `project-card${isReadonly ? ' project-card--readonly' : ''}${isSelected ? ' selected' : ''}`;
|
||||
card.innerHTML = `
|
||||
<div class="project-card__check${isReadonly ? ' project-card__check--hidden' : ''}"></div>
|
||||
<div class="project-card__info">
|
||||
<div class="project-card__name">${project.name}</div>
|
||||
<div class="project-card__desc">${project.desc}</div>
|
||||
</div>
|
||||
<div class="project-card__side">
|
||||
<div class="project-card__tags">
|
||||
<span class="project-card__price">${formatPrice(project.price)}</span>
|
||||
<span class="project-card__badge${project.level === 'key' ? ' project-card__badge--key' : ''}">${projectLevelText}</span>
|
||||
</div>
|
||||
<span class="project-card__arrow" data-detail="${project.id}">›</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
// [交互] 箭头点击跳转项目详情
|
||||
card.querySelector('.project-card__arrow').addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
window.location.href = `project-detail.html?id=${project.id}`;
|
||||
});
|
||||
|
||||
if (!isReadonly) {
|
||||
card.addEventListener('click', () => {
|
||||
if (selectedOptionalIds.has(project.id)) {
|
||||
selectedOptionalIds.delete(project.id);
|
||||
} else {
|
||||
selectedOptionalIds.add(project.id);
|
||||
}
|
||||
renderProjects();
|
||||
updateSummary();
|
||||
});
|
||||
}
|
||||
|
||||
grid.appendChild(card);
|
||||
});
|
||||
}
|
||||
|
||||
tabButtons.forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
activeTab = button.dataset.tab;
|
||||
tabButtons.forEach(item => item.classList.remove('project-tab--active'));
|
||||
button.classList.add('project-tab--active');
|
||||
renderProjects();
|
||||
});
|
||||
});
|
||||
|
||||
renderProjects();
|
||||
updateSummary();
|
||||
|
||||
function openSubmitConfirm() {
|
||||
const requiredCount = getRequiredProjects().length;
|
||||
const optionalCount = selectedOptionalIds.size;
|
||||
const totalCount = requiredCount + optionalCount;
|
||||
const totalFee = getRequiredFee() + getOptionalFee();
|
||||
document.getElementById('confirmCount').textContent = totalCount + ' 项';
|
||||
document.getElementById('confirmFee').textContent = formatPrice(totalFee);
|
||||
document.getElementById('submitModal').classList.remove('hidden');
|
||||
}
|
||||
function closeSubmitConfirm() {
|
||||
document.getElementById('submitModal').classList.add('hidden');
|
||||
}
|
||||
function goPrevStep() {
|
||||
window.location.href = 'booking-hospital.html';
|
||||
}
|
||||
function confirmSubmit() {
|
||||
window.location.href = 'booking-project-selected.html';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,262 @@
|
||||
<!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;
|
||||
--border: #e8f3f3;
|
||||
--bg-page: #f0f2f5;
|
||||
--bg-content: #f7f9fb;
|
||||
--shadow: 0 10px 30px 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 180px, #f7f9fb 100%);
|
||||
padding-bottom: 120px;
|
||||
}
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.page-body { padding: 16px; }
|
||||
.section-title {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.section-desc {
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.type-card {
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
padding: 20px 18px;
|
||||
margin-bottom: 14px;
|
||||
border: 2px solid transparent;
|
||||
box-shadow: var(--shadow);
|
||||
cursor: pointer;
|
||||
transition: all 0.25s ease;
|
||||
}
|
||||
.type-card.active {
|
||||
border-color: var(--primary);
|
||||
background: var(--primary-light);
|
||||
}
|
||||
.type-card__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 14px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.type-card__icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 24px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.type-card__icon--routine {
|
||||
background: linear-gradient(135deg, #e6fffb 0%, #b5f5ec 100%);
|
||||
}
|
||||
.type-card__icon--gastro {
|
||||
background: linear-gradient(135deg, #fff7e6 0%, #ffe7ba 100%);
|
||||
}
|
||||
.type-card__name {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.type-card__desc {
|
||||
font-size: 13px;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.7;
|
||||
}
|
||||
.type-card__radio {
|
||||
position: absolute;
|
||||
right: 18px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.type-card__header { position: relative; }
|
||||
.radio-dot {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #d9d9d9;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.25s ease;
|
||||
flex-shrink: 0;
|
||||
margin-left: auto;
|
||||
}
|
||||
.type-card.active .radio-dot {
|
||||
border-color: var(--primary);
|
||||
background: var(--primary);
|
||||
}
|
||||
.radio-dot::after {
|
||||
content: '';
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #fff;
|
||||
opacity: 0;
|
||||
transition: opacity 0.25s ease;
|
||||
}
|
||||
.type-card.active .radio-dot::after { opacity: 1; }
|
||||
.bottom-actions {
|
||||
position: absolute;
|
||||
left: 16px;
|
||||
right: 16px;
|
||||
bottom: 18px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
.bottom-actions__btn {
|
||||
width: 100%;
|
||||
height: 48px;
|
||||
border-radius: 24px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 10px 20px rgba(19, 194, 194, 0.22);
|
||||
}
|
||||
</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">
|
||||
<!-- [交互] 点击返回上一页 -->
|
||||
<a class="nav-back" href="index.html">‹</a>
|
||||
<span class="nav-title">体检预约</span>
|
||||
</div>
|
||||
|
||||
<div class="scroll-content">
|
||||
<div class="page-body">
|
||||
<div class="section-title">选择体检类型</div>
|
||||
<div class="section-desc">请根据需求选择适合的体检项目</div>
|
||||
|
||||
<!-- [交互] 点击切换选中态,单选 -->
|
||||
<div class="type-card active" onclick="selectType(this, 'routine')">
|
||||
<div class="type-card__header">
|
||||
<div class="type-card__icon type-card__icon--routine">🩺</div>
|
||||
<div class="type-card__name">常规体检</div>
|
||||
<div class="radio-dot"></div>
|
||||
</div>
|
||||
<div class="type-card__desc">基础健康综合筛查,覆盖核心指标</div>
|
||||
</div>
|
||||
|
||||
<div class="type-card" onclick="selectType(this, 'gastro')">
|
||||
<div class="type-card__header">
|
||||
<div class="type-card__icon type-card__icon--gastro">🔬</div>
|
||||
<div class="type-card__name">胃肠镜体检</div>
|
||||
<div class="radio-dot"></div>
|
||||
</div>
|
||||
<div class="type-card__desc">胃肠内镜专项检查,直观诊断消化道病变</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bottom-actions">
|
||||
<!-- [交互] 根据选中的体检类型跳转到对应流程 -->
|
||||
<button class="bottom-actions__btn" onclick="goNext()">确定</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var selectedType = 'routine';
|
||||
function selectType(el, type) {
|
||||
document.querySelectorAll('.type-card').forEach(c => c.classList.remove('active'));
|
||||
el.classList.add('active');
|
||||
selectedType = type;
|
||||
}
|
||||
function goNext() {
|
||||
if (selectedType === 'gastro') {
|
||||
window.location.href = 'gastro-hospital.html?from=booking-type';
|
||||
} else {
|
||||
window.location.href = 'booking-hospital.html?from=booking-type';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,317 @@
|
||||
<!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: #666;
|
||||
--text-muted: #8c8c8c;
|
||||
--bg-page: #f0f2f5;
|
||||
--bg-content: #f7f9fb;
|
||||
--danger: #e84c4c;
|
||||
}
|
||||
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: #f5f5f5;
|
||||
}
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.page-body { padding: 0 0 28px; }
|
||||
|
||||
/* 大分类 */
|
||||
.category {
|
||||
background: #fff;
|
||||
margin-bottom: 10px;
|
||||
padding: 18px 16px 6px;
|
||||
}
|
||||
.category__title {
|
||||
font-size: 17px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
/* 子分类卡片 */
|
||||
.sub-section {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
.sub-section__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.sub-section__name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.sub-section__bar {
|
||||
width: 4px;
|
||||
height: 18px;
|
||||
border-radius: 2px;
|
||||
background: var(--primary);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.sub-section__link {
|
||||
font-size: 13px;
|
||||
color: var(--danger);
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 表格 */
|
||||
.consult-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #e8e8e8;
|
||||
}
|
||||
.consult-table thead th {
|
||||
background: var(--primary);
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
padding: 10px 8px;
|
||||
text-align: center;
|
||||
}
|
||||
.consult-table tbody td {
|
||||
font-size: 13px;
|
||||
color: var(--text-primary);
|
||||
padding: 11px 8px;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
background: #fff;
|
||||
}
|
||||
.consult-table tbody tr:last-child td {
|
||||
border-bottom: none;
|
||||
}
|
||||
.consult-table thead th:first-child { width: 34%; }
|
||||
.consult-table thead th:nth-child(2) { width: 22%; }
|
||||
.consult-table thead th:nth-child(3) { width: 20%; }
|
||||
.consult-table thead th:nth-child(4) { width: 24%; }
|
||||
.is-abnormal { color: var(--danger); font-weight: 600; }
|
||||
.consult-table tbody td:nth-child(2) { color: var(--danger); font-weight: 600; }
|
||||
</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">
|
||||
<a class="nav-back" href="index.html">‹</a>
|
||||
<span class="nav-title">一键咨询</span>
|
||||
</div>
|
||||
|
||||
<div class="scroll-content">
|
||||
<div class="page-body">
|
||||
<!-- 化学检查 -->
|
||||
<div class="category">
|
||||
<div class="category__title">化学检查</div>
|
||||
|
||||
<!-- 血脂 -->
|
||||
<div class="sub-section">
|
||||
<div class="sub-section__header">
|
||||
<div class="sub-section__name"><span class="sub-section__bar"></span>血脂</div>
|
||||
<a class="sub-section__link">专家库一键咨询></a>
|
||||
</div>
|
||||
<table class="consult-table">
|
||||
<thead><tr><th>名称</th><th>结果</th><th>单位</th><th>参考值</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>高密度脂蛋白</td><td class="is-abnormal">0.90</td><td>mmol/L</td><td>1.04--1.66</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 乙肝 -->
|
||||
<div class="sub-section">
|
||||
<div class="sub-section__header">
|
||||
<div class="sub-section__name"><span class="sub-section__bar"></span>乙肝</div>
|
||||
<a class="sub-section__link">专家库一键咨询></a>
|
||||
</div>
|
||||
<table class="consult-table">
|
||||
<thead><tr><th>名称</th><th>结果</th><th>单位</th><th>参考值</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>乙肝病毒表面抗体</td><td class="is-abnormal">弱阳性</td><td>/</td><td>阴性</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 肝功 -->
|
||||
<div class="sub-section">
|
||||
<div class="sub-section__header">
|
||||
<div class="sub-section__name"><span class="sub-section__bar"></span>肝功</div>
|
||||
<a class="sub-section__link">专家库一键咨询></a>
|
||||
</div>
|
||||
<table class="consult-table">
|
||||
<thead><tr><th>名称</th><th>结果</th><th>单位</th><th>参考值</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>谷丙转氨酶</td><td class="is-abnormal">59</td><td>U/L</td><td>9--50</td></tr>
|
||||
<tr><td>总胆红素</td><td class="is-abnormal">33.0</td><td>umol/L</td><td>3.42--23</td></tr>
|
||||
<tr><td>直接胆红素</td><td class="is-abnormal">7.5</td><td>umol/L</td><td>0--6.84</td></tr>
|
||||
<tr><td>间接胆红素</td><td class="is-abnormal">25.5</td><td>umol/L</td><td>3.4--16.1</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 生化检查 -->
|
||||
<div class="sub-section">
|
||||
<div class="sub-section__header">
|
||||
<div class="sub-section__name"><span class="sub-section__bar"></span>生化检查</div>
|
||||
<a class="sub-section__link">专家库一键咨询></a>
|
||||
</div>
|
||||
<table class="consult-table">
|
||||
<thead><tr><th>名称</th><th>结果</th><th>单位</th><th>参考值</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>载脂蛋白-A1</td><td class="is-abnormal">0.88</td><td>g/L</td><td>1--1.6</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 常规检查 -->
|
||||
<div class="category">
|
||||
<div class="category__title">常规检查</div>
|
||||
|
||||
<!-- 血常规 -->
|
||||
<div class="sub-section">
|
||||
<div class="sub-section__header">
|
||||
<div class="sub-section__name"><span class="sub-section__bar"></span>血常规</div>
|
||||
<a class="sub-section__link">专家库一键咨询></a>
|
||||
</div>
|
||||
<table class="consult-table">
|
||||
<thead><tr><th>名称</th><th>结果</th><th>单位</th><th>参考值</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>中性粒细胞比率</td><td class="is-abnormal">78.6</td><td>%</td><td>40--75</td></tr>
|
||||
<tr><td>淋巴细胞比率</td><td class="is-abnormal">15.2</td><td>%</td><td>20--50</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 尿常规 -->
|
||||
<div class="sub-section">
|
||||
<div class="sub-section__header">
|
||||
<div class="sub-section__name"><span class="sub-section__bar"></span>尿常规</div>
|
||||
<a class="sub-section__link">专家库一键咨询></a>
|
||||
</div>
|
||||
<table class="consult-table">
|
||||
<thead><tr><th>名称</th><th>结果</th><th>单位</th><th>参考值</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>尿蛋白</td><td class="is-abnormal">弱阳性</td><td>/</td><td>阴性</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 影像检查 -->
|
||||
<div class="category">
|
||||
<div class="category__title">影像检查</div>
|
||||
|
||||
<div class="sub-section">
|
||||
<div class="sub-section__header">
|
||||
<div class="sub-section__name"><span class="sub-section__bar"></span>彩超</div>
|
||||
<a class="sub-section__link">专家库一键咨询></a>
|
||||
</div>
|
||||
<table class="consult-table">
|
||||
<thead><tr><th>名称</th><th>结果</th><th>单位</th><th>参考值</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>肝胆脾胰双肾</td><td class="is-abnormal">轻度脂肪肝</td><td>/</td><td>未见异常</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="sub-section">
|
||||
<div class="sub-section__header">
|
||||
<div class="sub-section__name"><span class="sub-section__bar"></span>颈椎</div>
|
||||
<a class="sub-section__link">专家库一键咨询></a>
|
||||
</div>
|
||||
<table class="consult-table">
|
||||
<thead><tr><th>名称</th><th>结果</th><th>单位</th><th>参考值</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>颈椎 CT</td><td class="is-abnormal">生理曲度变直</td><td>/</td><td>未见异常</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,312 @@
|
||||
<!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;
|
||||
--border: #e8f3f3;
|
||||
--bg-page: #f0f2f5;
|
||||
--bg-content: #f7f9fb;
|
||||
--shadow: 0 10px 30px 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 180px, #f7f9fb 100%); padding-bottom: 120px; }
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.page-body { padding: 16px; }
|
||||
.stepper { display: flex; align-items: center; justify-content: center; margin-bottom: 18px; padding: 16px 0; }
|
||||
.stepper__item { display: flex; flex-direction: column; align-items: center; gap: 6px; cursor: pointer; text-decoration: none; }
|
||||
.stepper__item--future { cursor: default; pointer-events: none; opacity: 0.45; }
|
||||
.stepper__dot {
|
||||
width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
|
||||
font-size: 12px; font-weight: 700; background: #e8e8e8; color: #bfbfbf; transition: all 0.25s;
|
||||
}
|
||||
.stepper__item--done .stepper__dot { background: var(--primary); color: #fff; }
|
||||
.stepper__item--active { cursor: default; pointer-events: none; }
|
||||
.stepper__item--active .stepper__dot {
|
||||
width: 34px; height: 34px; font-size: 14px;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%); color: #fff;
|
||||
box-shadow: 0 0 0 6px rgba(19,194,194,0.2);
|
||||
}
|
||||
.stepper__label { font-size: 12px; color: var(--text-muted); white-space: nowrap; transition: all 0.2s; }
|
||||
.stepper__item--done .stepper__label { color: var(--primary-dark); }
|
||||
.stepper__item--active .stepper__label {
|
||||
color: var(--primary-dark); font-weight: 700; font-size: 13px;
|
||||
background: var(--primary-light); padding: 2px 10px; border-radius: 10px;
|
||||
}
|
||||
.stepper__item--done:hover .stepper__dot { transform: scale(1.12); box-shadow: 0 0 0 4px rgba(19,194,194,0.15); }
|
||||
.stepper__item--done:hover .stepper__label { text-decoration: underline; text-underline-offset: 3px; }
|
||||
.stepper__line { width: 44px; height: 3px; background: #e8e8e8; margin: 0 8px; margin-bottom: 22px; border-radius: 2px; }
|
||||
.stepper__line--done { background: var(--primary); }
|
||||
.section-title { font-size: 16px; font-weight: 700; margin-bottom: 14px; margin-top: 6px; }
|
||||
.summary-card {
|
||||
background: #fff; border-radius: 20px; padding: 18px 16px; margin-bottom: 14px;
|
||||
box-shadow: var(--shadow); border: 1px solid rgba(19,194,194,0.06);
|
||||
}
|
||||
.summary-list { display: flex; flex-direction: column; gap: 14px; }
|
||||
.summary-item { display: flex; justify-content: space-between; gap: 12px; }
|
||||
.summary-item__label { font-size: 13px; color: var(--text-muted); flex-shrink: 0; }
|
||||
.summary-item__value { font-size: 14px; font-weight: 600; text-align: right; line-height: 1.6; }
|
||||
.date-card {
|
||||
background: #fff; border-radius: 20px; padding: 18px 16px;
|
||||
box-shadow: var(--shadow); border: 1px solid rgba(19,194,194,0.06);
|
||||
}
|
||||
.calendar-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; }
|
||||
.calendar-header__month { font-size: 17px; font-weight: 700; color: var(--text-primary); }
|
||||
.calendar-header__nav { display: flex; gap: 8px; }
|
||||
.calendar-header__btn {
|
||||
width: 32px; height: 32px; border-radius: 10px; border: 1px solid #e8e8e8;
|
||||
background: #fff; display: flex; align-items: center; justify-content: center;
|
||||
cursor: pointer; font-size: 14px; color: var(--text-secondary); transition: all 0.2s;
|
||||
}
|
||||
.calendar-header__btn:hover { border-color: var(--primary); color: var(--primary); }
|
||||
.calendar-header__btn:disabled { opacity: 0.3; pointer-events: none; }
|
||||
.calendar-weekdays { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; margin-bottom: 8px; }
|
||||
.calendar-weekday { text-align: center; font-size: 12px; font-weight: 600; color: var(--text-muted); padding: 6px 0; }
|
||||
.calendar-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; }
|
||||
.calendar-cell {
|
||||
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
||||
height: 52px; border-radius: 12px; cursor: pointer; transition: all 0.2s;
|
||||
border: 2px solid transparent; background: #f9fbfb; position: relative;
|
||||
}
|
||||
.calendar-cell:hover { border-color: var(--primary); }
|
||||
.calendar-cell.selected { background: var(--primary); border-color: var(--primary); }
|
||||
.calendar-cell.selected .calendar-cell__day,
|
||||
.calendar-cell.selected .calendar-cell__slots { color: #fff; }
|
||||
.calendar-cell.disabled { opacity: 0.3; pointer-events: none; background: #f5f5f5; }
|
||||
.calendar-cell.empty { background: transparent; pointer-events: none; }
|
||||
.calendar-cell__day { font-size: 15px; font-weight: 700; color: var(--text-primary); line-height: 1; }
|
||||
.calendar-cell__slots { font-size: 10px; color: var(--primary-dark); font-weight: 600; margin-top: 2px; }
|
||||
.calendar-cell__full { font-size: 10px; color: var(--text-muted); font-weight: 600; margin-top: 2px; }
|
||||
.calendar-cell.today .calendar-cell__day { color: var(--primary-dark); }
|
||||
.calendar-cell.today { border-color: rgba(19,194,194,0.3); }
|
||||
.bottom-actions {
|
||||
position: absolute; left: 16px; right: 16px; bottom: 18px;
|
||||
display: flex; gap: 12px; padding-bottom: 16px;
|
||||
}
|
||||
.bottom-actions__btn { flex: 1; height: 48px; border-radius: 24px; font-size: 15px; font-weight: 600; border: none; cursor: pointer; }
|
||||
.bottom-actions__btn--ghost { background: #fff; color: var(--primary-dark); border: 2px solid #d0eded; }
|
||||
.bottom-actions__btn--primary {
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff; box-shadow: 0 10px 20px rgba(19,194,194,0.22);
|
||||
}
|
||||
.modal-overlay {
|
||||
position: absolute; inset: 0; background: rgba(0,0,0,0.42); z-index: 120;
|
||||
display: flex; align-items: center; justify-content: center; padding: 24px;
|
||||
}
|
||||
.modal-overlay.hidden { display: none; }
|
||||
.confirm-modal { width: 100%; background: #fff; border-radius: 24px; padding: 22px 20px 18px; box-shadow: 0 20px 50px rgba(0,0,0,0.16); }
|
||||
.confirm-modal__title { font-size: 18px; font-weight: 700; text-align: center; margin-bottom: 8px; }
|
||||
.confirm-modal__desc { font-size: 13px; color: var(--text-muted); text-align: center; line-height: 1.6; margin-bottom: 18px; }
|
||||
.confirm-modal__info { background: #f7f9fb; border-radius: 16px; padding: 14px 16px; margin-bottom: 18px; }
|
||||
.confirm-modal__row { display: flex; justify-content: space-between; align-items: center; font-size: 14px; color: var(--text-secondary); margin-bottom: 12px; }
|
||||
.confirm-modal__row:last-child { margin-bottom: 0; }
|
||||
.confirm-modal__value { font-size: 15px; font-weight: 700; color: var(--text-primary); }
|
||||
.confirm-modal__value--highlight { color: var(--primary-dark); }
|
||||
.confirm-modal__actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
|
||||
.confirm-modal__btn { height: 44px; border-radius: 22px; font-size: 15px; font-weight: 600; border: none; cursor: pointer; }
|
||||
.confirm-modal__btn--ghost { background: #f5f5f5; color: var(--text-secondary); }
|
||||
.confirm-modal__btn--primary { background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%); color: #fff; }
|
||||
.toast {
|
||||
position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%) scale(0.9);
|
||||
background: rgba(0,0,0,0.75); color: #fff; padding: 14px 22px; border-radius: 12px;
|
||||
font-size: 13px; line-height: 1.6; text-align: center; z-index: 200;
|
||||
opacity: 0; pointer-events: none; transition: all 0.25s ease; max-width: 280px;
|
||||
}
|
||||
.toast.show { opacity: 1; transform: translate(-50%, -50%) scale(1); }
|
||||
</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">
|
||||
<a class="nav-back" href="gastro-questionnaire.html">‹</a>
|
||||
<span class="nav-title">胃肠镜预约</span>
|
||||
</div>
|
||||
<div class="scroll-content">
|
||||
<div class="page-body">
|
||||
<div class="stepper">
|
||||
<a class="stepper__item stepper__item--done" href="gastro-hospital.html"><div class="stepper__dot">✓</div><div class="stepper__label">选择医院</div></a>
|
||||
<div class="stepper__line stepper__line--done"></div>
|
||||
<a class="stepper__item stepper__item--done" href="gastro-questionnaire.html"><div class="stepper__dot">✓</div><div class="stepper__label">填问卷</div></a>
|
||||
<div class="stepper__line stepper__line--done"></div>
|
||||
<div class="stepper__item stepper__item--active"><div class="stepper__dot">3</div><div class="stepper__label">预约日期</div></div>
|
||||
</div>
|
||||
|
||||
<div class="summary-card">
|
||||
<div class="section-title">预约信息</div>
|
||||
<div class="summary-list">
|
||||
<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">宁夏宝石花医院</div></div>
|
||||
<div class="summary-item"><div class="summary-item__label">问卷状态</div><div class="summary-item__value" style="color:var(--primary-dark)">已完成</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="date-card">
|
||||
<div class="calendar-header">
|
||||
<span class="calendar-header__month" id="calendarMonth"></span>
|
||||
<div class="calendar-header__nav">
|
||||
<button class="calendar-header__btn" id="prevMonth">‹</button>
|
||||
<button class="calendar-header__btn" id="nextMonth">›</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="calendar-weekdays">
|
||||
<span class="calendar-weekday">一</span><span class="calendar-weekday">二</span>
|
||||
<span class="calendar-weekday">三</span><span class="calendar-weekday">四</span>
|
||||
<span class="calendar-weekday">五</span><span class="calendar-weekday">六</span>
|
||||
<span class="calendar-weekday">日</span>
|
||||
</div>
|
||||
<div class="calendar-grid" id="calendarGrid"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-actions">
|
||||
<button class="bottom-actions__btn bottom-actions__btn--ghost" onclick="location.href='gastro-questionnaire.html'">上一步</button>
|
||||
<button class="bottom-actions__btn bottom-actions__btn--primary" onclick="openConfirm()">确定预约</button>
|
||||
</div>
|
||||
<div class="modal-overlay hidden" id="confirmModal">
|
||||
<div class="confirm-modal">
|
||||
<div class="confirm-modal__title">确认预约信息</div>
|
||||
<div class="confirm-modal__desc">请确认以下胃肠镜预约信息无误</div>
|
||||
<div class="confirm-modal__info">
|
||||
<div class="confirm-modal__row"><span>体检类型</span><span class="confirm-modal__value">胃肠镜体检</span></div>
|
||||
<div class="confirm-modal__row"><span>体检医院</span><span class="confirm-modal__value">宁夏宝石花医院</span></div>
|
||||
<div class="confirm-modal__row"><span>预约日期</span><span class="confirm-modal__value confirm-modal__value--highlight" id="confirmDate">--</span></div>
|
||||
</div>
|
||||
<div class="confirm-modal__actions">
|
||||
<button class="confirm-modal__btn confirm-modal__btn--ghost" onclick="closeConfirm()">取消</button>
|
||||
<button class="confirm-modal__btn confirm-modal__btn--primary" onclick="showSuccessToast()">确认预约</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="toast" id="successToast">预约成功!请按时前往医院进行胃肠镜检查</div>
|
||||
</div>
|
||||
<script>
|
||||
var today = new Date(2026, 2, 16);
|
||||
var currentYear = today.getFullYear();
|
||||
var currentMonth = today.getMonth();
|
||||
var selectedDate = null;
|
||||
var grid = document.getElementById('calendarGrid');
|
||||
var monthLabel = document.getElementById('calendarMonth');
|
||||
var prevBtn = document.getElementById('prevMonth');
|
||||
var nextBtn = document.getElementById('nextMonth');
|
||||
var toastTimer = null;
|
||||
|
||||
function getSlots(year, month, day) {
|
||||
var d = new Date(year, month, day);
|
||||
var dow = d.getDay();
|
||||
if (d < new Date(today.getFullYear(), today.getMonth(), today.getDate())) return -1;
|
||||
if (dow === 0 || dow === 6) return 0;
|
||||
var seed = (day * 7 + month * 13) % 20;
|
||||
if (seed < 3) return 0;
|
||||
return seed + 2;
|
||||
}
|
||||
|
||||
function renderCalendar() {
|
||||
grid.innerHTML = '';
|
||||
monthLabel.textContent = currentYear + '年' + (currentMonth + 1) + '月';
|
||||
prevBtn.disabled = (currentYear === today.getFullYear() && currentMonth <= today.getMonth());
|
||||
var firstDay = new Date(currentYear, currentMonth, 1);
|
||||
var startDow = firstDay.getDay();
|
||||
startDow = startDow === 0 ? 6 : startDow - 1;
|
||||
var daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate();
|
||||
for (var i = 0; i < startDow; i++) {
|
||||
var empty = document.createElement('div');
|
||||
empty.className = 'calendar-cell empty';
|
||||
grid.appendChild(empty);
|
||||
}
|
||||
for (var day = 1; day <= daysInMonth; day++) {
|
||||
(function(d) {
|
||||
var cell = document.createElement('div');
|
||||
var slots = getSlots(currentYear, currentMonth, d);
|
||||
var isToday = (currentYear === today.getFullYear() && currentMonth === today.getMonth() && d === today.getDate());
|
||||
var isDisabled = slots <= 0;
|
||||
var isFull = slots === 0;
|
||||
var isPast = slots === -1;
|
||||
var cls = 'calendar-cell';
|
||||
if (isToday) cls += ' today';
|
||||
if (isDisabled) cls += ' disabled';
|
||||
if (selectedDate && selectedDate.y === currentYear && selectedDate.m === currentMonth && selectedDate.d === d) cls += ' selected';
|
||||
cell.className = cls;
|
||||
var slotsHtml = '';
|
||||
if (isPast) slotsHtml = '';
|
||||
else if (isFull) slotsHtml = '<span class="calendar-cell__full">不可约</span>';
|
||||
else if (slots > 0) slotsHtml = '<span class="calendar-cell__slots">余' + slots + '</span>';
|
||||
cell.innerHTML = '<span class="calendar-cell__day">' + d + '</span>' + slotsHtml;
|
||||
if (!isDisabled) {
|
||||
cell.addEventListener('click', function() {
|
||||
selectedDate = { y: currentYear, m: currentMonth, d: d };
|
||||
renderCalendar();
|
||||
});
|
||||
}
|
||||
grid.appendChild(cell);
|
||||
})(day);
|
||||
}
|
||||
}
|
||||
|
||||
prevBtn.addEventListener('click', function() {
|
||||
currentMonth--;
|
||||
if (currentMonth < 0) { currentMonth = 11; currentYear--; }
|
||||
renderCalendar();
|
||||
});
|
||||
nextBtn.addEventListener('click', function() {
|
||||
currentMonth++;
|
||||
if (currentMonth > 11) { currentMonth = 0; currentYear++; }
|
||||
renderCalendar();
|
||||
});
|
||||
|
||||
selectedDate = { y: today.getFullYear(), m: today.getMonth(), d: today.getDate() };
|
||||
renderCalendar();
|
||||
|
||||
function openConfirm() {
|
||||
if (!selectedDate) return;
|
||||
document.getElementById('confirmDate').textContent = selectedDate.y + '年' + (selectedDate.m + 1) + '月' + selectedDate.d + '日';
|
||||
document.getElementById('confirmModal').classList.remove('hidden');
|
||||
}
|
||||
function closeConfirm() { document.getElementById('confirmModal').classList.add('hidden'); }
|
||||
function showSuccessToast() {
|
||||
closeConfirm();
|
||||
var toast = document.getElementById('successToast');
|
||||
toast.classList.add('show');
|
||||
clearTimeout(toastTimer);
|
||||
toastTimer = setTimeout(function() { toast.classList.remove('show'); }, 2200);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,224 @@
|
||||
<!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;
|
||||
--border: #e8f3f3;
|
||||
--bg-page: #f0f2f5;
|
||||
--bg-content: #f7f9fb;
|
||||
--shadow: 0 10px 30px 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); }
|
||||
.nav-right {
|
||||
position: absolute; right: 16px; font-size: 13px; color: var(--primary);
|
||||
font-weight: 600; cursor: pointer; display: flex; align-items: center; gap: 4px;
|
||||
}
|
||||
.scroll-content { flex: 1; overflow-y: auto; background: linear-gradient(180deg, #effbfb 0%, #f7f9fb 180px, #f7f9fb 100%); padding-bottom: 120px; }
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.page-body { padding: 16px; }
|
||||
.stepper { display: flex; align-items: center; justify-content: center; margin-bottom: 18px; padding: 16px 0; }
|
||||
.stepper__item { display: flex; flex-direction: column; align-items: center; gap: 6px; cursor: pointer; text-decoration: none; }
|
||||
.stepper__item--future { cursor: default; pointer-events: none; opacity: 0.45; }
|
||||
.stepper__dot {
|
||||
width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
|
||||
font-size: 12px; font-weight: 700; background: #e8e8e8; color: #bfbfbf; transition: all 0.25s;
|
||||
}
|
||||
.stepper__item--done .stepper__dot { background: var(--primary); color: #fff; }
|
||||
.stepper__item--active { cursor: default; pointer-events: none; }
|
||||
.stepper__item--active .stepper__dot {
|
||||
width: 34px; height: 34px; font-size: 14px;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%); color: #fff;
|
||||
box-shadow: 0 0 0 6px rgba(19,194,194,0.2);
|
||||
}
|
||||
.stepper__label { font-size: 12px; color: var(--text-muted); white-space: nowrap; transition: all 0.2s; }
|
||||
.stepper__item--done .stepper__label { color: var(--primary-dark); }
|
||||
.stepper__item--active .stepper__label {
|
||||
color: var(--primary-dark); font-weight: 700; font-size: 13px;
|
||||
background: var(--primary-light); padding: 2px 10px; border-radius: 10px;
|
||||
}
|
||||
.stepper__line { width: 44px; height: 3px; background: #e8e8e8; margin: 0 8px; margin-bottom: 22px; border-radius: 2px; }
|
||||
.stepper__line--done { background: var(--primary); }
|
||||
.section-title { font-size: 16px; font-weight: 700; margin-bottom: 14px; margin-top: 6px; }
|
||||
.hospital-card {
|
||||
background: #fff; border-radius: 18px; padding: 16px; margin-bottom: 12px;
|
||||
border: 2px solid transparent; box-shadow: var(--shadow); cursor: pointer;
|
||||
display: flex; align-items: center; justify-content: space-between; transition: all 0.25s ease;
|
||||
}
|
||||
.hospital-card.active { border-color: var(--primary); background: var(--primary-light); }
|
||||
.hospital-card__info { display: flex; align-items: center; gap: 12px; }
|
||||
.hospital-card__icon {
|
||||
width: 42px; height: 42px; border-radius: 14px;
|
||||
background: linear-gradient(135deg, #e6fffb 0%, #b5f5ec 100%);
|
||||
display: flex; align-items: center; justify-content: center; font-size: 20px; flex-shrink: 0;
|
||||
}
|
||||
.hospital-card__name { font-size: 15px; font-weight: 600; color: var(--text-primary); margin-bottom: 2px; }
|
||||
.hospital-card__addr { font-size: 12px; color: var(--text-muted); }
|
||||
.radio-dot {
|
||||
width: 22px; height: 22px; border-radius: 50%; border: 2px solid #d9d9d9;
|
||||
display: flex; align-items: center; justify-content: center; transition: all 0.25s ease; flex-shrink: 0;
|
||||
}
|
||||
.hospital-card.active .radio-dot { border-color: var(--primary); background: var(--primary); }
|
||||
.radio-dot::after { content: ''; width: 8px; height: 8px; border-radius: 50%; background: #fff; opacity: 0; transition: opacity 0.25s ease; }
|
||||
.hospital-card.active .radio-dot::after { opacity: 1; }
|
||||
.bottom-actions { position: absolute; left: 16px; right: 16px; bottom: 18px; padding-bottom: 16px; }
|
||||
.bottom-actions__btn {
|
||||
width: 100%; height: 48px; border-radius: 24px; font-size: 15px; font-weight: 600;
|
||||
border: none; cursor: pointer; background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff; box-shadow: 0 10px 20px rgba(19, 194, 194, 0.22);
|
||||
}
|
||||
.modal-overlay {
|
||||
position: absolute; inset: 0; background: rgba(0,0,0,0.45); z-index: 100;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
}
|
||||
.modal-overlay.hidden { display: none; }
|
||||
.modal-card { width: 340px; background: #fff; border-radius: 24px; padding: 24px 20px; box-shadow: 0 20px 60px rgba(0,0,0,0.18); }
|
||||
.modal-card__title { font-size: 18px; font-weight: 700; text-align: center; margin-bottom: 6px; }
|
||||
.modal-card__sub { font-size: 13px; color: var(--text-muted); text-align: center; margin-bottom: 20px; }
|
||||
.modal-field { display: flex; justify-content: space-between; align-items: center; padding: 14px 0; border-bottom: 1px solid #f0f0f0; }
|
||||
.modal-field:last-of-type { border-bottom: none; }
|
||||
.modal-field__label { font-size: 14px; color: var(--text-muted); }
|
||||
.modal-field__value { font-size: 14px; color: var(--text-primary); font-weight: 600; }
|
||||
.marriage-toggle { display: inline-flex; background: #f5f5f5; border-radius: 20px; overflow: hidden; }
|
||||
.marriage-toggle__btn {
|
||||
padding: 6px 16px; font-size: 13px; font-weight: 600; border: none;
|
||||
background: transparent; color: var(--text-muted); cursor: pointer; border-radius: 20px; transition: all 0.2s ease;
|
||||
}
|
||||
.marriage-toggle__btn.active { background: var(--primary); color: #fff; }
|
||||
.modal-confirm-btn {
|
||||
margin-top: 20px; width: 100%; height: 44px; border-radius: 22px; font-size: 15px; font-weight: 600;
|
||||
border: none; cursor: pointer; background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff; box-shadow: 0 8px 20px rgba(19, 194, 194, 0.2);
|
||||
}
|
||||
</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">
|
||||
<a class="nav-back" href="booking-type.html">‹</a>
|
||||
<span class="nav-title">胃肠镜预约</span>
|
||||
<span class="nav-right" onclick="openModal()">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
|
||||
个人信息
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="scroll-content">
|
||||
<div class="page-body">
|
||||
<div class="stepper">
|
||||
<a class="stepper__item stepper__item--active" href="gastro-hospital.html"><div class="stepper__dot">1</div><div class="stepper__label">选择医院</div></a>
|
||||
<div class="stepper__line"></div>
|
||||
<div class="stepper__item stepper__item--future"><div class="stepper__dot">2</div><div class="stepper__label">填问卷</div></div>
|
||||
<div class="stepper__line"></div>
|
||||
<div class="stepper__item stepper__item--future"><div class="stepper__dot">3</div><div class="stepper__label">预约日期</div></div>
|
||||
</div>
|
||||
|
||||
<div class="section-title">选择医院</div>
|
||||
<div class="hospital-card active" onclick="selectHospital(this)">
|
||||
<div class="hospital-card__info">
|
||||
<div class="hospital-card__icon">🏥</div>
|
||||
<div><div class="hospital-card__name">宁夏宝石花医院</div><div class="hospital-card__addr">宁夏银川市</div></div>
|
||||
</div>
|
||||
<div class="radio-dot"></div>
|
||||
</div>
|
||||
<div class="hospital-card" onclick="selectHospital(this)">
|
||||
<div class="hospital-card__info">
|
||||
<div class="hospital-card__icon">🏥</div>
|
||||
<div><div class="hospital-card__name">长庆星龙园医院</div><div class="hospital-card__addr">陕西西安市</div></div>
|
||||
</div>
|
||||
<div class="radio-dot"></div>
|
||||
</div>
|
||||
<div class="hospital-card" onclick="selectHospital(this)">
|
||||
<div class="hospital-card__info">
|
||||
<div class="hospital-card__icon">🏥</div>
|
||||
<div><div class="hospital-card__name">西安长庆医院</div><div class="hospital-card__addr">陕西西安市</div></div>
|
||||
</div>
|
||||
<div class="radio-dot"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bottom-actions">
|
||||
<button class="bottom-actions__btn" onclick="location.href='gastro-questionnaire.html'">下一步</button>
|
||||
</div>
|
||||
|
||||
<div class="modal-overlay hidden" id="personModal">
|
||||
<div class="modal-card">
|
||||
<div class="modal-card__title">确认个人信息</div>
|
||||
<div class="modal-card__sub">请核对以下信息,确认无误后继续预约</div>
|
||||
<div class="modal-field"><span class="modal-field__label">姓名</span><span class="modal-field__value">刘韵琴</span></div>
|
||||
<div class="modal-field"><span class="modal-field__label">单位</span><span class="modal-field__value">长庆油田第一采油厂</span></div>
|
||||
<div class="modal-field"><span class="modal-field__label">身份证号</span><span class="modal-field__value">6101021994********</span></div>
|
||||
<div class="modal-field"><span class="modal-field__label">性别</span><span class="modal-field__value">女</span></div>
|
||||
<div class="modal-field">
|
||||
<span class="modal-field__label">婚姻状况</span>
|
||||
<div class="marriage-toggle">
|
||||
<button class="marriage-toggle__btn active" onclick="toggleMarriage(this)">已婚</button>
|
||||
<button class="marriage-toggle__btn" onclick="toggleMarriage(this)">未婚</button>
|
||||
</div>
|
||||
</div>
|
||||
<button class="modal-confirm-btn" onclick="closeModal()">确认</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
if (new URLSearchParams(window.location.search).get('from') === 'booking-type') {
|
||||
document.getElementById('personModal').classList.remove('hidden');
|
||||
}
|
||||
function selectHospital(el) {
|
||||
document.querySelectorAll('.hospital-card').forEach(c => c.classList.remove('active'));
|
||||
el.classList.add('active');
|
||||
}
|
||||
function openModal() { document.getElementById('personModal').classList.remove('hidden'); }
|
||||
function closeModal() { document.getElementById('personModal').classList.add('hidden'); }
|
||||
function toggleMarriage(btn) {
|
||||
document.querySelectorAll('.marriage-toggle__btn').forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,200 @@
|
||||
<!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 30px 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 180px, #f7f9fb 100%); padding-bottom: 120px; }
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.page-body { padding: 16px; }
|
||||
.stepper { display: flex; align-items: center; justify-content: center; margin-bottom: 18px; padding: 16px 0; }
|
||||
.stepper__item { display: flex; flex-direction: column; align-items: center; gap: 6px; cursor: pointer; text-decoration: none; }
|
||||
.stepper__item--future { cursor: default; pointer-events: none; opacity: 0.45; }
|
||||
.stepper__dot {
|
||||
width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
|
||||
font-size: 12px; font-weight: 700; background: #e8e8e8; color: #bfbfbf; transition: all 0.25s;
|
||||
}
|
||||
.stepper__item--done .stepper__dot { background: var(--primary); color: #fff; }
|
||||
.stepper__item--active { cursor: default; pointer-events: none; }
|
||||
.stepper__item--active .stepper__dot {
|
||||
width: 34px; height: 34px; font-size: 14px;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%); color: #fff;
|
||||
box-shadow: 0 0 0 6px rgba(19,194,194,0.2);
|
||||
}
|
||||
.stepper__label { font-size: 12px; color: var(--text-muted); white-space: nowrap; transition: all 0.2s; }
|
||||
.stepper__item--done .stepper__label { color: var(--primary-dark); }
|
||||
.stepper__item--active .stepper__label {
|
||||
color: var(--primary-dark); font-weight: 700; font-size: 13px;
|
||||
background: var(--primary-light); padding: 2px 10px; border-radius: 10px;
|
||||
}
|
||||
.stepper__item--done:hover .stepper__dot { transform: scale(1.12); box-shadow: 0 0 0 4px rgba(19,194,194,0.15); }
|
||||
.stepper__item--done:hover .stepper__label { text-decoration: underline; text-underline-offset: 3px; }
|
||||
.stepper__line { width: 44px; height: 3px; background: #e8e8e8; margin: 0 8px; margin-bottom: 22px; border-radius: 2px; }
|
||||
.stepper__line--done { background: var(--primary); }
|
||||
.section-title { font-size: 16px; font-weight: 700; margin-bottom: 6px; }
|
||||
.section-desc { font-size: 13px; color: var(--text-muted); margin-bottom: 20px; }
|
||||
.q-card {
|
||||
background: #fff; border-radius: 18px; padding: 18px; margin-bottom: 14px;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
.q-card__index {
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
width: 22px; height: 22px; border-radius: 50%; background: var(--primary);
|
||||
color: #fff; font-size: 11px; font-weight: 700; margin-right: 8px; flex-shrink: 0;
|
||||
}
|
||||
.q-card__label {
|
||||
font-size: 15px; font-weight: 600; color: var(--text-primary);
|
||||
display: flex; align-items: center; margin-bottom: 14px;
|
||||
}
|
||||
.q-options { display: flex; gap: 12px; }
|
||||
.q-option {
|
||||
flex: 1; height: 44px; border-radius: 22px; border: 2px solid #e8e8e8;
|
||||
background: #fff; font-size: 14px; font-weight: 600; color: var(--text-secondary);
|
||||
cursor: pointer; transition: all 0.2s ease; display: flex; align-items: center; justify-content: center;
|
||||
}
|
||||
.q-option.active { border-color: var(--primary); background: var(--primary-light); color: var(--primary-dark); }
|
||||
.bottom-actions {
|
||||
position: absolute; left: 16px; right: 16px; bottom: 18px; padding-bottom: 16px;
|
||||
display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
|
||||
}
|
||||
.bottom-actions__btn {
|
||||
height: 48px; border-radius: 24px; font-size: 15px; font-weight: 600; border: none; cursor: pointer;
|
||||
}
|
||||
.bottom-actions__btn--ghost {
|
||||
background: #fff; color: var(--primary-dark); border: 2px solid #d0eded;
|
||||
}
|
||||
.bottom-actions__btn--primary {
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff; box-shadow: 0 10px 20px rgba(19, 194, 194, 0.22);
|
||||
}
|
||||
</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">
|
||||
<a class="nav-back" href="gastro-hospital.html">‹</a>
|
||||
<span class="nav-title">胃肠镜预约</span>
|
||||
</div>
|
||||
|
||||
<div class="scroll-content">
|
||||
<div class="page-body">
|
||||
<div class="stepper">
|
||||
<a class="stepper__item stepper__item--done" href="gastro-hospital.html"><div class="stepper__dot">✓</div><div class="stepper__label">选择医院</div></a>
|
||||
<div class="stepper__line stepper__line--done"></div>
|
||||
<div class="stepper__item stepper__item--active"><div class="stepper__dot">2</div><div class="stepper__label">填问卷</div></div>
|
||||
<div class="stepper__line"></div>
|
||||
<div class="stepper__item stepper__item--future"><div class="stepper__dot">3</div><div class="stepper__label">预约日期</div></div>
|
||||
</div>
|
||||
|
||||
<div class="section-title">胃肠镜检查问卷</div>
|
||||
<div class="section-desc">请如实填写以下信息,以便医生评估检查方案</div>
|
||||
|
||||
<div class="q-card">
|
||||
<div class="q-card__label"><span class="q-card__index">1</span>是否使用阿司匹林?</div>
|
||||
<div class="q-options">
|
||||
<button class="q-option" onclick="toggleOption(this)">是</button>
|
||||
<button class="q-option active" onclick="toggleOption(this)">否</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="q-card">
|
||||
<div class="q-card__label"><span class="q-card__index">2</span>是否有心脏疾病?</div>
|
||||
<div class="q-options">
|
||||
<button class="q-option" onclick="toggleOption(this)">是</button>
|
||||
<button class="q-option active" onclick="toggleOption(this)">否</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="q-card">
|
||||
<div class="q-card__label"><span class="q-card__index">3</span>是否有肺部疾病?</div>
|
||||
<div class="q-options">
|
||||
<button class="q-option" onclick="toggleOption(this)">是</button>
|
||||
<button class="q-option active" onclick="toggleOption(this)">否</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="q-card">
|
||||
<div class="q-card__label"><span class="q-card__index">4</span>是否有哮喘?</div>
|
||||
<div class="q-options">
|
||||
<button class="q-option" onclick="toggleOption(this)">是</button>
|
||||
<button class="q-option active" onclick="toggleOption(this)">否</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="q-card">
|
||||
<div class="q-card__label"><span class="q-card__index">5</span>胸部是否检查?</div>
|
||||
<div class="q-options">
|
||||
<button class="q-option active" onclick="toggleOption(this)">是</button>
|
||||
<button class="q-option" onclick="toggleOption(this)">否</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="q-card">
|
||||
<div class="q-card__label"><span class="q-card__index">6</span>血液是否检查?</div>
|
||||
<div class="q-options">
|
||||
<button class="q-option active" onclick="toggleOption(this)">是</button>
|
||||
<button class="q-option" onclick="toggleOption(this)">否</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bottom-actions">
|
||||
<button class="bottom-actions__btn bottom-actions__btn--ghost" onclick="location.href='gastro-hospital.html'">上一步</button>
|
||||
<button class="bottom-actions__btn bottom-actions__btn--primary" onclick="location.href='gastro-date.html'">下一步</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function toggleOption(btn) {
|
||||
var group = btn.parentElement;
|
||||
group.querySelectorAll('.q-option').forEach(function(b) { b.classList.remove('active'); });
|
||||
btn.classList.add('active');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,253 @@
|
||||
<!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.html -->
|
||||
<a class="nav-back" href="my-appointments.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.html -->
|
||||
<button class="bottom-action__btn" onclick="window.location.href='my-appointments.html'">返回我的预约</button>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,280 @@
|
||||
<!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.html -->
|
||||
<div class="feature-card" onclick="location.href='my-appointments.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>
|
||||
@@ -0,0 +1,392 @@
|
||||
<!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 160px, #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 #e3f6f4;
|
||||
border-radius: 20px;
|
||||
padding: 18px 16px;
|
||||
box-shadow: 0 6px 18px rgba(20, 180, 176, 0.08);
|
||||
}
|
||||
.hero-card__badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
height: 28px;
|
||||
padding: 0 10px;
|
||||
border-radius: 14px;
|
||||
background: rgba(255, 170, 0, 0.12);
|
||||
color: #d48806;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.hero-card__title {
|
||||
font-size: 22px;
|
||||
line-height: 1.2;
|
||||
font-weight: 700;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.hero-card__desc {
|
||||
font-size: 14px;
|
||||
line-height: 1.7;
|
||||
color: #666;
|
||||
}
|
||||
.fee-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);
|
||||
}
|
||||
.fee-card__label {
|
||||
font-size: 13px;
|
||||
opacity: 0.9;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.fee-card__value {
|
||||
font-size: 30px;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.fee-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;
|
||||
cursor: pointer;
|
||||
transition: transform 0.15s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.quick-card:active { transform: scale(0.985); }
|
||||
.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;
|
||||
}
|
||||
.tips-card {
|
||||
margin-top: 16px;
|
||||
background: #fff;
|
||||
border-radius: 18px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 4px 14px rgba(0,0,0,0.05);
|
||||
border: 1px solid #f0f0f0;
|
||||
}
|
||||
.tips-card__title {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.tips-card__list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
.tips-card__item {
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
color: #666;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
.tips-card__dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: #13c2c2;
|
||||
margin-top: 7px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.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="location.href='../home/index.html'">‹</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="fee-card">
|
||||
<div class="fee-card__label">本年度体检费用(元)</div>
|
||||
<div class="fee-card__value">1500.00</div>
|
||||
<!-- <div class="fee-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.html -->
|
||||
<div class="feature-card" onclick="location.href='my-appointments.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">查看报告/ 解读结果</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>
|
||||
|
||||
<!-- [交互] 一键咨询入口,点击跳转至 consult.html -->
|
||||
<div class="quick-card" onclick="location.href='consult.html'">
|
||||
<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="tips-card">-->
|
||||
<!-- <div class="tips-card__title">体检提醒</div>-->
|
||||
<!-- <div class="tips-card__list">-->
|
||||
<!-- <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 class="tips-card__item"><span class="tips-card__dot"></span><span>报告生成后可在线查看,并结合解读结果关注异常指标。</span></div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<div class="bottom-spacer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,200 @@
|
||||
<!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;
|
||||
--success-bg: #f6ffed;
|
||||
--success-text: #52c41a;
|
||||
--warning-bg: #fff7e6;
|
||||
--warning-text: #fa8c16;
|
||||
--danger-bg: #fff1f0;
|
||||
--danger-text: #ff4d4f;
|
||||
--text-primary: #1a1a1a;
|
||||
--text-secondary: #666666;
|
||||
--text-muted: #8c8c8c;
|
||||
--bg-page: #f0f2f5;
|
||||
--bg-content: #f7f9fb;
|
||||
--border: #e8f3f3;
|
||||
--shadow: 0 10px 24px rgba(19, 194, 194, 0.06);
|
||||
}
|
||||
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, #f0fbfb 0%, #f7f9fb 140px, #f7f9fb 100%);
|
||||
padding: 14px 16px 20px;
|
||||
}
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.tabs {
|
||||
display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; padding: 6px;
|
||||
background: rgba(255,255,255,0.92); border-radius: 18px;
|
||||
box-shadow: 0 8px 20px rgba(19, 194, 194, 0.08);
|
||||
position: sticky; top: 0; z-index: 5; backdrop-filter: blur(10px);
|
||||
}
|
||||
.tabs__item {
|
||||
height: 36px; border: none; border-radius: 14px; background: transparent;
|
||||
color: var(--text-secondary); font-size: 13px; font-weight: 600; cursor: pointer;
|
||||
text-decoration: none; display: flex; align-items: center; justify-content: center;
|
||||
}
|
||||
.tabs__item--active {
|
||||
background: var(--primary-light); color: var(--primary-dark);
|
||||
box-shadow: inset 0 0 0 1px rgba(19, 194, 194, 0.16);
|
||||
}
|
||||
.summary-bar {
|
||||
margin: 14px 0 12px; padding: 16px; border-radius: 20px;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff; box-shadow: 0 12px 24px rgba(19, 194, 194, 0.2);
|
||||
}
|
||||
.summary-bar__title { font-size: 18px; font-weight: 700; margin-bottom: 6px; }
|
||||
.summary-bar__desc { font-size: 13px; line-height: 1.7; opacity: 0.92; }
|
||||
.appointment-list { display: flex; flex-direction: column; gap: 12px; }
|
||||
.appointment-card {
|
||||
background: #fff; border-radius: 20px; padding: 16px;
|
||||
border: 1px solid rgba(19, 194, 194, 0.06); box-shadow: var(--shadow);
|
||||
}
|
||||
.appointment-card[data-status="done"],
|
||||
.appointment-card[data-status="cancelled"] { opacity: 0.94; }
|
||||
.appointment-card__top { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 12px; }
|
||||
.appointment-card__title { font-size: 16px; font-weight: 700; color: var(--text-primary); }
|
||||
.appointment-card__status { flex-shrink: 0; padding: 5px 10px; border-radius: 999px; font-size: 12px; font-weight: 600; }
|
||||
.appointment-card__status--pending { background: var(--warning-bg); color: var(--warning-text); }
|
||||
.appointment-card__status--done { background: var(--success-bg); color: var(--success-text); }
|
||||
.appointment-card__status--cancelled { background: var(--danger-bg); color: var(--danger-text); }
|
||||
.appointment-card__meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 12px; margin-bottom: 12px; }
|
||||
.meta-item { background: #f9fbfb; border-radius: 14px; padding: 10px 12px; border: 1px solid #f0f5f5; }
|
||||
.meta-item__label { font-size: 11px; color: var(--text-muted); margin-bottom: 5px; }
|
||||
.meta-item__value { font-size: 13px; color: var(--text-primary); font-weight: 600; line-height: 1.5; }
|
||||
.appointment-card__progress { margin-bottom: 14px; }
|
||||
.progress-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; font-size: 12px; color: var(--text-secondary); }
|
||||
.progress-bar { height: 8px; border-radius: 999px; background: #eef3f3; overflow: hidden; }
|
||||
.progress-bar__fill { height: 100%; border-radius: 999px; background: linear-gradient(90deg, #13c2c2 0%, #5cdbd3 100%); }
|
||||
.appointment-card__actions { display: flex; gap: 10px; }
|
||||
.appointment-card__btn {
|
||||
flex: 1; height: 40px; border-radius: 20px; font-size: 14px; font-weight: 600; border: none; cursor: pointer;
|
||||
}
|
||||
.appointment-card__btn--ghost { background: #f5f7fa; color: var(--text-secondary); border: 1px solid #ebeff2; }
|
||||
.appointment-card__btn--primary {
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff; box-shadow: 0 8px 20px rgba(19, 194, 194, 0.18);
|
||||
}
|
||||
</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">
|
||||
<a class="nav-back" href="index.html">‹</a>
|
||||
<span class="nav-title">我的预约</span>
|
||||
</div>
|
||||
<div class="scroll-content">
|
||||
<div class="tabs">
|
||||
<a class="tabs__item tabs__item--active" href="my-appointments-all.html">全部</a>
|
||||
<a class="tabs__item" href="my-appointments.html">待体检</a>
|
||||
<a class="tabs__item" href="my-appointments-done.html">已完成</a>
|
||||
<a class="tabs__item" href="my-appointments-cancelled.html">已取消</a>
|
||||
</div>
|
||||
|
||||
<div class="appointment-list">
|
||||
<!-- 待体检 -->
|
||||
<div class="appointment-card" data-status="pending">
|
||||
<div class="appointment-card__top">
|
||||
<div class="appointment-card__title">常规体检</div>
|
||||
<div class="appointment-card__status appointment-card__status--pending">待体检</div>
|
||||
</div>
|
||||
<div class="appointment-card__meta">
|
||||
<div class="meta-item"><div class="meta-item__label">体检医院</div><div class="meta-item__value">宁夏宝石花医院</div></div>
|
||||
<div class="meta-item"><div class="meta-item__label">预约日期</div><div class="meta-item__value">2026-03-23</div></div>
|
||||
</div>
|
||||
<div class="appointment-card__progress">
|
||||
<div class="progress-head"><span>体检进度</span><span>5/26</span></div>
|
||||
<div class="progress-bar"><div class="progress-bar__fill" style="width: 19.2%;"></div></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- 已完成 -->
|
||||
<div class="appointment-card" data-status="done">
|
||||
<div class="appointment-card__top">
|
||||
<div class="appointment-card__title">常规体检</div>
|
||||
<div class="appointment-card__status appointment-card__status--done">已完成</div>
|
||||
</div>
|
||||
<div class="appointment-card__meta">
|
||||
<div class="meta-item"><div class="meta-item__label">体检医院</div><div class="meta-item__value">宁夏宝石花医院</div></div>
|
||||
<div class="meta-item"><div class="meta-item__label">预约日期</div><div class="meta-item__value">2026-03-23</div></div>
|
||||
</div>
|
||||
<div class="appointment-card__progress">
|
||||
<div class="progress-head"><span>体检进度</span><span>26/26</span></div>
|
||||
<div class="progress-bar"><div class="progress-bar__fill" style="width: 100%;"></div></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- 已取消 -->
|
||||
<div class="appointment-card" data-status="cancelled">
|
||||
<div class="appointment-card__top">
|
||||
<div class="appointment-card__title">胃肠镜体检</div>
|
||||
<div class="appointment-card__status appointment-card__status--cancelled">已取消</div>
|
||||
</div>
|
||||
<div class="appointment-card__meta">
|
||||
<div class="meta-item"><div class="meta-item__label">体检医院</div><div class="meta-item__value">宁夏宝石花医院</div></div>
|
||||
<div class="meta-item"><div class="meta-item__label">预约日期</div><div class="meta-item__value">2026-03-10</div></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- 待体检 -->
|
||||
<div class="appointment-card" data-status="pending">
|
||||
<div class="appointment-card__top">
|
||||
<div class="appointment-card__title">常规体检</div>
|
||||
<div class="appointment-card__status appointment-card__status--pending">待体检</div>
|
||||
</div>
|
||||
<div class="appointment-card__meta">
|
||||
<div class="meta-item"><div class="meta-item__label">体检医院</div><div class="meta-item__value">宁夏宝石花医院</div></div>
|
||||
<div class="meta-item"><div class="meta-item__label">预约日期</div><div class="meta-item__value">2026-03-23</div></div>
|
||||
</div>
|
||||
<div class="appointment-card__progress">
|
||||
<div class="progress-head"><span>体检进度</span><span>0/26</span></div>
|
||||
<div class="progress-bar"><div class="progress-bar__fill" style="width: 0%;"></div></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,150 @@
|
||||
<!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;
|
||||
--success-bg: #f6ffed;
|
||||
--success-text: #52c41a;
|
||||
--warning-bg: #fff7e6;
|
||||
--warning-text: #fa8c16;
|
||||
--danger-bg: #fff1f0;
|
||||
--danger-text: #ff4d4f;
|
||||
--text-primary: #1a1a1a;
|
||||
--text-secondary: #666666;
|
||||
--text-muted: #8c8c8c;
|
||||
--bg-page: #f0f2f5;
|
||||
--bg-content: #f7f9fb;
|
||||
--border: #e8f3f3;
|
||||
--shadow: 0 10px 24px rgba(19, 194, 194, 0.06);
|
||||
}
|
||||
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, #f0fbfb 0%, #f7f9fb 140px, #f7f9fb 100%);
|
||||
padding: 14px 16px 20px;
|
||||
}
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.tabs {
|
||||
display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; padding: 6px;
|
||||
background: rgba(255,255,255,0.92); border-radius: 18px;
|
||||
box-shadow: 0 8px 20px rgba(19, 194, 194, 0.08);
|
||||
position: sticky; top: 0; z-index: 5; backdrop-filter: blur(10px);
|
||||
}
|
||||
.tabs__item {
|
||||
height: 36px; border: none; border-radius: 14px; background: transparent;
|
||||
color: var(--text-secondary); font-size: 13px; font-weight: 600; cursor: pointer;
|
||||
text-decoration: none; display: flex; align-items: center; justify-content: center;
|
||||
}
|
||||
.tabs__item--active {
|
||||
background: var(--primary-light); color: var(--primary-dark);
|
||||
box-shadow: inset 0 0 0 1px rgba(19, 194, 194, 0.16);
|
||||
}
|
||||
.summary-bar {
|
||||
margin: 14px 0 12px; padding: 16px; border-radius: 20px;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff; box-shadow: 0 12px 24px rgba(19, 194, 194, 0.2);
|
||||
}
|
||||
.summary-bar__title { font-size: 18px; font-weight: 700; margin-bottom: 6px; }
|
||||
.summary-bar__desc { font-size: 13px; line-height: 1.7; opacity: 0.92; }
|
||||
.appointment-list { display: flex; flex-direction: column; gap: 12px; }
|
||||
.appointment-card {
|
||||
background: #fff; border-radius: 20px; padding: 16px;
|
||||
border: 1px solid rgba(19, 194, 194, 0.06); box-shadow: var(--shadow); opacity: 0.94;
|
||||
}
|
||||
.appointment-card__top { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 12px; }
|
||||
.appointment-card__title { font-size: 16px; font-weight: 700; color: var(--text-primary); }
|
||||
.appointment-card__status { flex-shrink: 0; padding: 5px 10px; border-radius: 999px; font-size: 12px; font-weight: 600; }
|
||||
.appointment-card__status--cancelled { background: var(--danger-bg); color: var(--danger-text); }
|
||||
.appointment-card__meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 12px; margin-bottom: 12px; }
|
||||
.meta-item { background: #f9fbfb; border-radius: 14px; padding: 10px 12px; border: 1px solid #f0f5f5; }
|
||||
.meta-item__label { font-size: 11px; color: var(--text-muted); margin-bottom: 5px; }
|
||||
.meta-item__value { font-size: 13px; color: var(--text-primary); font-weight: 600; line-height: 1.5; }
|
||||
.appointment-card__actions { display: flex; gap: 10px; }
|
||||
.appointment-card__btn {
|
||||
flex: 1; height: 40px; border-radius: 20px; font-size: 14px; font-weight: 600; border: none; cursor: pointer;
|
||||
}
|
||||
.appointment-card__btn--ghost { background: #f5f7fa; color: var(--text-secondary); border: 1px solid #ebeff2; }
|
||||
</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">
|
||||
<a class="nav-back" href="index.html">‹</a>
|
||||
<span class="nav-title">我的预约</span>
|
||||
</div>
|
||||
<div class="scroll-content">
|
||||
<div class="tabs">
|
||||
<a class="tabs__item" href="my-appointments-all.html">全部</a>
|
||||
<a class="tabs__item" href="my-appointments.html">待体检</a>
|
||||
<a class="tabs__item" href="my-appointments-done.html">已完成</a>
|
||||
<a class="tabs__item tabs__item--active" href="my-appointments-cancelled.html">已取消</a>
|
||||
</div>
|
||||
|
||||
<div class="appointment-list">
|
||||
<a class="appointment-card" href="my-appointments-detail-cancelled.html" style="text-decoration:none;color:inherit;">
|
||||
<div class="appointment-card__top">
|
||||
<div class="appointment-card__title">胃肠镜体检</div>
|
||||
<div class="appointment-card__status appointment-card__status--cancelled">已取消</div>
|
||||
</div>
|
||||
<div class="appointment-card__meta">
|
||||
<div class="meta-item"><div class="meta-item__label">体检医院</div><div class="meta-item__value">宁夏宝石花医院</div></div>
|
||||
<div class="meta-item"><div class="meta-item__label">预约日期</div><div class="meta-item__value">2026-03-10</div></div>
|
||||
</div>
|
||||
|
||||
</a>
|
||||
<a class="appointment-card" href="my-appointments-detail-cancelled.html" style="text-decoration:none;color:inherit;">
|
||||
<div class="appointment-card__top">
|
||||
<div class="appointment-card__title">常规体检</div>
|
||||
<div class="appointment-card__status appointment-card__status--cancelled">已取消</div>
|
||||
</div>
|
||||
<div class="appointment-card__meta">
|
||||
<div class="meta-item"><div class="meta-item__label">体检医院</div><div class="meta-item__value">宁夏宝石花医院</div></div>
|
||||
<div class="meta-item"><div class="meta-item__label">预约日期</div><div class="meta-item__value">2026-01-15</div></div>
|
||||
</div>
|
||||
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,439 @@
|
||||
<!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;
|
||||
--success-light: #f6ffed;
|
||||
--success-text: #52c41a;
|
||||
--danger: #ff4d4f;
|
||||
--danger-light: #fff1f0;
|
||||
--text-primary: #1a1a1a;
|
||||
--text-secondary: #666666;
|
||||
--text-muted: #8c8c8c;
|
||||
--border: #e8f3f3;
|
||||
--bg-page: #f0f2f5;
|
||||
--bg-content: #f7f9fb;
|
||||
--shadow: 0 10px 30px 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 180px, #f7f9fb 100%);
|
||||
padding-bottom: 120px;
|
||||
}
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.page-body { padding: 16px; }
|
||||
/* 预约状态栏 */
|
||||
.status-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 14px 16px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.status-bar__left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.status-bar__dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #fa8c16;
|
||||
}
|
||||
.status-bar__text {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #fa8c16;
|
||||
}
|
||||
.status-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.24);
|
||||
}
|
||||
.status-card__badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 12px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255,255,255,0.18);
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.status-card__title {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
line-height: 1.25;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.status-card__desc {
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
opacity: 0.92;
|
||||
}
|
||||
.summary-card,
|
||||
.info-card {
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
padding: 18px 16px;
|
||||
margin-top: 14px;
|
||||
margin-top: 14px;
|
||||
box-shadow: var(--shadow);
|
||||
border: 1px solid rgba(19, 194, 194, 0.06);
|
||||
}
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.summary-list,
|
||||
.info-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
}
|
||||
.summary-item,
|
||||
.info-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.summary-item__label,
|
||||
.info-item__label {
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.summary-item__value,
|
||||
.info-item__value {
|
||||
font-size: 14px;
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
text-align: right;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.summary-item--fee {
|
||||
margin-top: 2px;
|
||||
padding: 14px;
|
||||
border-radius: 18px;
|
||||
background: linear-gradient(135deg, #f0fffe 0%, #f7fffd 100%);
|
||||
border: 1px solid #d7f5f3;
|
||||
align-items: center;
|
||||
}
|
||||
.summary-item--fee .summary-item__label {
|
||||
color: var(--primary-dark);
|
||||
font-weight: 600;
|
||||
}
|
||||
.summary-item--fee .summary-item__value {
|
||||
color: var(--primary-dark);
|
||||
font-size: 24px;
|
||||
font-weight: 800;
|
||||
}
|
||||
.person-card {
|
||||
margin-top: 14px;
|
||||
background: linear-gradient(135deg, #ffffff 0%, #f8fffe 100%);
|
||||
border-radius: 20px;
|
||||
padding: 16px;
|
||||
border: 1px solid #e4f7f5;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
.person-card__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.person-card__avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 16px;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #5cdbd3 100%);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.person-card__name {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.person-card__meta {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.tips-card {
|
||||
margin-top: 14px;
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
padding: 16px;
|
||||
border: 1px solid #eef5f5;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
.tips-card__title {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.tips-card__item {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.tips-card__item:last-child { margin-bottom: 0; }
|
||||
.tips-card__dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--primary);
|
||||
margin-top: 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/* 已选体检项目 */
|
||||
.project-section {
|
||||
background: #fff; border-radius: 20px; padding: 18px 16px;
|
||||
box-shadow: var(--shadow); border: 1px solid rgba(19,194,194,0.06); margin-top: 14px;
|
||||
}
|
||||
.project-section__header {
|
||||
display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px;
|
||||
}
|
||||
.project-section__count { font-size: 13px; color: var(--text-muted); }
|
||||
.project-section__count em { font-style: normal; color: var(--primary-dark); font-weight: 700; }
|
||||
.project-tabs {
|
||||
display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px;
|
||||
padding: 5px; background: #f5f7f7; border-radius: 14px; margin-bottom: 14px;
|
||||
}
|
||||
.project-tab {
|
||||
height: 34px; border: none; border-radius: 10px; background: transparent;
|
||||
color: var(--text-secondary); font-size: 13px; font-weight: 600; cursor: pointer;
|
||||
}
|
||||
.project-tab--active {
|
||||
background: #fff; color: var(--primary-dark);
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.06);
|
||||
}
|
||||
.project-list-panel {
|
||||
max-height: 280px; overflow-y: auto; padding-right: 2px;
|
||||
}
|
||||
.project-list-panel::-webkit-scrollbar { display: none; }
|
||||
.project-list { display: flex; flex-direction: column; gap: 10px; }
|
||||
.project-item {
|
||||
display: flex; align-items: center; gap: 12px; padding: 12px 14px;
|
||||
background: #f9fbfb; border-radius: 14px; border: 1px solid #eef5f5;
|
||||
}
|
||||
.project-item__dot {
|
||||
width: 8px; height: 8px; border-radius: 50%; background: var(--primary); flex-shrink: 0;
|
||||
}
|
||||
.project-item__info { flex: 1; }
|
||||
.project-item__name { font-size: 14px; font-weight: 600; margin-bottom: 2px; }
|
||||
.project-item__desc { font-size: 12px; color: var(--text-muted); }
|
||||
.project-item__price { font-size: 13px; font-weight: 700; color: var(--primary-dark); flex-shrink: 0; }
|
||||
.project-item__badge {
|
||||
display: inline-flex; align-items: center; height: 20px; padding: 0 8px;
|
||||
border-radius: 10px; font-size: 10px; font-weight: 600; flex-shrink: 0;
|
||||
}
|
||||
.project-item__badge--normal { background: #f5f5f5; color: var(--text-muted); }
|
||||
.project-item__badge--key { background: #fff1f0; color: #ff4d4f; }
|
||||
</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-cancelled.html -->
|
||||
<a class="nav-back" href="my-appointments-cancelled.html">‹</a>
|
||||
<span class="nav-title">体检预约详情</span>
|
||||
</div>
|
||||
|
||||
<div class="scroll-content">
|
||||
|
||||
<!-- 预约状态栏 -->
|
||||
<div class="status-bar">
|
||||
<div class="status-bar__left">
|
||||
<div class="status-bar__dot" style="background:#ff4d4f;"></div>
|
||||
<div class="status-bar__text" style="color:#ff4d4f;">已取消</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="summary-card">
|
||||
<div class="section-title">常规体检</div>
|
||||
<div class="summary-list">
|
||||
<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">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>
|
||||
</div>
|
||||
|
||||
<!-- 已选体检项目 -->
|
||||
<div class="project-section">
|
||||
<div class="project-section__header">
|
||||
<div class="section-title" style="margin-bottom:0">已选体检项目</div>
|
||||
<span class="project-section__count">共 <em id="totalCount">14</em> 项</span>
|
||||
</div>
|
||||
<!-- [交互] 点击切换自选项目/必检项目 -->
|
||||
<div class="project-tabs">
|
||||
<button class="project-tab project-tab--active" type="button" data-tab="optional">自选项目(6)</button>
|
||||
<button class="project-tab" type="button" data-tab="required">必检项目(8)</button>
|
||||
</div>
|
||||
<div class="project-list-panel">
|
||||
<div class="project-list" id="projectList"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const projects = [
|
||||
{ name: '一般检查', desc: '身高、体重、血压、视力', price: 120, type: 'required', level: 'normal' },
|
||||
{ name: '血常规', desc: '血红蛋白、白细胞、血小板等', price: 80, type: 'required', level: 'normal' },
|
||||
{ name: '尿常规', desc: '尿蛋白、尿糖、尿潜血等', price: 45, type: 'required', level: 'normal' },
|
||||
{ name: '肝功能', desc: 'ALT、AST、总胆红素等', price: 160, type: 'required', level: 'key' },
|
||||
{ name: '肾功能', desc: '肌酐、尿素氮、尿酸等', price: 110, type: 'required', level: 'key' },
|
||||
{ name: '血脂四项', desc: '总胆固醇、甘油三酯、HDL、LDL', price: 90, type: 'required', level: 'normal' },
|
||||
{ name: '空腹血糖', desc: '空腹静脉血糖检测', price: 40, type: 'required', level: 'normal' },
|
||||
{ name: '心电图', desc: '十二导联心电图检查', price: 75, type: 'required', level: 'key' },
|
||||
{ name: '胸部X光', desc: '胸部正位X线摄影', price: 140, type: 'optional', level: 'normal' },
|
||||
{ name: '腹部彩超', desc: '肝胆脾胰肾彩色超声', price: 180, type: 'optional', level: 'key' },
|
||||
{ name: '甲状腺彩超', desc: '甲状腺彩色多普勒超声', price: 150, type: 'optional', level: 'key' },
|
||||
{ name: '肿瘤标志物', desc: 'AFP、CEA、CA199等', price: 280, type: 'optional', level: 'key' },
|
||||
{ name: '幽门螺杆菌', desc: 'C14呼气试验', price: 120, type: 'optional', level: 'normal' },
|
||||
{ name: '骨密度检测', desc: '超声骨密度检测', price: 100, type: 'optional', level: 'normal' }
|
||||
];
|
||||
|
||||
let activeTab = 'optional';
|
||||
const listEl = document.getElementById('projectList');
|
||||
const tabButtons = document.querySelectorAll('.project-tab');
|
||||
|
||||
function renderProjects() {
|
||||
const filtered = projects.filter(item => item.type === activeTab);
|
||||
listEl.innerHTML = filtered.map(item => {
|
||||
const badgeText = item.level === 'key' ? '重点' : '一般';
|
||||
const badgeClass = item.level === 'key' ? 'project-item__badge--key' : 'project-item__badge--normal';
|
||||
return `
|
||||
<div class="project-item">
|
||||
<div class="project-item__dot"></div>
|
||||
<div class="project-item__info">
|
||||
<div class="project-item__name">${item.name}</div>
|
||||
<div class="project-item__desc">${item.desc}</div>
|
||||
</div>
|
||||
<div class="project-item__price">¥${item.price}</div>
|
||||
<div class="project-item__badge ${badgeClass}">${badgeText}</div>
|
||||
</div>
|
||||
`;
|
||||
}).join('');
|
||||
}
|
||||
|
||||
tabButtons.forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
tabButtons.forEach(item => item.classList.remove('project-tab--active'));
|
||||
btn.classList.add('project-tab--active');
|
||||
activeTab = btn.dataset.tab;
|
||||
renderProjects();
|
||||
});
|
||||
});
|
||||
|
||||
renderProjects();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,668 @@
|
||||
<!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;
|
||||
--success-light: #f6ffed;
|
||||
--success-text: #52c41a;
|
||||
--danger: #ff4d4f;
|
||||
--danger-light: #fff1f0;
|
||||
--text-primary: #1a1a1a;
|
||||
--text-secondary: #666666;
|
||||
--text-muted: #8c8c8c;
|
||||
--border: #e8f3f3;
|
||||
--bg-page: #f0f2f5;
|
||||
--bg-content: #f7f9fb;
|
||||
--shadow: 0 10px 30px 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 180px, #f7f9fb 100%);
|
||||
padding-bottom: 120px;
|
||||
}
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.page-body { padding: 16px; }
|
||||
/* 预约状态栏 */
|
||||
.status-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 14px 16px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.status-bar__left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.status-bar__dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #fa8c16;
|
||||
}
|
||||
.status-bar__text {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #fa8c16;
|
||||
}
|
||||
.status-bar__btn {
|
||||
padding: 6px 14px;
|
||||
border-radius: 999px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
border: 1px solid rgba(255, 77, 79, 0.3);
|
||||
background: var(--danger-light);
|
||||
color: var(--danger);
|
||||
cursor: pointer;
|
||||
}
|
||||
.status-bar__btn--disabled {
|
||||
border: 1px solid #d9d9d9;
|
||||
background: #f5f5f5;
|
||||
color: #bfbfbf;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
/* 确认弹窗 */
|
||||
.confirm-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0,0,0,0.5);
|
||||
z-index: 200;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.confirm-overlay--visible { display: flex; }
|
||||
.confirm-dialog {
|
||||
width: 300px;
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
padding: 24px 20px 18px;
|
||||
text-align: center;
|
||||
}
|
||||
.confirm-dialog__title {
|
||||
font-size: 17px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 14px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.confirm-dialog__info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-bottom: 20px;
|
||||
padding: 12px;
|
||||
background: #f9fbfb;
|
||||
border-radius: 12px;
|
||||
border: 1px solid #f0f5f5;
|
||||
}
|
||||
.confirm-dialog__row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 13px;
|
||||
}
|
||||
.confirm-dialog__label { color: var(--text-muted); }
|
||||
.confirm-dialog__value { color: var(--text-primary); font-weight: 600; }
|
||||
.confirm-dialog__actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
.confirm-dialog__btn {
|
||||
flex: 1;
|
||||
height: 42px;
|
||||
border-radius: 21px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.confirm-dialog__btn--cancel {
|
||||
background: #f5f7fa;
|
||||
color: var(--text-secondary);
|
||||
border: 1px solid #ebeff2;
|
||||
}
|
||||
.confirm-dialog__btn--confirm {
|
||||
background: var(--danger);
|
||||
color: #fff;
|
||||
}
|
||||
.toast {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: rgba(0,0,0,0.76);
|
||||
color: #fff;
|
||||
padding: 14px 24px;
|
||||
border-radius: 12px;
|
||||
font-size: 14px;
|
||||
z-index: 200;
|
||||
text-align: center;
|
||||
max-width: 280px;
|
||||
line-height: 1.6;
|
||||
display: none;
|
||||
}
|
||||
.toast--visible { display: block; }
|
||||
.status-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.24);
|
||||
}
|
||||
.status-card__badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 12px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255,255,255,0.18);
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.status-card__title {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
line-height: 1.25;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.status-card__desc {
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
opacity: 0.92;
|
||||
}
|
||||
.summary-card,
|
||||
.info-card {
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
padding: 18px 16px;
|
||||
margin-top: 14px;
|
||||
margin-top: 14px;
|
||||
box-shadow: var(--shadow);
|
||||
border: 1px solid rgba(19, 194, 194, 0.06);
|
||||
}
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.summary-list,
|
||||
.info-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
}
|
||||
.summary-item,
|
||||
.info-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.summary-item__label,
|
||||
.info-item__label {
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.summary-item__value,
|
||||
.info-item__value {
|
||||
font-size: 14px;
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
text-align: right;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.summary-item--fee {
|
||||
margin-top: 2px;
|
||||
padding: 14px;
|
||||
border-radius: 18px;
|
||||
background: linear-gradient(135deg, #f0fffe 0%, #f7fffd 100%);
|
||||
border: 1px solid #d7f5f3;
|
||||
align-items: center;
|
||||
}
|
||||
.summary-item--fee .summary-item__label {
|
||||
color: var(--primary-dark);
|
||||
font-weight: 600;
|
||||
}
|
||||
.summary-item--fee .summary-item__value {
|
||||
color: var(--primary-dark);
|
||||
font-size: 24px;
|
||||
font-weight: 800;
|
||||
}
|
||||
.person-card {
|
||||
margin-top: 14px;
|
||||
background: linear-gradient(135deg, #ffffff 0%, #f8fffe 100%);
|
||||
border-radius: 20px;
|
||||
padding: 16px;
|
||||
border: 1px solid #e4f7f5;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
.person-card__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.person-card__avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 16px;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #5cdbd3 100%);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.person-card__name {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.person-card__meta {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.tips-card {
|
||||
margin-top: 14px;
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
padding: 16px;
|
||||
border: 1px solid #eef5f5;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
.tips-card__title {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.tips-card__item {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.tips-card__item:last-child { margin-bottom: 0; }
|
||||
.tips-card__dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--primary);
|
||||
margin-top: 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.qrcode-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.qrcode-wrap__img {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid #eef5f5;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
.qrcode-wrap__img:hover { transform: scale(1.04); }
|
||||
.qrcode-wrap__hint {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
/* 二维码放大遮罩 */
|
||||
.qr-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0,0,0,0.6);
|
||||
z-index: 100;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.qr-overlay--visible { display: flex; }
|
||||
.qr-overlay__img {
|
||||
width: 260px;
|
||||
height: 260px;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
|
||||
}
|
||||
/* 体检进度 */
|
||||
.progress-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);
|
||||
}
|
||||
.progress-card__header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.progress-card__title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.progress-card__ratio {
|
||||
font-size: 13px;
|
||||
color: var(--primary-dark);
|
||||
font-weight: 600;
|
||||
}
|
||||
.progress-bar-lg {
|
||||
height: 10px;
|
||||
border-radius: 999px;
|
||||
background: #eef3f3;
|
||||
overflow: hidden;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.progress-bar-lg__fill {
|
||||
height: 100%;
|
||||
border-radius: 999px;
|
||||
background: linear-gradient(90deg, #13c2c2 0%, #5cdbd3 100%);
|
||||
}
|
||||
.project-tabs {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.project-tabs__btn {
|
||||
height: 34px;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
background: #f5f7fa;
|
||||
color: var(--text-secondary);
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.project-tabs__btn--active {
|
||||
background: var(--primary-light);
|
||||
color: var(--primary-dark);
|
||||
box-shadow: inset 0 0 0 1px rgba(19, 194, 194, 0.16);
|
||||
}
|
||||
.project-list { display: flex; flex-direction: column; gap: 8px; }
|
||||
.project-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 12px;
|
||||
border-radius: 14px;
|
||||
background: #f9fbfb;
|
||||
border: 1px solid #f0f5f5;
|
||||
}
|
||||
.project-item__icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
.project-item__icon--done {
|
||||
background: var(--success-light);
|
||||
color: var(--success-text);
|
||||
}
|
||||
.project-item__icon--pending {
|
||||
background: #fff7e6;
|
||||
color: #fa8c16;
|
||||
}
|
||||
.project-item__name {
|
||||
flex: 1;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.project-item__status {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.project-item__status--done { color: var(--success-text); }
|
||||
.project-item__status--pending { color: #fa8c16; }
|
||||
.hidden { display: none !important; }
|
||||
.bottom-actions {
|
||||
position: absolute;
|
||||
left: 16px;
|
||||
right: 16px;
|
||||
bottom: 18px;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
.bottom-actions__btn {
|
||||
flex: 1;
|
||||
height: 48px;
|
||||
border-radius: 24px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.bottom-actions__btn--ghost {
|
||||
background: var(--danger-light);
|
||||
color: var(--danger);
|
||||
border: 1px solid rgba(255, 77, 79, 0.2);
|
||||
}
|
||||
.bottom-actions__btn--primary {
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 10px 20px rgba(19, 194, 194, 0.22);
|
||||
}
|
||||
</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-done.html -->
|
||||
<a class="nav-back" href="my-appointments-done.html">‹</a>
|
||||
<span class="nav-title">体检预约详情</span>
|
||||
</div>
|
||||
|
||||
<div class="scroll-content">
|
||||
|
||||
<!-- 预约状态栏 -->
|
||||
<div class="status-bar">
|
||||
<div class="status-bar__left">
|
||||
<div class="status-bar__dot" style="background:#52c41a;"></div>
|
||||
<div class="status-bar__text" style="color:#52c41a;">已完成</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="summary-card">
|
||||
<div class="section-title">常规体检</div>
|
||||
<div class="summary-list">
|
||||
<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">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>
|
||||
</div>
|
||||
|
||||
<!-- 体检进度 -->
|
||||
<div class="progress-card">
|
||||
<div class="progress-card__header">
|
||||
<div class="progress-card__title">体检进度</div>
|
||||
<div class="progress-card__ratio" id="progressRatio">26 / 26 项</div>
|
||||
</div>
|
||||
<div class="progress-bar-lg"><div class="progress-bar-lg__fill" id="progressFill" style="width: 100%;"></div></div>
|
||||
|
||||
<!-- [交互] 点击切换已检/未检 Tab -->
|
||||
<div class="project-tabs" id="projectTabs">
|
||||
<button class="project-tabs__btn project-tabs__btn--active" type="button" id="tabDone" onclick="switchTab(0)">已检项目 (0)</button>
|
||||
<button class="project-tabs__btn" type="button" id="tabPending" onclick="switchTab(1)">未检项目 (0)</button>
|
||||
</div>
|
||||
|
||||
<!-- 已检项目列表(JS动态生成) -->
|
||||
<div class="project-list" id="doneList"></div>
|
||||
|
||||
<!-- 未检项目列表(默认隐藏,JS动态生成) -->
|
||||
<div class="project-list hidden" id="pendingList"></div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="bottom-actions">-->
|
||||
<!-- <!– [交互] 点击跳转至: my-appointments.html –>-->
|
||||
<!-- <button class="bottom-actions__btn bottom-actions__btn--ghost" onclick="window.location.href='my-appointments.html'">取消预约</button>-->
|
||||
<!-- <!– [交互] 点击跳转至: hospital-checkin.html –>-->
|
||||
<!-- <button class="bottom-actions__btn bottom-actions__btn--primary" onclick="window.location.href='hospital-checkin.html'">到院体检</button>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- 二维码放大遮罩 -->
|
||||
<div class="qr-overlay" id="qrOverlay" onclick="this.classList.remove('qr-overlay--visible')">
|
||||
<svg class="qr-overlay__img" viewBox="0 0 160 160" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="160" height="160" fill="#fff"/>
|
||||
<rect x="12" y="12" width="40" height="40" rx="4" fill="#1a1a1a"/><rect x="18" y="18" width="28" height="28" rx="2" fill="#fff"/><rect x="24" y="24" width="16" height="16" rx="2" fill="#1a1a1a"/>
|
||||
<rect x="108" y="12" width="40" height="40" rx="4" fill="#1a1a1a"/><rect x="114" y="18" width="28" height="28" rx="2" fill="#fff"/><rect x="120" y="24" width="16" height="16" rx="2" fill="#1a1a1a"/>
|
||||
<rect x="12" y="108" width="40" height="40" rx="4" fill="#1a1a1a"/><rect x="18" y="114" width="28" height="28" rx="2" fill="#fff"/><rect x="24" y="120" width="16" height="16" rx="2" fill="#1a1a1a"/>
|
||||
<rect x="60" y="12" width="8" height="8" fill="#1a1a1a"/><rect x="76" y="12" width="8" height="8" fill="#1a1a1a"/><rect x="92" y="12" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="60" y="24" width="8" height="8" fill="#1a1a1a"/><rect x="84" y="24" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="68" y="36" width="8" height="8" fill="#1a1a1a"/><rect x="92" y="36" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="12" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="28" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="44" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="68" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="92" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="108" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="132" y="60" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="20" y="72" width="8" height="8" fill="#1a1a1a"/><rect x="44" y="72" width="8" height="8" fill="#1a1a1a"/><rect x="60" y="72" width="8" height="8" fill="#1a1a1a"/><rect x="84" y="72" width="8" height="8" fill="#1a1a1a"/><rect x="108" y="72" width="8" height="8" fill="#1a1a1a"/><rect x="124" y="72" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="12" y="84" width="8" height="8" fill="#1a1a1a"/><rect x="36" y="84" width="8" height="8" fill="#1a1a1a"/><rect x="60" y="84" width="8" height="8" fill="#1a1a1a"/><rect x="76" y="84" width="8" height="8" fill="#1a1a1a"/><rect x="100" y="84" width="8" height="8" fill="#1a1a1a"/><rect x="140" y="84" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="28" y="96" width="8" height="8" fill="#1a1a1a"/><rect x="52" y="96" width="8" height="8" fill="#1a1a1a"/><rect x="68" y="96" width="8" height="8" fill="#1a1a1a"/><rect x="92" y="96" width="8" height="8" fill="#1a1a1a"/><rect x="116" y="96" width="8" height="8" fill="#1a1a1a"/><rect x="140" y="96" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="60" y="108" width="8" height="8" fill="#1a1a1a"/><rect x="76" y="108" width="8" height="8" fill="#1a1a1a"/><rect x="100" y="108" width="8" height="8" fill="#1a1a1a"/><rect x="124" y="108" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="60" y="120" width="8" height="8" fill="#1a1a1a"/><rect x="84" y="120" width="8" height="8" fill="#1a1a1a"/><rect x="108" y="120" width="8" height="8" fill="#1a1a1a"/><rect x="140" y="120" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="60" y="132" width="8" height="8" fill="#1a1a1a"/><rect x="76" y="132" width="8" height="8" fill="#1a1a1a"/><rect x="92" y="132" width="8" height="8" fill="#1a1a1a"/><rect x="116" y="132" width="8" height="8" fill="#1a1a1a"/><rect x="140" y="132" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="68" y="140" width="8" height="8" fill="#1a1a1a"/><rect x="100" y="140" width="8" height="8" fill="#1a1a1a"/><rect x="132" y="140" width="8" height="8" fill="#1a1a1a"/>
|
||||
</svg>
|
||||
</div>
|
||||
<script>
|
||||
function switchTab(idx) {
|
||||
var btns = document.querySelectorAll('.project-tabs__btn');
|
||||
btns.forEach(function(b) { b.classList.remove('project-tabs__btn--active'); });
|
||||
btns[idx].classList.add('project-tabs__btn--active');
|
||||
document.getElementById('doneList').classList.toggle('hidden', idx !== 0);
|
||||
document.getElementById('pendingList').classList.toggle('hidden', idx !== 1);
|
||||
}
|
||||
|
||||
var totalCount = 26;
|
||||
var doneCount = 26;
|
||||
var allProjects = [
|
||||
'一般检查', '内科', '外科', '眼科检查', '耳鼻喉科', '口腔科',
|
||||
'血常规', '尿常规', '肝功能', '肾功能', '血脂四项', '空腹血糖',
|
||||
'甲状腺功能', '肿瘤标志物', '心电图', '胸部DR', '腹部彩超',
|
||||
'甲状腺彩超', '泌尿系彩超', '心脏彩超', '颈动脉彩超',
|
||||
'骨密度检测', '肺功能', '幽门螺杆菌', '中医体质辨识', '总检报告'
|
||||
];
|
||||
|
||||
function renderItem(name) {
|
||||
return '<div class="project-item">' +
|
||||
'<div class="project-item__icon project-item__icon--done">✓</div>' +
|
||||
'<div class="project-item__name">' + name + '</div>' +
|
||||
'<div class="project-item__status project-item__status--done">已完成</div></div>';
|
||||
}
|
||||
|
||||
document.getElementById('doneList').innerHTML = allProjects.map(function(n) { return renderItem(n); }).join('');
|
||||
document.getElementById('pendingList').innerHTML = '<div class="project-item"><div class="project-item__icon project-item__icon--done">✓</div><div class="project-item__name">当前预约项目已全部完成</div><div class="project-item__status project-item__status--done">完成</div></div>';
|
||||
document.getElementById('tabDone').textContent = '已检项目 (' + doneCount + ')';
|
||||
document.getElementById('tabPending').textContent = '未检项目 (0)';
|
||||
document.getElementById('progressRatio').textContent = doneCount + ' / ' + totalCount + ' 项';
|
||||
document.getElementById('progressFill').style.width = '100%';
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,771 @@
|
||||
<!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;
|
||||
--success-light: #f6ffed;
|
||||
--success-text: #52c41a;
|
||||
--danger: #ff4d4f;
|
||||
--danger-light: #fff1f0;
|
||||
--text-primary: #1a1a1a;
|
||||
--text-secondary: #666666;
|
||||
--text-muted: #8c8c8c;
|
||||
--border: #e8f3f3;
|
||||
--bg-page: #f0f2f5;
|
||||
--bg-content: #f7f9fb;
|
||||
--shadow: 0 10px 30px 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 180px, #f7f9fb 100%);
|
||||
padding-bottom: 120px;
|
||||
}
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.page-body { padding: 16px; }
|
||||
/* 预约状态栏 */
|
||||
.status-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 14px 16px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.status-bar__left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.status-bar__dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: #fa8c16;
|
||||
}
|
||||
.status-bar__text {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #fa8c16;
|
||||
}
|
||||
.status-bar__btn {
|
||||
padding: 6px 14px;
|
||||
border-radius: 999px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
border: 1px solid rgba(255, 77, 79, 0.3);
|
||||
background: var(--danger-light);
|
||||
color: var(--danger);
|
||||
cursor: pointer;
|
||||
}
|
||||
.status-bar__btn--disabled {
|
||||
border: 1px solid #d9d9d9;
|
||||
background: #f5f5f5;
|
||||
color: #bfbfbf;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
/* 确认弹窗 */
|
||||
.confirm-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0,0,0,0.5);
|
||||
z-index: 200;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.confirm-overlay--visible { display: flex; }
|
||||
.confirm-dialog {
|
||||
width: 300px;
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
padding: 24px 20px 18px;
|
||||
text-align: center;
|
||||
}
|
||||
.confirm-dialog__title {
|
||||
font-size: 17px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 14px;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.confirm-dialog__info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
margin-bottom: 20px;
|
||||
padding: 12px;
|
||||
background: #f9fbfb;
|
||||
border-radius: 12px;
|
||||
border: 1px solid #f0f5f5;
|
||||
}
|
||||
.confirm-dialog__row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 13px;
|
||||
}
|
||||
.confirm-dialog__label { color: var(--text-muted); }
|
||||
.confirm-dialog__value { color: var(--text-primary); font-weight: 600; }
|
||||
.confirm-dialog__actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
.confirm-dialog__btn {
|
||||
flex: 1;
|
||||
height: 42px;
|
||||
border-radius: 21px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.confirm-dialog__btn--cancel {
|
||||
background: #f5f7fa;
|
||||
color: var(--text-secondary);
|
||||
border: 1px solid #ebeff2;
|
||||
}
|
||||
.confirm-dialog__btn--confirm {
|
||||
background: var(--danger);
|
||||
color: #fff;
|
||||
}
|
||||
.toast {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: rgba(0,0,0,0.76);
|
||||
color: #fff;
|
||||
padding: 14px 24px;
|
||||
border-radius: 12px;
|
||||
font-size: 14px;
|
||||
z-index: 200;
|
||||
text-align: center;
|
||||
max-width: 280px;
|
||||
line-height: 1.6;
|
||||
display: none;
|
||||
}
|
||||
.toast--visible { display: block; }
|
||||
.status-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.24);
|
||||
}
|
||||
.status-card__badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 6px 12px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255,255,255,0.18);
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.status-card__title {
|
||||
font-size: 24px;
|
||||
font-weight: 700;
|
||||
line-height: 1.25;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.status-card__desc {
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
opacity: 0.92;
|
||||
}
|
||||
.summary-card,
|
||||
.info-card {
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
padding: 18px 16px;
|
||||
margin-top: 14px;
|
||||
margin-top: 14px;
|
||||
box-shadow: var(--shadow);
|
||||
border: 1px solid rgba(19, 194, 194, 0.06);
|
||||
}
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.summary-list,
|
||||
.info-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 14px;
|
||||
}
|
||||
.summary-item,
|
||||
.info-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
.summary-item__label,
|
||||
.info-item__label {
|
||||
font-size: 13px;
|
||||
color: var(--text-muted);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.summary-item__value,
|
||||
.info-item__value {
|
||||
font-size: 14px;
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
text-align: right;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.summary-item--fee {
|
||||
margin-top: 2px;
|
||||
padding: 14px;
|
||||
border-radius: 18px;
|
||||
background: linear-gradient(135deg, #f0fffe 0%, #f7fffd 100%);
|
||||
border: 1px solid #d7f5f3;
|
||||
align-items: center;
|
||||
}
|
||||
.summary-item--fee .summary-item__label {
|
||||
color: var(--primary-dark);
|
||||
font-weight: 600;
|
||||
}
|
||||
.summary-item--fee .summary-item__value {
|
||||
color: var(--primary-dark);
|
||||
font-size: 24px;
|
||||
font-weight: 800;
|
||||
}
|
||||
.person-card {
|
||||
margin-top: 14px;
|
||||
background: linear-gradient(135deg, #ffffff 0%, #f8fffe 100%);
|
||||
border-radius: 20px;
|
||||
padding: 16px;
|
||||
border: 1px solid #e4f7f5;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
.person-card__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.person-card__avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 16px;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #5cdbd3 100%);
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.person-card__name {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.person-card__meta {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.tips-card {
|
||||
margin-top: 14px;
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
padding: 16px;
|
||||
border: 1px solid #eef5f5;
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
.tips-card__title {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.tips-card__item {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.tips-card__item:last-child { margin-bottom: 0; }
|
||||
.tips-card__dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--primary);
|
||||
margin-top: 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.qrcode-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.qrcode-wrap__img {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid #eef5f5;
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
.qrcode-wrap__img:hover { transform: scale(1.04); }
|
||||
.qrcode-wrap__hint {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
/* 二维码放大遮罩 */
|
||||
.qr-overlay {
|
||||
display: none;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0,0,0,0.6);
|
||||
z-index: 100;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.qr-overlay--visible { display: flex; }
|
||||
.qr-overlay__img {
|
||||
width: 260px;
|
||||
height: 260px;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
|
||||
}
|
||||
/* 体检进度 */
|
||||
.progress-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);
|
||||
}
|
||||
.progress-card__header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.progress-card__title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.progress-card__ratio {
|
||||
font-size: 13px;
|
||||
color: var(--primary-dark);
|
||||
font-weight: 600;
|
||||
}
|
||||
.progress-bar-lg {
|
||||
height: 10px;
|
||||
border-radius: 999px;
|
||||
background: #eef3f3;
|
||||
overflow: hidden;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.progress-bar-lg__fill {
|
||||
height: 100%;
|
||||
border-radius: 999px;
|
||||
background: linear-gradient(90deg, #13c2c2 0%, #5cdbd3 100%);
|
||||
}
|
||||
.project-tabs {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.project-tabs__btn {
|
||||
height: 34px;
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
background: #f5f7fa;
|
||||
color: var(--text-secondary);
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.project-tabs__btn--active {
|
||||
background: var(--primary-light);
|
||||
color: var(--primary-dark);
|
||||
box-shadow: inset 0 0 0 1px rgba(19, 194, 194, 0.16);
|
||||
}
|
||||
.project-list { display: flex; flex-direction: column; gap: 8px; }
|
||||
.project-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding: 10px 12px;
|
||||
border-radius: 14px;
|
||||
background: #f9fbfb;
|
||||
border: 1px solid #f0f5f5;
|
||||
}
|
||||
.project-item__icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 8px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-shrink: 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
.project-item__icon--done {
|
||||
background: var(--success-light);
|
||||
color: var(--success-text);
|
||||
}
|
||||
.project-item__icon--pending {
|
||||
background: #fff7e6;
|
||||
color: #fa8c16;
|
||||
}
|
||||
.project-item__name {
|
||||
flex: 1;
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.project-item__status {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.project-item__status--done { color: var(--success-text); }
|
||||
.project-item__status--pending { color: #fa8c16; }
|
||||
.hidden { display: none !important; }
|
||||
.bottom-actions {
|
||||
position: absolute;
|
||||
left: 16px;
|
||||
right: 16px;
|
||||
bottom: 18px;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
.bottom-actions__btn {
|
||||
flex: 1;
|
||||
height: 48px;
|
||||
border-radius: 24px;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.bottom-actions__btn--ghost {
|
||||
background: var(--danger-light);
|
||||
color: var(--danger);
|
||||
border: 1px solid rgba(255, 77, 79, 0.2);
|
||||
}
|
||||
.bottom-actions__btn--primary {
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 10px 20px rgba(19, 194, 194, 0.22);
|
||||
}
|
||||
</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.html -->
|
||||
<a class="nav-back" href="my-appointments.html">‹</a>
|
||||
<span class="nav-title">体检预约详情</span>
|
||||
</div>
|
||||
|
||||
<div class="scroll-content">
|
||||
|
||||
<!-- 预约状态栏 -->
|
||||
<div class="status-bar">
|
||||
<div class="status-bar__left">
|
||||
<div class="status-bar__dot"></div>
|
||||
<div class="status-bar__text">待体检</div>
|
||||
</div>
|
||||
<button class="status-bar__btn status-bar__btn--disabled" id="cancelBtn" disabled>取消预约</button>
|
||||
</div>
|
||||
|
||||
<div class="summary-card">
|
||||
<div class="section-title">常规体检</div>
|
||||
<div class="summary-list">
|
||||
<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">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>
|
||||
</div>
|
||||
|
||||
<div class="person-card">
|
||||
<div class="section-title">体检签到码</div>
|
||||
<div class="qrcode-wrap">
|
||||
<!-- [交互] 点击二维码放大展示 -->
|
||||
<svg class="qrcode-wrap__img" onclick="document.getElementById('qrOverlay').classList.add('qr-overlay--visible')" viewBox="0 0 160 160" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="160" height="160" fill="#fff"/>
|
||||
<!-- 左上定位块 -->
|
||||
<rect x="12" y="12" width="40" height="40" rx="4" fill="#1a1a1a"/>
|
||||
<rect x="18" y="18" width="28" height="28" rx="2" fill="#fff"/>
|
||||
<rect x="24" y="24" width="16" height="16" rx="2" fill="#1a1a1a"/>
|
||||
<!-- 右上定位块 -->
|
||||
<rect x="108" y="12" width="40" height="40" rx="4" fill="#1a1a1a"/>
|
||||
<rect x="114" y="18" width="28" height="28" rx="2" fill="#fff"/>
|
||||
<rect x="120" y="24" width="16" height="16" rx="2" fill="#1a1a1a"/>
|
||||
<!-- 左下定位块 -->
|
||||
<rect x="12" y="108" width="40" height="40" rx="4" fill="#1a1a1a"/>
|
||||
<rect x="18" y="114" width="28" height="28" rx="2" fill="#fff"/>
|
||||
<rect x="24" y="120" width="16" height="16" rx="2" fill="#1a1a1a"/>
|
||||
<!-- 数据区域模拟 -->
|
||||
<rect x="60" y="12" width="8" height="8" fill="#1a1a1a"/><rect x="76" y="12" width="8" height="8" fill="#1a1a1a"/><rect x="92" y="12" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="60" y="24" width="8" height="8" fill="#1a1a1a"/><rect x="84" y="24" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="68" y="36" width="8" height="8" fill="#1a1a1a"/><rect x="92" y="36" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="12" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="28" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="44" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="68" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="92" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="108" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="132" y="60" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="20" y="72" width="8" height="8" fill="#1a1a1a"/><rect x="44" y="72" width="8" height="8" fill="#1a1a1a"/><rect x="60" y="72" width="8" height="8" fill="#1a1a1a"/><rect x="84" y="72" width="8" height="8" fill="#1a1a1a"/><rect x="108" y="72" width="8" height="8" fill="#1a1a1a"/><rect x="124" y="72" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="12" y="84" width="8" height="8" fill="#1a1a1a"/><rect x="36" y="84" width="8" height="8" fill="#1a1a1a"/><rect x="60" y="84" width="8" height="8" fill="#1a1a1a"/><rect x="76" y="84" width="8" height="8" fill="#1a1a1a"/><rect x="100" y="84" width="8" height="8" fill="#1a1a1a"/><rect x="140" y="84" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="28" y="96" width="8" height="8" fill="#1a1a1a"/><rect x="52" y="96" width="8" height="8" fill="#1a1a1a"/><rect x="68" y="96" width="8" height="8" fill="#1a1a1a"/><rect x="92" y="96" width="8" height="8" fill="#1a1a1a"/><rect x="116" y="96" width="8" height="8" fill="#1a1a1a"/><rect x="140" y="96" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="60" y="108" width="8" height="8" fill="#1a1a1a"/><rect x="76" y="108" width="8" height="8" fill="#1a1a1a"/><rect x="100" y="108" width="8" height="8" fill="#1a1a1a"/><rect x="124" y="108" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="60" y="120" width="8" height="8" fill="#1a1a1a"/><rect x="84" y="120" width="8" height="8" fill="#1a1a1a"/><rect x="108" y="120" width="8" height="8" fill="#1a1a1a"/><rect x="140" y="120" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="60" y="132" width="8" height="8" fill="#1a1a1a"/><rect x="76" y="132" width="8" height="8" fill="#1a1a1a"/><rect x="92" y="132" width="8" height="8" fill="#1a1a1a"/><rect x="116" y="132" width="8" height="8" fill="#1a1a1a"/><rect x="140" y="132" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="68" y="140" width="8" height="8" fill="#1a1a1a"/><rect x="100" y="140" width="8" height="8" fill="#1a1a1a"/><rect x="132" y="140" width="8" height="8" fill="#1a1a1a"/>
|
||||
</svg>
|
||||
<span class="qrcode-wrap__hint">点击二维码可放大查看</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 体检进度 -->
|
||||
<div class="progress-card">
|
||||
<div class="progress-card__header">
|
||||
<div class="progress-card__title">体检进度</div>
|
||||
<div class="progress-card__ratio" id="progressRatio">5 / 26 项</div>
|
||||
</div>
|
||||
<div class="progress-bar-lg"><div class="progress-bar-lg__fill" id="progressFill" style="width: 19.2%;"></div></div>
|
||||
|
||||
<!-- [交互] 点击切换已检/未检 Tab -->
|
||||
<div class="project-tabs" id="projectTabs">
|
||||
<button class="project-tabs__btn project-tabs__btn--active" type="button" id="tabDone" onclick="switchTab(0)">已检项目 (0)</button>
|
||||
<button class="project-tabs__btn" type="button" id="tabPending" onclick="switchTab(1)">未检项目 (0)</button>
|
||||
</div>
|
||||
|
||||
<!-- 已检项目列表(JS动态生成) -->
|
||||
<div class="project-list" id="doneList"></div>
|
||||
|
||||
<!-- 未检项目列表(默认隐藏,JS动态生成) -->
|
||||
<div class="project-list hidden" id="pendingList"></div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="bottom-actions">-->
|
||||
<!-- <!– [交互] 点击跳转至: my-appointments.html –>-->
|
||||
<!-- <button class="bottom-actions__btn bottom-actions__btn--ghost" onclick="window.location.href='my-appointments.html'">取消预约</button>-->
|
||||
<!-- <!– [交互] 点击跳转至: hospital-checkin.html –>-->
|
||||
<!-- <button class="bottom-actions__btn bottom-actions__btn--primary" onclick="window.location.href='hospital-checkin.html'">到院体检</button>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- 二维码放大遮罩 -->
|
||||
<div class="qr-overlay" id="qrOverlay" onclick="this.classList.remove('qr-overlay--visible')">
|
||||
<svg class="qr-overlay__img" viewBox="0 0 160 160" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="160" height="160" fill="#fff"/>
|
||||
<rect x="12" y="12" width="40" height="40" rx="4" fill="#1a1a1a"/><rect x="18" y="18" width="28" height="28" rx="2" fill="#fff"/><rect x="24" y="24" width="16" height="16" rx="2" fill="#1a1a1a"/>
|
||||
<rect x="108" y="12" width="40" height="40" rx="4" fill="#1a1a1a"/><rect x="114" y="18" width="28" height="28" rx="2" fill="#fff"/><rect x="120" y="24" width="16" height="16" rx="2" fill="#1a1a1a"/>
|
||||
<rect x="12" y="108" width="40" height="40" rx="4" fill="#1a1a1a"/><rect x="18" y="114" width="28" height="28" rx="2" fill="#fff"/><rect x="24" y="120" width="16" height="16" rx="2" fill="#1a1a1a"/>
|
||||
<rect x="60" y="12" width="8" height="8" fill="#1a1a1a"/><rect x="76" y="12" width="8" height="8" fill="#1a1a1a"/><rect x="92" y="12" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="60" y="24" width="8" height="8" fill="#1a1a1a"/><rect x="84" y="24" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="68" y="36" width="8" height="8" fill="#1a1a1a"/><rect x="92" y="36" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="12" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="28" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="44" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="68" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="92" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="108" y="60" width="8" height="8" fill="#1a1a1a"/><rect x="132" y="60" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="20" y="72" width="8" height="8" fill="#1a1a1a"/><rect x="44" y="72" width="8" height="8" fill="#1a1a1a"/><rect x="60" y="72" width="8" height="8" fill="#1a1a1a"/><rect x="84" y="72" width="8" height="8" fill="#1a1a1a"/><rect x="108" y="72" width="8" height="8" fill="#1a1a1a"/><rect x="124" y="72" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="12" y="84" width="8" height="8" fill="#1a1a1a"/><rect x="36" y="84" width="8" height="8" fill="#1a1a1a"/><rect x="60" y="84" width="8" height="8" fill="#1a1a1a"/><rect x="76" y="84" width="8" height="8" fill="#1a1a1a"/><rect x="100" y="84" width="8" height="8" fill="#1a1a1a"/><rect x="140" y="84" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="28" y="96" width="8" height="8" fill="#1a1a1a"/><rect x="52" y="96" width="8" height="8" fill="#1a1a1a"/><rect x="68" y="96" width="8" height="8" fill="#1a1a1a"/><rect x="92" y="96" width="8" height="8" fill="#1a1a1a"/><rect x="116" y="96" width="8" height="8" fill="#1a1a1a"/><rect x="140" y="96" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="60" y="108" width="8" height="8" fill="#1a1a1a"/><rect x="76" y="108" width="8" height="8" fill="#1a1a1a"/><rect x="100" y="108" width="8" height="8" fill="#1a1a1a"/><rect x="124" y="108" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="60" y="120" width="8" height="8" fill="#1a1a1a"/><rect x="84" y="120" width="8" height="8" fill="#1a1a1a"/><rect x="108" y="120" width="8" height="8" fill="#1a1a1a"/><rect x="140" y="120" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="60" y="132" width="8" height="8" fill="#1a1a1a"/><rect x="76" y="132" width="8" height="8" fill="#1a1a1a"/><rect x="92" y="132" width="8" height="8" fill="#1a1a1a"/><rect x="116" y="132" width="8" height="8" fill="#1a1a1a"/><rect x="140" y="132" width="8" height="8" fill="#1a1a1a"/>
|
||||
<rect x="68" y="140" width="8" height="8" fill="#1a1a1a"/><rect x="100" y="140" width="8" height="8" fill="#1a1a1a"/><rect x="132" y="140" width="8" height="8" fill="#1a1a1a"/>
|
||||
</svg>
|
||||
</div>
|
||||
<script>
|
||||
function switchTab(idx) {
|
||||
var btns = document.querySelectorAll('.project-tabs__btn');
|
||||
btns.forEach(function(b) { b.classList.remove('project-tabs__btn--active'); });
|
||||
btns[idx].classList.add('project-tabs__btn--active');
|
||||
document.getElementById('doneList').classList.toggle('hidden', idx !== 0);
|
||||
document.getElementById('pendingList').classList.toggle('hidden', idx !== 1);
|
||||
}
|
||||
function showToast(msg) {
|
||||
var t = document.getElementById('cancelToast');
|
||||
t.textContent = msg;
|
||||
t.classList.add('toast--visible');
|
||||
setTimeout(function() { t.classList.remove('toast--visible'); }, 2000);
|
||||
}
|
||||
|
||||
// 读取 URL 参数
|
||||
var params = new URLSearchParams(window.location.search);
|
||||
var doneCount = parseInt(params.get('done') || '5', 10);
|
||||
var totalCount = parseInt(params.get('total') || '26', 10);
|
||||
var hospital = params.get('hospital') || '宁夏宝石花医院';
|
||||
var date = params.get('date') || '2026-03-23';
|
||||
|
||||
// 动态更新体检进度
|
||||
var pct = totalCount > 0 ? Math.round(doneCount / totalCount * 1000) / 10 : 0;
|
||||
document.getElementById('progressRatio').textContent = doneCount + ' / ' + totalCount + ' 项';
|
||||
document.getElementById('progressFill').style.width = pct + '%';
|
||||
|
||||
// 全部体检项目池(按常规体检顺序)
|
||||
var allProjects = [
|
||||
'一般检查', '内科', '外科', '眼科检查', '耳鼻喉科', '口腔科',
|
||||
'血常规', '尿常规', '肝功能', '肾功能', '血脂四项', '空腹血糖',
|
||||
'甲状腺功能', '肿瘤标志物', '心电图', '胸部DR', '腹部彩超',
|
||||
'甲状腺彩超', '泌尿系彩超', '心脏彩超', '颈动脉彩超',
|
||||
'骨密度检测', '肺功能', '幽门螺杆菌', '中医体质辨识', '总检报告'
|
||||
];
|
||||
// 取前 totalCount 个项目,前 doneCount 个为已检
|
||||
var projects = allProjects.slice(0, totalCount);
|
||||
var doneProjects = projects.slice(0, doneCount);
|
||||
var pendingProjects = projects.slice(doneCount);
|
||||
|
||||
function renderItem(name, isDone) {
|
||||
return '<div class="project-item">' +
|
||||
'<div class="project-item__icon project-item__icon--' + (isDone ? 'done' : 'pending') + '">' +
|
||||
(isDone ? '✓' : '●') + '</div>' +
|
||||
'<div class="project-item__name">' + name + '</div>' +
|
||||
'<div class="project-item__status project-item__status--' + (isDone ? 'done' : 'pending') + '">' +
|
||||
(isDone ? '已完成' : '未检') + '</div></div>';
|
||||
}
|
||||
|
||||
document.getElementById('doneList').innerHTML = doneProjects.map(function(n) { return renderItem(n, true); }).join('');
|
||||
document.getElementById('pendingList').innerHTML = pendingProjects.map(function(n) { return renderItem(n, false); }).join('');
|
||||
document.getElementById('tabDone').textContent = '已检项目 (' + doneCount + ')';
|
||||
document.getElementById('tabPending').textContent = '未检项目 (' + pendingProjects.length + ')';
|
||||
|
||||
// done=0 时默认显示未检 Tab
|
||||
if (doneCount === 0) {
|
||||
switchTab(1);
|
||||
}
|
||||
|
||||
// 根据进度控制取消按钮状态
|
||||
var cancelBtn = document.getElementById('cancelBtn');
|
||||
if (doneCount > 0) {
|
||||
// 已有体检进度 → 按钮禁用,点击弹 toast
|
||||
cancelBtn.classList.add('status-bar__btn--disabled');
|
||||
cancelBtn.disabled = false;
|
||||
cancelBtn.onclick = function() {
|
||||
showToast('您当前已体检了部分项目,无法取消预约');
|
||||
};
|
||||
} else {
|
||||
// 无体检进度 → 按钮可点击,弹二次确认
|
||||
cancelBtn.classList.remove('status-bar__btn--disabled');
|
||||
cancelBtn.disabled = false;
|
||||
cancelBtn.onclick = function() {
|
||||
document.getElementById('confirmHospital').textContent = hospital;
|
||||
document.getElementById('confirmDate').textContent = date;
|
||||
document.getElementById('confirmOverlay').classList.add('confirm-overlay--visible');
|
||||
};
|
||||
}
|
||||
</script>
|
||||
<div class="toast" id="cancelToast"></div>
|
||||
<!-- 取消预约二次确认弹窗 -->
|
||||
<div class="confirm-overlay" id="confirmOverlay">
|
||||
<div class="confirm-dialog">
|
||||
<div class="confirm-dialog__title">是否确认取消预约</div>
|
||||
<div class="confirm-dialog__info">
|
||||
<div class="confirm-dialog__row">
|
||||
<span class="confirm-dialog__label">体检医院</span>
|
||||
<span class="confirm-dialog__value" id="confirmHospital">宁夏宝石花医院</span>
|
||||
</div>
|
||||
<div class="confirm-dialog__row">
|
||||
<span class="confirm-dialog__label">预约日期</span>
|
||||
<span class="confirm-dialog__value" id="confirmDate">2026-03-23</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="confirm-dialog__actions">
|
||||
<button class="confirm-dialog__btn confirm-dialog__btn--cancel" onclick="document.getElementById('confirmOverlay').classList.remove('confirm-overlay--visible')">再想想</button>
|
||||
<button class="confirm-dialog__btn confirm-dialog__btn--confirm" onclick="window.location.href='my-appointments.html'">确认取消</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,163 @@
|
||||
<!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;
|
||||
--success-bg: #f6ffed;
|
||||
--success-text: #52c41a;
|
||||
--warning-bg: #fff7e6;
|
||||
--warning-text: #fa8c16;
|
||||
--danger-bg: #fff1f0;
|
||||
--danger-text: #ff4d4f;
|
||||
--text-primary: #1a1a1a;
|
||||
--text-secondary: #666666;
|
||||
--text-muted: #8c8c8c;
|
||||
--bg-page: #f0f2f5;
|
||||
--bg-content: #f7f9fb;
|
||||
--border: #e8f3f3;
|
||||
--shadow: 0 10px 24px rgba(19, 194, 194, 0.06);
|
||||
}
|
||||
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, #f0fbfb 0%, #f7f9fb 140px, #f7f9fb 100%);
|
||||
padding: 14px 16px 20px;
|
||||
}
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.tabs {
|
||||
display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; padding: 6px;
|
||||
background: rgba(255,255,255,0.92); border-radius: 18px;
|
||||
box-shadow: 0 8px 20px rgba(19, 194, 194, 0.08);
|
||||
position: sticky; top: 0; z-index: 5; backdrop-filter: blur(10px);
|
||||
}
|
||||
.tabs__item {
|
||||
height: 36px; border: none; border-radius: 14px; background: transparent;
|
||||
color: var(--text-secondary); font-size: 13px; font-weight: 600; cursor: pointer;
|
||||
text-decoration: none; display: flex; align-items: center; justify-content: center;
|
||||
}
|
||||
.tabs__item--active {
|
||||
background: var(--primary-light); color: var(--primary-dark);
|
||||
box-shadow: inset 0 0 0 1px rgba(19, 194, 194, 0.16);
|
||||
}
|
||||
.summary-bar {
|
||||
margin: 14px 0 12px; padding: 16px; border-radius: 20px;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff; box-shadow: 0 12px 24px rgba(19, 194, 194, 0.2);
|
||||
}
|
||||
.summary-bar__title { font-size: 18px; font-weight: 700; margin-bottom: 6px; }
|
||||
.summary-bar__desc { font-size: 13px; line-height: 1.7; opacity: 0.92; }
|
||||
.appointment-list { display: flex; flex-direction: column; gap: 12px; }
|
||||
.appointment-card {
|
||||
background: #fff; border-radius: 20px; padding: 16px;
|
||||
border: 1px solid rgba(19, 194, 194, 0.06); box-shadow: var(--shadow);
|
||||
}
|
||||
.appointment-card__top { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin-bottom: 12px; }
|
||||
.appointment-card__title { font-size: 16px; font-weight: 700; color: var(--text-primary); }
|
||||
.appointment-card__status { flex-shrink: 0; padding: 5px 10px; border-radius: 999px; font-size: 12px; font-weight: 600; }
|
||||
.appointment-card__status--done { background: var(--success-bg); color: var(--success-text); }
|
||||
.appointment-card__meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 12px; margin-bottom: 12px; }
|
||||
.meta-item { background: #f9fbfb; border-radius: 14px; padding: 10px 12px; border: 1px solid #f0f5f5; }
|
||||
.meta-item__label { font-size: 11px; color: var(--text-muted); margin-bottom: 5px; }
|
||||
.meta-item__value { font-size: 13px; color: var(--text-primary); font-weight: 600; line-height: 1.5; }
|
||||
.appointment-card__progress { margin-bottom: 14px; }
|
||||
.progress-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; font-size: 12px; color: var(--text-secondary); }
|
||||
.progress-bar { height: 8px; border-radius: 999px; background: #eef3f3; overflow: hidden; }
|
||||
.progress-bar__fill { height: 100%; border-radius: 999px; background: linear-gradient(90deg, #13c2c2 0%, #5cdbd3 100%); }
|
||||
.appointment-card__actions { display: flex; gap: 10px; }
|
||||
.appointment-card__btn {
|
||||
flex: 1; height: 40px; border-radius: 20px; font-size: 14px; font-weight: 600; border: none; cursor: pointer;
|
||||
}
|
||||
.appointment-card__btn--ghost { background: #f5f7fa; color: var(--text-secondary); border: 1px solid #ebeff2; }
|
||||
</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">
|
||||
<a class="nav-back" href="index.html">‹</a>
|
||||
<span class="nav-title">我的预约</span>
|
||||
</div>
|
||||
<div class="scroll-content">
|
||||
<!-- [交互] 点击 Tab 跳转对应页面 -->
|
||||
<div class="tabs">
|
||||
<a class="tabs__item" href="my-appointments-all.html">全部</a>
|
||||
<a class="tabs__item" href="my-appointments.html">待体检</a>
|
||||
<a class="tabs__item tabs__item--active" href="my-appointments-done.html">已完成</a>
|
||||
<a class="tabs__item" href="my-appointments-cancelled.html">已取消</a>
|
||||
</div>
|
||||
|
||||
<div class="appointment-list">
|
||||
<a class="appointment-card" href="my-appointments-detail-done.html" style="text-decoration:none;color:inherit;">
|
||||
<div class="appointment-card__top">
|
||||
<div class="appointment-card__title">常规体检</div>
|
||||
<div class="appointment-card__status appointment-card__status--done">已完成</div>
|
||||
</div>
|
||||
<div class="appointment-card__meta">
|
||||
<div class="meta-item"><div class="meta-item__label">体检医院</div><div class="meta-item__value">宁夏宝石花医院</div></div>
|
||||
<div class="meta-item"><div class="meta-item__label">预约日期</div><div class="meta-item__value">2026-03-23</div></div>
|
||||
</div>
|
||||
<div class="appointment-card__progress">
|
||||
<div class="progress-head"><span>完成进度</span><span>26/26</span></div>
|
||||
<div class="progress-bar"><div class="progress-bar__fill" style="width: 100%;"></div></div>
|
||||
</div>
|
||||
|
||||
</a>
|
||||
<a class="appointment-card" href="my-appointments-detail-done.html" style="text-decoration:none;color:inherit;">
|
||||
<div class="appointment-card__top">
|
||||
<div class="appointment-card__title">胃肠镜体检</div>
|
||||
<div class="appointment-card__status appointment-card__status--done">已完成</div>
|
||||
</div>
|
||||
<div class="appointment-card__meta">
|
||||
<div class="meta-item"><div class="meta-item__label">体检医院</div><div class="meta-item__value">宁夏宝石花医院</div></div>
|
||||
<div class="meta-item"><div class="meta-item__label">预约日期</div><div class="meta-item__value">2026-02-18</div></div>
|
||||
</div>
|
||||
<div class="appointment-card__progress">
|
||||
<div class="progress-head"><span>完成进度</span><span>2/2</span></div>
|
||||
<div class="progress-bar"><div class="progress-bar__fill" style="width: 100%;"></div></div>
|
||||
</div>
|
||||
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,340 @@
|
||||
<!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;
|
||||
--success-bg: #f6ffed;
|
||||
--success-text: #52c41a;
|
||||
--warning-bg: #fff7e6;
|
||||
--warning-text: #fa8c16;
|
||||
--danger-bg: #fff1f0;
|
||||
--danger-text: #ff4d4f;
|
||||
--text-primary: #1a1a1a;
|
||||
--text-secondary: #666666;
|
||||
--text-muted: #8c8c8c;
|
||||
--bg-page: #f0f2f5;
|
||||
--bg-content: #f7f9fb;
|
||||
--border: #e8f3f3;
|
||||
--shadow: 0 10px 24px rgba(19, 194, 194, 0.06);
|
||||
}
|
||||
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, #f0fbfb 0%, #f7f9fb 140px, #f7f9fb 100%);
|
||||
padding: 14px 16px 20px;
|
||||
}
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.tabs {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 8px;
|
||||
padding: 6px;
|
||||
background: rgba(255,255,255,0.92);
|
||||
border-radius: 18px;
|
||||
box-shadow: 0 8px 20px rgba(19, 194, 194, 0.08);
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 5;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
.tabs__item {
|
||||
height: 36px;
|
||||
border: none;
|
||||
border-radius: 14px;
|
||||
background: transparent;
|
||||
color: var(--text-secondary);
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.tabs__item--active {
|
||||
background: var(--primary-light);
|
||||
color: var(--primary-dark);
|
||||
box-shadow: inset 0 0 0 1px rgba(19, 194, 194, 0.16);
|
||||
}
|
||||
.summary-bar {
|
||||
margin: 14px 0 12px;
|
||||
padding: 16px;
|
||||
border-radius: 20px;
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 12px 24px rgba(19, 194, 194, 0.2);
|
||||
}
|
||||
.summary-bar__title {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.summary-bar__desc {
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
opacity: 0.92;
|
||||
}
|
||||
.appointment-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
.appointment-card {
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
padding: 16px;
|
||||
border: 1px solid rgba(19, 194, 194, 0.06);
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
.appointment-card__top {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.appointment-card__title {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: var(--text-primary);
|
||||
}
|
||||
.appointment-card__status {
|
||||
flex-shrink: 0;
|
||||
padding: 5px 10px;
|
||||
border-radius: 999px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.appointment-card__status--pending {
|
||||
background: var(--warning-bg);
|
||||
color: var(--warning-text);
|
||||
}
|
||||
.appointment-card__status--done {
|
||||
background: var(--success-bg);
|
||||
color: var(--success-text);
|
||||
}
|
||||
.appointment-card__status--cancelled {
|
||||
background: var(--danger-bg);
|
||||
color: var(--danger-text);
|
||||
}
|
||||
.appointment-card__meta {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 10px 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.meta-item {
|
||||
background: #f9fbfb;
|
||||
border-radius: 14px;
|
||||
padding: 10px 12px;
|
||||
border: 1px solid #f0f5f5;
|
||||
}
|
||||
.meta-item__label {
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.meta-item__value {
|
||||
font-size: 13px;
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.appointment-card__progress {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.progress-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 8px;
|
||||
font-size: 12px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
.progress-bar {
|
||||
height: 8px;
|
||||
border-radius: 999px;
|
||||
background: #eef3f3;
|
||||
overflow: hidden;
|
||||
}
|
||||
.progress-bar__fill {
|
||||
height: 100%;
|
||||
border-radius: 999px;
|
||||
background: linear-gradient(90deg, #13c2c2 0%, #5cdbd3 100%);
|
||||
}
|
||||
.appointment-card__actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
}
|
||||
.appointment-card__btn {
|
||||
flex: 1;
|
||||
height: 40px;
|
||||
border-radius: 20px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
.appointment-card__btn--ghost {
|
||||
background: #f5f7fa;
|
||||
color: var(--text-secondary);
|
||||
border: 1px solid #ebeff2;
|
||||
}
|
||||
.appointment-card__btn--primary {
|
||||
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 8px 20px rgba(19, 194, 194, 0.18);
|
||||
}
|
||||
.appointment-card[data-status="done"],
|
||||
.appointment-card[data-status="cancelled"] {
|
||||
opacity: 0.94;
|
||||
}
|
||||
</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">
|
||||
<!-- [交互] 点击返回至: index.html -->
|
||||
<a class="nav-back" href="index.html">‹</a>
|
||||
<span class="nav-title">我的预约</span>
|
||||
</div>
|
||||
|
||||
<div class="scroll-content">
|
||||
<!-- [交互] 点击 Tab 跳转对应页面 -->
|
||||
<div class="tabs">
|
||||
<a class="tabs__item" href="my-appointments-all.html">全部</a>
|
||||
<a class="tabs__item tabs__item--active" href="my-appointments.html">待体检</a>
|
||||
<a class="tabs__item" href="my-appointments-done.html">已完成</a>
|
||||
<a class="tabs__item" href="my-appointments-cancelled.html">已取消</a>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="appointment-list">
|
||||
<!-- [交互] 点击卡片跳转至详情页,URL携带进度/医院/日期参数 -->
|
||||
<a class="appointment-card" data-status="pending" href="my-appointments-detail.html?done=5&total=26&hospital=宁夏宝石花医院&date=2026-03-23" style="text-decoration:none;color:inherit;">
|
||||
<div class="appointment-card__top">
|
||||
<div class="appointment-card__title">常规体检</div>
|
||||
<div class="appointment-card__status appointment-card__status--pending">待体检</div>
|
||||
</div>
|
||||
<div class="appointment-card__meta">
|
||||
<div class="meta-item">
|
||||
<div class="meta-item__label">体检医院</div>
|
||||
<div class="meta-item__value">宁夏宝石花医院</div>
|
||||
</div>
|
||||
<div class="meta-item">
|
||||
<div class="meta-item__label">预约日期</div>
|
||||
<div class="meta-item__value">2026-03-23</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="appointment-card__progress">
|
||||
<div class="progress-head">
|
||||
<span>体检进度</span>
|
||||
<span>5/26</span>
|
||||
</div>
|
||||
<div class="progress-bar"><div class="progress-bar__fill" style="width: 19.2%;"></div></div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<a class="appointment-card" data-status="pending" href="my-appointments-detail.html?done=0&total=26&hospital=宁夏宝石花医院&date=2026-03-23" style="text-decoration:none;color:inherit;">
|
||||
<div class="appointment-card__top">
|
||||
<div class="appointment-card__title">常规体检</div>
|
||||
<div class="appointment-card__status appointment-card__status--pending">待体检</div>
|
||||
</div>
|
||||
<div class="appointment-card__meta">
|
||||
<div class="meta-item">
|
||||
<div class="meta-item__label">体检医院</div>
|
||||
<div class="meta-item__value">宁夏宝石花医院</div>
|
||||
</div>
|
||||
<div class="meta-item">
|
||||
<div class="meta-item__label">预约日期</div>
|
||||
<div class="meta-item__value">2026-03-23</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="appointment-card__progress">
|
||||
<div class="progress-head">
|
||||
<span>体检进度</span>
|
||||
<span>0/26</span>
|
||||
</div>
|
||||
<div class="progress-bar"><div class="progress-bar__fill" style="width: 0%;"></div></div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,215 @@
|
||||
<!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 30px 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; }
|
||||
.scroll-content {
|
||||
flex: 1; overflow-y: auto; background: #f7f9fb;
|
||||
}
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
/* 顶部项目图片 */
|
||||
.detail-hero {
|
||||
width: 100%; height: 220px; background: linear-gradient(135deg, #e0f7fa 0%, #b2dfdb 50%, #80cbc4 100%);
|
||||
display: flex; align-items: center; justify-content: center; position: relative;
|
||||
}
|
||||
.detail-hero__icon {
|
||||
width: 80px; height: 80px; border-radius: 24px;
|
||||
background: rgba(255,255,255,0.85); display: flex; align-items: center; justify-content: center;
|
||||
box-shadow: 0 8px 24px rgba(0,0,0,0.08);
|
||||
}
|
||||
.detail-hero__icon svg { width: 40px; height: 40px; color: var(--primary-dark); }
|
||||
/* 内容区 */
|
||||
.detail-body { padding: 20px 16px 32px; }
|
||||
.detail-name {
|
||||
font-size: 22px; font-weight: 800; color: var(--text-primary); margin-bottom: 6px;
|
||||
}
|
||||
.detail-meta {
|
||||
display: flex; gap: 10px; align-items: center; margin-bottom: 18px;
|
||||
}
|
||||
.detail-badge {
|
||||
display: inline-flex; align-items: center; height: 24px; padding: 0 12px;
|
||||
border-radius: 12px; font-size: 12px; font-weight: 600;
|
||||
}
|
||||
.detail-badge--normal { background: #f5f5f5; color: var(--text-muted); }
|
||||
.detail-badge--key { background: #fff1f0; color: #ff4d4f; }
|
||||
.detail-price { font-size: 18px; font-weight: 800; color: var(--primary-dark); }
|
||||
/* 卡片通用 */
|
||||
.detail-card {
|
||||
background: #fff; border-radius: 20px; padding: 18px 16px; margin-bottom: 14px;
|
||||
box-shadow: var(--shadow); border: 1px solid rgba(19,194,194,0.06);
|
||||
}
|
||||
.detail-card__title {
|
||||
font-size: 16px; font-weight: 700; color: var(--text-primary); margin-bottom: 12px;
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
}
|
||||
.detail-card__title-dot {
|
||||
width: 4px; height: 18px; border-radius: 2px; background: var(--primary);
|
||||
}
|
||||
.detail-card__text {
|
||||
font-size: 14px; color: var(--text-secondary); line-height: 1.8;
|
||||
}
|
||||
/* 视频播放器占位 */
|
||||
.video-section { margin-bottom: 16px; }
|
||||
.video-section:last-child { margin-bottom: 0; }
|
||||
.video-section__label {
|
||||
font-size: 14px; font-weight: 600; color: var(--text-primary); margin-bottom: 10px;
|
||||
display: flex; align-items: center; gap: 6px;
|
||||
}
|
||||
.video-section__label-icon { color: var(--primary); }
|
||||
.video-player {
|
||||
width: 100%; height: 180px; border-radius: 16px; overflow: hidden;
|
||||
background: #1a1a1a; position: relative; display: flex; align-items: center; justify-content: center;
|
||||
}
|
||||
.video-player__poster {
|
||||
position: absolute; inset: 0;
|
||||
background: linear-gradient(135deg, #2a2a2a 0%, #3a3a3a 100%);
|
||||
}
|
||||
.video-player__play {
|
||||
width: 56px; height: 56px; border-radius: 50%; border: none; cursor: pointer;
|
||||
background: rgba(255,255,255,0.2); backdrop-filter: blur(8px);
|
||||
display: flex; align-items: center; justify-content: center; position: relative; z-index: 1;
|
||||
transition: transform 0.2s, background 0.2s;
|
||||
}
|
||||
.video-player__play:hover { transform: scale(1.08); background: rgba(255,255,255,0.3); }
|
||||
.video-player__play svg { color: #fff; }
|
||||
.video-player__duration {
|
||||
position: absolute; bottom: 10px; right: 12px; font-size: 12px; color: rgba(255,255,255,0.7);
|
||||
z-index: 1;
|
||||
}
|
||||
</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">
|
||||
<a class="nav-back" onclick="history.back()">‹</a>
|
||||
<span class="nav-title">项目详情</span>
|
||||
</div>
|
||||
<div class="scroll-content" id="scrollContent"></div>
|
||||
</div>
|
||||
<script>
|
||||
const projects = {
|
||||
general: { name: '一般检查', desc: '身高、体重、血压、视力', price: 120, level: 'normal',
|
||||
intro: '一般检查是健康体检的基础项目,通过测量身高、体重、体质指数(BMI)、血压、脉搏及视力等基本生理指标,初步评估受检者的整体健康状况,为后续专项检查提供参考依据。',
|
||||
videos: { before: '03:25', after: '02:18', faq: '04:12' } },
|
||||
blood: { name: '血常规', desc: '血红蛋白、白细胞、血小板等', price: 80, level: 'normal',
|
||||
intro: '血常规检查通过采集静脉血样本,分析红细胞、白细胞、血小板等血液成分的数量和形态,是筛查贫血、感染、血液系统疾病等的重要基础检查项目。',
|
||||
videos: { before: '02:50', after: '03:05', faq: '03:40' } },
|
||||
urine: { name: '尿常规', desc: '尿蛋白、尿糖、尿潜血等', price: 45, level: 'normal',
|
||||
intro: '尿常规检查通过分析尿液中的蛋白质、糖分、潜血、白细胞等成分,辅助筛查泌尿系统疾病、糖尿病、肾脏疾病等,是临床常用的基础检验项目。',
|
||||
videos: { before: '02:15', after: '01:58', faq: '03:10' } },
|
||||
liver: { name: '肝功能', desc: 'ALT、AST、总胆红素等', price: 160, level: 'key',
|
||||
intro: '肝功能检查通过检测血清中谷丙转氨酶(ALT)、谷草转氨酶(AST)、总胆红素、白蛋白等指标,评估肝脏的代谢、合成和解毒功能,是肝脏疾病筛查的核心项目。',
|
||||
videos: { before: '03:45', after: '02:30', faq: '04:20' } },
|
||||
kidney: { name: '肾功能', desc: '肌酐、尿素氮、尿酸等', price: 110, level: 'key',
|
||||
intro: '肾功能检查通过检测血清肌酐、尿素氮、尿酸等指标,评估肾脏的滤过和排泄功能,早期发现肾脏损伤和代谢异常,对高血压、糖尿病患者尤为重要。',
|
||||
videos: { before: '03:10', after: '02:45', faq: '03:55' } },
|
||||
lipid: { name: '血脂四项', desc: '总胆固醇、甘油三酯、HDL、LDL', price: 90, level: 'normal',
|
||||
intro: '血脂四项检查包括总胆固醇、甘油三酯、高密度脂蛋白胆固醇(HDL-C)和低密度脂蛋白胆固醇(LDL-C),是评估心脑血管疾病风险的关键指标。',
|
||||
videos: { before: '02:40', after: '03:15', faq: '04:00' } },
|
||||
glucose: { name: '空腹血糖', desc: '空腹静脉血糖检测', price: 40, level: 'normal',
|
||||
intro: '空腹血糖检测要求受检者空腹8-12小时后采集静脉血,测定血液中葡萄糖浓度,是筛查糖尿病和糖耐量异常的首选检查方法。',
|
||||
videos: { before: '02:20', after: '01:50', faq: '03:30' } },
|
||||
ecg: { name: '心电图', desc: '十二导联心电图检查', price: 75, level: 'key',
|
||||
intro: '十二导联心电图通过记录心脏电活动,检测心律失常、心肌缺血、心肌梗死等心脏疾病,是心血管系统筛查的基础且不可替代的检查手段。',
|
||||
videos: { before: '03:00', after: '02:25', faq: '04:35' } },
|
||||
xray: { name: '胸部X光', desc: '胸部正位X线摄影', price: 140, level: 'normal',
|
||||
intro: '胸部X光检查通过X射线成像技术,观察肺部、心脏、纵隔及胸廓骨骼结构,筛查肺炎、肺结核、肺部肿瘤、心脏增大等胸部疾病。',
|
||||
videos: { before: '02:55', after: '02:10', faq: '03:45' } },
|
||||
ultrasound: { name: '腹部B超', desc: '肝胆脾胰肾超声检查', price: 180, level: 'key',
|
||||
intro: '腹部B超利用超声波成像技术,对肝脏、胆囊、脾脏、胰腺和双肾进行无创检查,可发现结石、囊肿、肿瘤等器质性病变,是腹部脏器筛查的首选方法。',
|
||||
videos: { before: '03:30', after: '02:00', faq: '04:10' } },
|
||||
thyroid: { name: '甲状腺彩超', desc: '甲状腺结构与结节筛查', price: 160, level: 'key',
|
||||
intro: '甲状腺彩超通过高频超声探头检查甲状腺的大小、形态、内部回声及血流情况,是筛查甲状腺结节、甲状腺肿大、甲状腺炎等疾病的重要影像学手段。',
|
||||
videos: { before: '02:35', after: '01:45', faq: '03:20' } },
|
||||
tumor: { name: '肿瘤标志物', desc: '基础肿瘤风险筛查', price: 220, level: 'key',
|
||||
intro: '肿瘤标志物检查通过检测血清中特定蛋白质或代谢产物的浓度,辅助筛查常见恶性肿瘤风险。本项目包含AFP、CEA、CA199等基础肿瘤标志物组合。',
|
||||
videos: { before: '04:00', after: '03:20', faq: '05:15' } }
|
||||
};
|
||||
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const projectId = params.get('id') || 'general';
|
||||
const p = projects[projectId] || projects.general;
|
||||
|
||||
const playIcon = `<svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>`;
|
||||
const videoIcon = `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2" ry="2"/></svg>`;
|
||||
|
||||
function renderVideo(label, duration) {
|
||||
return `<div class="video-section">
|
||||
<div class="video-section__label"><span class="video-section__label-icon">${videoIcon}</span>${label}</div>
|
||||
<div class="video-player">
|
||||
<div class="video-player__poster"></div>
|
||||
<button class="video-player__play">${playIcon}</button>
|
||||
<span class="video-player__duration">${duration}</span>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
document.getElementById('scrollContent').innerHTML = `
|
||||
<div class="detail-hero">
|
||||
<div class="detail-hero__icon">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M22 12h-4l-3 9L9 3l-3 9H2"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-body">
|
||||
<div class="detail-name">${p.name}</div>
|
||||
<div class="detail-meta">
|
||||
<span class="detail-badge detail-badge--${p.level === 'key' ? 'key' : 'normal'}">${p.level === 'key' ? '重点项目' : '一般项目'}</span>
|
||||
<span class="detail-price">¥${p.price.toFixed(2)}</span>
|
||||
</div>
|
||||
<div class="detail-card">
|
||||
<div class="detail-card__title"><span class="detail-card__title-dot"></span>项目介绍</div>
|
||||
<div class="detail-card__text">${p.intro}</div>
|
||||
</div>
|
||||
<div class="detail-card">
|
||||
<div class="detail-card__title"><span class="detail-card__title-dot"></span>体检说明</div>
|
||||
${renderVideo('检前说明', p.videos.before)}
|
||||
${renderVideo('检后说明', p.videos.after)}
|
||||
${renderVideo('问题说明', p.videos.faq)}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,742 @@
|
||||
<!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: #20c7c7;
|
||||
--primary-dark: #119b9b;
|
||||
--primary-light: #e8fbfb;
|
||||
--border: #cfeeee;
|
||||
--line: #dff3f3;
|
||||
--bg-page: #f0f2f5;
|
||||
--bg-content: #f6fbfb;
|
||||
--text-primary: #1a1a1a;
|
||||
--text-secondary: #666;
|
||||
--text-muted: #8c8c8c;
|
||||
--danger: #ff4d4f;
|
||||
--danger-light: #fff1f0;
|
||||
--warning: #fa8c16;
|
||||
--success: #52c41a;
|
||||
--paper-shadow: 0 8px 24px rgba(17, 155, 155, 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);
|
||||
}
|
||||
.nav-action {
|
||||
margin-left: auto;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 12px;
|
||||
color: var(--primary-dark);
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
}
|
||||
.scroll-content {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
background: linear-gradient(180deg, #ecfbfb 0%, #f7fbfb 160px, #f7fbfb 100%);
|
||||
}
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.page-body { padding: 14px; }
|
||||
.report-paper {
|
||||
background: #fff;
|
||||
border-radius: 20px;
|
||||
box-shadow: var(--paper-shadow);
|
||||
border: 1px solid rgba(32, 199, 199, 0.08);
|
||||
overflow: hidden;
|
||||
}
|
||||
.report-header {
|
||||
padding: 18px 16px 14px;
|
||||
background: linear-gradient(180deg, #fbffff 0%, #f4ffff 100%);
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
.report-header__top {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.report-header__title {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 1px;
|
||||
color: #0f7d7d;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.report-header__sub {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
line-height: 1.6;
|
||||
}
|
||||
.report-status {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 62px;
|
||||
height: 28px;
|
||||
padding: 0 10px;
|
||||
border-radius: 14px;
|
||||
background: #f6ffed;
|
||||
color: var(--success);
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.summary-strip {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 8px;
|
||||
}
|
||||
.summary-strip__item {
|
||||
background: var(--primary-light);
|
||||
border-radius: 14px;
|
||||
padding: 10px 8px;
|
||||
text-align: center;
|
||||
}
|
||||
.summary-strip__label {
|
||||
font-size: 11px;
|
||||
color: var(--text-muted);
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.summary-strip__value {
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
color: var(--primary-dark);
|
||||
}
|
||||
.basic-info {
|
||||
padding: 10px 16px 2px;
|
||||
}
|
||||
.basic-info__title,
|
||||
.report-section__title,
|
||||
.conclusion-card__title {
|
||||
height: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 12px;
|
||||
margin: 0 -16px 12px;
|
||||
background: linear-gradient(90deg, #78e3e3 0%, #a4eded 100%);
|
||||
color: #0c7070;
|
||||
font-size: 13px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.5px;
|
||||
}
|
||||
.basic-info__grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
column-gap: 12px;
|
||||
row-gap: 10px;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
.basic-info__item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
min-width: 0;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.basic-info__label {
|
||||
color: var(--text-muted);
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.basic-info__value {
|
||||
color: var(--text-primary);
|
||||
font-weight: 600;
|
||||
min-width: 0;
|
||||
word-break: break-all;
|
||||
}
|
||||
.report-section {
|
||||
padding: 12px 16px 0;
|
||||
}
|
||||
.insight-cards {
|
||||
padding: 14px 16px 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
}
|
||||
.insight-card {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 16px;
|
||||
background: linear-gradient(180deg, #fdffff 0%, #f8ffff 100%);
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 16px rgba(17, 155, 155, 0.05);
|
||||
}
|
||||
.insight-card__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
padding: 12px 12px 10px;
|
||||
}
|
||||
.insight-card__title {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: #0d7878;
|
||||
}
|
||||
.insight-card__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.insight-card__voice {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid #c7eded;
|
||||
background: #fff;
|
||||
color: var(--primary-dark);
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
}
|
||||
.insight-card__voice svg { width: 18px; height: 18px; }
|
||||
.insight-card__voice.is-playing {
|
||||
background: var(--primary);
|
||||
border-color: var(--primary);
|
||||
color: #fff;
|
||||
}
|
||||
.insight-card__content {
|
||||
position: relative;
|
||||
padding: 0 12px 12px;
|
||||
}
|
||||
.insight-card__text {
|
||||
font-size: 12px;
|
||||
line-height: 1.8;
|
||||
color: #4d4d4d;
|
||||
max-height: 64px;
|
||||
overflow: hidden;
|
||||
transition: max-height 0.25s ease;
|
||||
}
|
||||
.insight-card.is-expanded .insight-card__text {
|
||||
max-height: 320px;
|
||||
}
|
||||
.insight-card__fade {
|
||||
position: absolute;
|
||||
left: 12px;
|
||||
right: 12px;
|
||||
bottom: 40px;
|
||||
height: 28px;
|
||||
background: linear-gradient(180deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.96) 100%);
|
||||
pointer-events: none;
|
||||
}
|
||||
.insight-card.is-expanded .insight-card__fade {
|
||||
display: none;
|
||||
}
|
||||
.insight-card__toggle {
|
||||
margin-top: 10px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
border: none;
|
||||
background: transparent;
|
||||
color: var(--primary-dark);
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
}
|
||||
.report-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
table-layout: fixed;
|
||||
margin-bottom: 12px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.report-table th,
|
||||
.report-table td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 7px 6px;
|
||||
font-size: 11px;
|
||||
line-height: 1.45;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
word-break: break-word;
|
||||
}
|
||||
.report-table th {
|
||||
background: #f2ffff;
|
||||
color: #0e7f7f;
|
||||
font-weight: 700;
|
||||
}
|
||||
.report-table td:first-child,
|
||||
.report-table th:first-child {
|
||||
text-align: left;
|
||||
padding-left: 8px;
|
||||
}
|
||||
.report-table__hint {
|
||||
color: var(--text-muted);
|
||||
}
|
||||
.is-high,
|
||||
.is-low,
|
||||
.is-warn {
|
||||
color: var(--danger);
|
||||
font-weight: 700;
|
||||
}
|
||||
.flag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 24px;
|
||||
height: 18px;
|
||||
padding: 0 6px;
|
||||
border-radius: 9px;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
}
|
||||
.flag--normal {
|
||||
background: #f6ffed;
|
||||
color: var(--success);
|
||||
}
|
||||
.flag--warn {
|
||||
background: var(--danger-light);
|
||||
color: var(--danger);
|
||||
}
|
||||
.conclusion-wrap {
|
||||
padding: 12px 16px 18px;
|
||||
}
|
||||
.conclusion-card {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
.conclusion-card__box {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 14px;
|
||||
background: #fbffff;
|
||||
padding: 12px;
|
||||
font-size: 12px;
|
||||
line-height: 1.8;
|
||||
color: #444;
|
||||
}
|
||||
.back-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6px;
|
||||
width: 100%;
|
||||
height: 46px;
|
||||
border: none;
|
||||
border-radius: 23px;
|
||||
background: linear-gradient(135deg, #13c2c2, #36cfc9);
|
||||
color: #fff;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
box-shadow: 0 8px 20px rgba(19, 194, 194, 0.22);
|
||||
}
|
||||
.bottom-spacer { height: 20px; }
|
||||
</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="location.href='reports.html'">‹</span>
|
||||
<span class="nav-title">报告查询</span>
|
||||
<a class="nav-action" href="javascript:void(0)">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
|
||||
下载
|
||||
</a>
|
||||
</div>
|
||||
<div class="scroll-content">
|
||||
<div class="page-body">
|
||||
<div class="report-paper">
|
||||
<div class="report-header">
|
||||
<div class="report-header__top">
|
||||
<div>
|
||||
<div class="report-header__title">2025年体检报告</div>
|
||||
<div class="report-header__sub">姓名:张旭
|
||||
<br>性别:男
|
||||
<br>年龄:32
|
||||
<br>身份证号:430626198503250024
|
||||
<br>体检日期:2025-03-21
|
||||
<br>体检医院:宁夏宝石花医院健康管理中心
|
||||
</div>
|
||||
</div>
|
||||
<div class="report-status">已出报告</div>
|
||||
</div>
|
||||
<!-- <div class="summary-strip">-->
|
||||
<!-- <div class="summary-strip__item">-->
|
||||
<!-- <div class="summary-strip__label">总体状态</div>-->
|
||||
<!-- <div class="summary-strip__value">已完成</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="summary-strip__item">-->
|
||||
<!-- <div class="summary-strip__label">异常项</div>-->
|
||||
<!-- <div class="summary-strip__value">6 项</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="summary-strip__item">-->
|
||||
<!-- <div class="summary-strip__label">体检日期</div>-->
|
||||
<!-- <div class="summary-strip__value">03-15</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
|
||||
<div class="insight-cards">
|
||||
<div class="insight-card" id="reportInterpretationCard">
|
||||
<div class="insight-card__header">
|
||||
<div class="insight-card__title">体检报告解读</div>
|
||||
</div>
|
||||
<div class="insight-card__content">
|
||||
<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>
|
||||
|
||||
<div class="insight-card" id="reportConclusionCard">
|
||||
<div class="insight-card__header">
|
||||
<div class="insight-card__title">体检结论</div>
|
||||
<div class="insight-card__actions">
|
||||
<!-- [交互] 点击切换语音播报按钮状态 -->
|
||||
<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>
|
||||
<div class="insight-card__content">
|
||||
<div class="insight-card__text">
|
||||
体检结论显示:BMI 偏高,提示目前处于超重状态;尿酸偏高,需警惕高嘌呤饮食带来的持续影响;血脂中总胆固醇、甘油三酯、低密度脂蛋白存在升高情况,属于代谢类指标异常;彩超提示轻度脂肪肝;颈椎影像提示生理曲度变直。其余血常规、尿常规、血糖、肝功能、甲状腺功能、肿瘤标志物及心电图结果总体平稳。
|
||||
</div>
|
||||
<div class="insight-card__fade"></div>
|
||||
<!-- [交互] 点击展开/收起体检结论 -->
|
||||
<button class="insight-card__toggle" type="button" onclick="toggleInsight('reportConclusionCard', this)">展开</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="insight-card" id="reportAdviceCard">
|
||||
<div class="insight-card__header">
|
||||
<div class="insight-card__title">体检建议</div>
|
||||
<div class="insight-card__actions">
|
||||
<!-- [交互] 点击切换语音播报按钮状态 -->
|
||||
<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>
|
||||
<div class="insight-card__content">
|
||||
<div class="insight-card__text">
|
||||
建议近期以减重和代谢指标管理为重点:控制油炸食品、动物内脏、甜食和夜宵摄入,增加蔬菜、粗粮和优质蛋白比例;每周保持不少于 150 分钟中等强度有氧运动,并增加颈肩拉伸训练;每日足量饮水,减少含糖饮料和酒精;保持规律作息,避免长期伏案和久坐;建议 3 个月后复查血脂、尿酸、肝脏彩超等相关项目,动态观察改善情况。
|
||||
</div>
|
||||
<div class="insight-card__fade"></div>
|
||||
<!-- [交互] 点击展开/收起体检建议 -->
|
||||
<button class="insight-card__toggle" type="button" onclick="toggleInsight('reportAdviceCard', this)">展开</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="report-section">
|
||||
<div class="report-section__title">一般检查</div>
|
||||
<table class="report-table">
|
||||
<thead>
|
||||
<tr><th style="width:30%">项目</th><th style="width:24%">结果</th><th style="width:18%">单位</th><th style="width:28%">参考值</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>身高</td><td>163</td><td>cm</td><td>--</td></tr>
|
||||
<tr><td>体重</td><td>68.5</td><td>kg</td><td>--</td></tr>
|
||||
<tr><td>BMI</td><td class="is-high">25.8 ↑</td><td>kg/m²</td><td>18.5-23.9</td></tr>
|
||||
<tr><td>收缩压</td><td>120</td><td>mmHg</td><td>90-139</td></tr>
|
||||
<tr><td>舒张压</td><td>78</td><td>mmHg</td><td>60-89</td></tr>
|
||||
<tr><td>脉搏</td><td>76</td><td>次/分</td><td>60-100</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="report-section">
|
||||
<div class="report-section__title">内科</div>
|
||||
<table class="report-table">
|
||||
<thead>
|
||||
<tr><th>项目</th><th>检查结果</th><th>单位</th><th>参考值</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>心率</td><td>76</td><td>次/分</td><td>60-100</td></tr>
|
||||
<tr><td>心律</td><td>齐</td><td>--</td><td>--</td></tr>
|
||||
<tr><td>心音</td><td>未见异常</td><td>--</td><td>--</td></tr>
|
||||
<tr><td>呼吸系统</td><td>双肺呼吸音清</td><td>--</td><td>--</td></tr>
|
||||
<tr><td>腹部触诊</td><td>未见异常</td><td>--</td><td>--</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="report-section">
|
||||
<div class="report-section__title">外科</div>
|
||||
<table class="report-table">
|
||||
<thead>
|
||||
<tr><th>项目</th><th>检查结果</th><th>单位</th><th>参考值</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>甲状腺</td><td>未触及肿大</td><td>--</td><td>--</td></tr>
|
||||
<tr><td>浅表淋巴结</td><td>未见异常</td><td>--</td><td>--</td></tr>
|
||||
<tr><td>脊柱</td><td>未见异常</td><td>--</td><td>--</td></tr>
|
||||
<tr><td>四肢关节</td><td>活动可</td><td>--</td><td>--</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="report-section">
|
||||
<div class="report-section__title">血常规</div>
|
||||
<table class="report-table">
|
||||
<thead>
|
||||
<tr><th style="width:32%">项目</th><th style="width:22%">结果</th><th style="width:18%">单位</th><th style="width:28%">参考范围</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>白细胞计数 WBC</td><td>6.80</td><td>10^9/L</td><td>3.5-9.5</td></tr>
|
||||
<tr><td>红细胞计数 RBC</td><td>4.52</td><td>10^12/L</td><td>3.8-5.1</td></tr>
|
||||
<tr><td>血红蛋白 HGB</td><td>136</td><td>g/L</td><td>115-150</td></tr>
|
||||
<tr><td>红细胞压积 HCT</td><td>40.5</td><td>%</td><td>35-45</td></tr>
|
||||
<tr><td>血小板计数 PLT</td><td>248</td><td>10^9/L</td><td>125-350</td></tr>
|
||||
<tr><td>中性粒细胞比率</td><td>58.6</td><td>%</td><td>40-75</td></tr>
|
||||
<tr><td>淋巴细胞比率</td><td>33.2</td><td>%</td><td>20-50</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="report-section">
|
||||
<div class="report-section__title">尿常规</div>
|
||||
<table class="report-table">
|
||||
<thead>
|
||||
<tr><th>项目</th><th>结果</th><th>单位</th><th>参考范围</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>尿蛋白 PRO</td><td>阴性</td><td>--</td><td>阴性</td></tr>
|
||||
<tr><td>尿糖 GLU</td><td>阴性</td><td>--</td><td>阴性</td></tr>
|
||||
<tr><td>酮体 KET</td><td>阴性</td><td>--</td><td>阴性</td></tr>
|
||||
<tr><td>潜血 BLD</td><td>阴性</td><td>--</td><td>阴性</td></tr>
|
||||
<tr><td>白细胞 LEU</td><td>阴性</td><td>--</td><td>阴性</td></tr>
|
||||
<tr><td>尿比重 SG</td><td>1.020</td><td>--</td><td>1.005-1.030</td></tr>
|
||||
<tr><td>尿酸碱度 pH</td><td>6.0</td><td>--</td><td>5.0-8.0</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="report-section">
|
||||
<div class="report-section__title">肝功能</div>
|
||||
<table class="report-table">
|
||||
<thead>
|
||||
<tr><th>项目</th><th>结果</th><th>单位</th><th>参考范围</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>丙氨酸氨基转移酶 ALT</td><td>24.6</td><td>U/L</td><td>7-40</td></tr>
|
||||
<tr><td>天门冬氨酸氨基转移酶 AST</td><td>22.4</td><td>U/L</td><td>13-35</td></tr>
|
||||
<tr><td>总蛋白 TP</td><td>74.8</td><td>g/L</td><td>65-85</td></tr>
|
||||
<tr><td>白蛋白 ALB</td><td>44.2</td><td>g/L</td><td>40-55</td></tr>
|
||||
<tr><td>总胆红素 TBIL</td><td>12.1</td><td>μmol/L</td><td>5-21</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="report-section">
|
||||
<div class="report-section__title">肾功能</div>
|
||||
<table class="report-table">
|
||||
<thead>
|
||||
<tr><th>项目</th><th>结果</th><th>单位</th><th>参考范围</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>尿素 UREA</td><td>4.8</td><td>mmol/L</td><td>2.8-7.2</td></tr>
|
||||
<tr><td>肌酐 CREA</td><td>71</td><td>μmol/L</td><td>41-73</td></tr>
|
||||
<tr><td>尿酸 UA</td><td class="is-high">389 ↑</td><td>μmol/L</td><td>155-357</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="report-section">
|
||||
<div class="report-section__title">血脂</div>
|
||||
<table class="report-table">
|
||||
<thead>
|
||||
<tr><th>项目</th><th>结果</th><th>单位</th><th>参考范围</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>总胆固醇 TC</td><td class="is-high">6.10 ↑</td><td>mmol/L</td><td>3.1-5.7</td></tr>
|
||||
<tr><td>甘油三酯 TG</td><td class="is-high">2.08 ↑</td><td>mmol/L</td><td>0.4-1.7</td></tr>
|
||||
<tr><td>高密度脂蛋白 HDL-C</td><td>1.18</td><td>mmol/L</td><td>1.04-1.55</td></tr>
|
||||
<tr><td>低密度脂蛋白 LDL-C</td><td class="is-high">3.92 ↑</td><td>mmol/L</td><td>0-3.4</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="report-section">
|
||||
<div class="report-section__title">血糖</div>
|
||||
<table class="report-table">
|
||||
<thead>
|
||||
<tr><th>项目</th><th>结果</th><th>单位</th><th>参考范围</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>空腹血糖 GLU</td><td>5.20</td><td>mmol/L</td><td>3.9-6.1</td></tr>
|
||||
<tr><td>糖化血红蛋白 HbA1c</td><td>5.6</td><td>%</td><td>4.0-6.0</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="report-section">
|
||||
<div class="report-section__title">甲状腺功能</div>
|
||||
<table class="report-table">
|
||||
<thead>
|
||||
<tr><th>项目</th><th>结果</th><th>单位</th><th>参考范围</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>促甲状腺激素 TSH</td><td>2.26</td><td>mIU/L</td><td>0.27-4.20</td></tr>
|
||||
<tr><td>游离三碘甲状腺原氨酸 FT3</td><td>4.88</td><td>pmol/L</td><td>3.1-6.8</td></tr>
|
||||
<tr><td>游离甲状腺素 FT4</td><td>15.4</td><td>pmol/L</td><td>12-22</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="report-section">
|
||||
<div class="report-section__title">肿瘤标志物</div>
|
||||
<table class="report-table">
|
||||
<thead>
|
||||
<tr><th>项目</th><th>结果</th><th>单位</th><th>参考范围</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>癌胚抗原 CEA</td><td>1.82</td><td>ng/mL</td><td>0-5.0</td></tr>
|
||||
<tr><td>甲胎蛋白 AFP</td><td>3.44</td><td>ng/mL</td><td>0-8.1</td></tr>
|
||||
<tr><td>糖类抗原 CA125</td><td>18.6</td><td>U/mL</td><td>0-35</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="report-section">
|
||||
<div class="report-section__title">心电图</div>
|
||||
<table class="report-table">
|
||||
<thead>
|
||||
<tr><th style="width:30%">项目</th><th style="width:36%">结果</th><th style="width:14%">单位</th><th style="width:20%">参考</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>十二导联心电图</td><td>窦性心律</td><td>--</td><td>--</td></tr>
|
||||
<tr><td>心电图提示</td><td>未见明显异常</td><td>--</td><td>--</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="report-section">
|
||||
<div class="report-section__title">彩超检查</div>
|
||||
<table class="report-table">
|
||||
<thead>
|
||||
<tr><th>检查项目</th><th>检查结果</th><th>单位</th><th>参考</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>肝胆脾胰双肾彩超</td><td>轻度脂肪肝</td><td>--</td><td>--</td></tr>
|
||||
<tr><td>甲状腺彩超</td><td>甲状腺双叶回声均匀</td><td>--</td><td>--</td></tr>
|
||||
<tr><td>乳腺彩超</td><td>未见明显异常</td><td>--</td><td>--</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="report-section">
|
||||
<div class="report-section__title">影像检查</div>
|
||||
<table class="report-table">
|
||||
<thead>
|
||||
<tr><th>检查项目</th><th>检查结果</th><th>单位</th><th>参考</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>胸部 DR</td><td>心肺膈未见明显异常</td><td>--</td><td>--</td></tr>
|
||||
<tr><td>颈椎 CT</td><td>颈椎生理曲度变直</td><td>--</td><td>--</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="conclusion-wrap">
|
||||
<!-- [交互] 返回报告列表按钮 -->
|
||||
<button class="back-btn" onclick="location.href='reports.html'">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="19" y1="12" x2="5" y2="12"/><polyline points="12 19 5 12 12 5"/></svg>
|
||||
返回报告列表
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-spacer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// [交互] 展开/收起洞察卡片
|
||||
function toggleInsight(cardId, btn) {
|
||||
var card = document.getElementById(cardId);
|
||||
var content = card.querySelector('.insight-card__content');
|
||||
var fade = card.querySelector('.insight-card__fade');
|
||||
var isExpanded = card.classList.toggle('is-expanded');
|
||||
btn.textContent = isExpanded ? '收起' : '展开';
|
||||
if (fade) fade.style.display = isExpanded ? 'none' : '';
|
||||
}
|
||||
|
||||
// [交互] 语音播报按钮切换(原型演示,仅切换状态)
|
||||
function toggleVoice(btn) {
|
||||
btn.classList.toggle('is-playing');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,157 @@
|
||||
<!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 160px, #f7f9fb 100%); }
|
||||
.scroll-content::-webkit-scrollbar { display: none; }
|
||||
.page-body { padding: 16px; }
|
||||
/* 顶部 AI 解读大卡片 */
|
||||
.ai-card {
|
||||
background: linear-gradient(135deg, #ffffff 0%, #e6fffb 100%);
|
||||
border: 1px solid #b5f5ec; border-radius: 20px; padding: 20px 18px;
|
||||
box-shadow: 0 6px 18px rgba(20, 180, 176, 0.10); position: relative; overflow: hidden;
|
||||
}
|
||||
.ai-card::after {
|
||||
content: ''; position: absolute; right: -30px; top: -30px; width: 120px; height: 120px;
|
||||
border-radius: 50%; background: rgba(19, 194, 194, 0.08);
|
||||
}
|
||||
.ai-card__badge {
|
||||
display: inline-flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px;
|
||||
border-radius: 13px; background: rgba(19, 194, 194, 0.12); color: #08979c;
|
||||
font-size: 12px; font-weight: 600; margin-bottom: 10px;
|
||||
}
|
||||
.ai-card__title { font-size: 20px; font-weight: 700; color: #1a1a1a; margin-bottom: 4px; position: relative; z-index: 1; }
|
||||
.ai-card__sub { font-size: 13px; color: #13c2c2; font-weight: 600; margin-bottom: 8px; position: relative; z-index: 1; }
|
||||
.ai-card__desc { font-size: 13px; line-height: 1.7; color: #666; position: relative; z-index: 1; }
|
||||
/* 报告列表 */
|
||||
.section-title { font-size: 16px; font-weight: 700; color: #1a1a1a; margin: 22px 2px 12px; }
|
||||
.report-list { display: flex; flex-direction: column; gap: 12px; }
|
||||
.report-item {
|
||||
background: #fff; border-radius: 16px; 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;
|
||||
}
|
||||
.report-item:active { transform: scale(0.985); }
|
||||
.report-item__icon {
|
||||
width: 48px; height: 48px; border-radius: 14px; display: flex; align-items: center;
|
||||
justify-content: center; flex-shrink: 0; background: #fff7e6; color: #fa8c16;
|
||||
}
|
||||
.report-item__content { flex: 1; min-width: 0; }
|
||||
.report-item__title { font-size: 15px; font-weight: 600; color: #1a1a1a; margin-bottom: 4px; }
|
||||
.report-item__meta { font-size: 12px; color: #8c8c8c; }
|
||||
.report-item__arrow { font-size: 18px; color: #c6c6c6; flex-shrink: 0; }
|
||||
.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="location.href='index.html'">‹</span>
|
||||
<span class="nav-title">体检报告</span>
|
||||
</div>
|
||||
<div class="scroll-content">
|
||||
<div class="page-body">
|
||||
<!-- 顶部 AI 解读大卡片 -->
|
||||
<div class="ai-card">
|
||||
<div class="ai-card__badge">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
|
||||
<span>AI解读</span>
|
||||
</div>
|
||||
<div class="ai-card__title">体检报告解读</div>
|
||||
<div class="ai-card__desc">依托 AI 技术,自动解析体检报告数据,提供专业指标解读、风险评估与个性化健康指导。</div>
|
||||
<br>
|
||||
<div class="ai-card__sub">查看报告解读</div>
|
||||
</div>
|
||||
|
||||
<!-- 报告列表 -->
|
||||
<div class="section-title">我的历年报告</div>
|
||||
<div class="report-list">
|
||||
<!-- [交互] 点击跳转至: report-query.html -->
|
||||
<div class="report-item" onclick="location.href='report-query.html'">
|
||||
<div class="report-item__icon">
|
||||
<svg width="24" height="24" 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="report-item__content">
|
||||
<div class="report-item__title">2025年度胃肠镜体检报告</div>
|
||||
<div class="report-item__meta">长庆星龙园医院</div>
|
||||
</div>
|
||||
<span class="report-item__arrow">›</span>
|
||||
</div>
|
||||
<!-- [交互] 点击跳转至: report-query.html -->
|
||||
<div class="report-item" onclick="location.href='report-query.html'">
|
||||
<div class="report-item__icon">
|
||||
<svg width="24" height="24" 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="report-item__content">
|
||||
<div class="report-item__title">2025年度常规体检报告</div>
|
||||
<div class="report-item__meta">长庆星龙园医院</div>
|
||||
</div>
|
||||
<span class="report-item__arrow">›</span>
|
||||
</div>
|
||||
<!-- [交互] 点击跳转至: report-query.html -->
|
||||
<div class="report-item" onclick="location.href='report-query.html'">
|
||||
<div class="report-item__icon">
|
||||
<svg width="24" height="24" 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="report-item__content">
|
||||
<div class="report-item__title">2024年度常规体检报告</div>
|
||||
<div class="report-item__meta">长庆星龙园医院</div>
|
||||
</div>
|
||||
<span class="report-item__arrow">›</span>
|
||||
</div>
|
||||
<!-- [交互] 点击跳转至: report-query.html -->
|
||||
<div class="report-item" onclick="location.href='report-query.html'">
|
||||
<div class="report-item__icon">
|
||||
<svg width="24" height="24" 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="report-item__content">
|
||||
<div class="report-item__title">2023年度常规体检报告</div>
|
||||
<div class="report-item__meta">长庆星龙园医院</div>
|
||||
</div>
|
||||
<span class="report-item__arrow">›</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-spacer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -154,7 +154,7 @@
|
||||
|
||||
<!-- [交互] 导航栏:返回按钮 + 标题 + 右侧消息图标 -->
|
||||
<div class="nav-bar">
|
||||
<span class="nav-back" onclick="goBackFromSource()">← 返回</span>
|
||||
<span class="nav-back" onclick="location.href='../home/index.html'">← 返回</span>
|
||||
<span class="nav-title">健康咨询</span>
|
||||
|
||||
</div>
|
||||
@@ -261,20 +261,5 @@
|
||||
<div class="bottom-spacer"></div>
|
||||
|
||||
</div><!-- /.phone-shell -->
|
||||
<script>
|
||||
function goBackFromSource() {
|
||||
var params = new URLSearchParams(window.location.search);
|
||||
var from = params.get('from');
|
||||
if (from === 'index') {
|
||||
window.location.href = '../home/index.html';
|
||||
return;
|
||||
}
|
||||
if (document.referrer) {
|
||||
history.back();
|
||||
return;
|
||||
}
|
||||
window.location.href = '../home/index.html';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -157,7 +157,7 @@
|
||||
|
||||
|
||||
<!-- 温馨提示 -->
|
||||
<div class="tip-box">📌 温馨提示:请在预约时间前5分钟准备好,保持网络畅通,等待医生拨打视频通话</div>
|
||||
<div class="tip-box">📌 温馨提示:请在预约时间内保持网络畅通,等待医生拨打视频通话</div>
|
||||
</div>
|
||||
|
||||
<!-- [交互] 底部操作栏 -->
|
||||
|
||||
@@ -0,0 +1,329 @@
|
||||
<!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;
|
||||
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; }
|
||||
|
||||
/* 预警统计卡片 */
|
||||
.stats-card {
|
||||
margin: 12px 12px 0;
|
||||
background: #fff;
|
||||
border-radius: 14px;
|
||||
padding: 20px 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.stats-card__left { display: flex; flex-direction: column; align-items: flex-start; }
|
||||
.stats-card__label { font-size: 13px; color: #999; margin-bottom: 6px; }
|
||||
.stats-card__count-row { display: flex; align-items: baseline; gap: 4px; }
|
||||
/* 本月无预警,数字显示绿色 */
|
||||
.stats-card__count { font-size: 40px; font-weight: 800; color: #52c41a; line-height: 1; }
|
||||
.stats-card__unit { font-size: 14px; color: #52c41a; font-weight: 600; }
|
||||
.stats-card__right { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
|
||||
.stats-card__recent-label { font-size: 12px; color: #999; }
|
||||
.stats-card__recent-time { font-size: 13px; font-weight: 600; color: #333; }
|
||||
|
||||
/* 预警图标装饰 */
|
||||
.stats-card__icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background: #f6ffed;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
/* 列表区块标题 */
|
||||
.section-title {
|
||||
font-size: 13px;
|
||||
color: #999;
|
||||
padding: 14px 16px 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 预警记录卡片 */
|
||||
.alert-card {
|
||||
margin: 0 12px 10px;
|
||||
background: #fff;
|
||||
border-radius: 14px;
|
||||
padding: 14px 14px 14px 12px;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
/* 左侧等级圆点 */
|
||||
.alert-card__dot-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding-top: 3px;
|
||||
gap: 4px;
|
||||
}
|
||||
.alert-card__dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/* 严重:红色 */
|
||||
.alert-card__dot--critical { background: #ff4d4f; box-shadow: 0 0 0 3px rgba(255,77,79,0.18); }
|
||||
|
||||
/* 卡片主体内容 */
|
||||
.alert-card__body { flex: 1; min-width: 0; }
|
||||
.alert-card__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.alert-card__time { font-size: 13px; color: #666; }
|
||||
.alert-card__badge {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
padding: 2px 8px;
|
||||
border-radius: 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/* 严重标签:红底红字 */
|
||||
.alert-card__badge--critical { background: #fff1f0; color: #ff4d4f; }
|
||||
|
||||
/* 监测值 */
|
||||
.alert-card__value-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 4px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.alert-card__value { font-size: 24px; font-weight: 800; color: #1a1a1a; line-height: 1; }
|
||||
.alert-card__value-unit { font-size: 13px; color: #999; }
|
||||
|
||||
/* 详情行 */
|
||||
.alert-card__detail-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.alert-card__detail-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
.alert-card__detail-item svg { flex-shrink: 0; }
|
||||
|
||||
/* 触发原因 */
|
||||
.alert-card__reason {
|
||||
margin-top: 8px;
|
||||
font-size: 12px;
|
||||
color: #bbb;
|
||||
background: #fafafa;
|
||||
border-radius: 6px;
|
||||
padding: 6px 8px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 底部安全区 */
|
||||
.bottom-safe { height: 20px; flex-shrink: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="phone-shell">
|
||||
|
||||
<!-- 状态栏 -->
|
||||
<div class="status-bar">
|
||||
<span class="time">9:41</span>
|
||||
<div class="icons">
|
||||
<!-- WiFi 图标 -->
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2">
|
||||
<path d="M5 12.55a11 11 0 0 1 14.08 0"/>
|
||||
<path d="M1.42 9a16 16 0 0 1 21.16 0"/>
|
||||
<path d="M8.53 16.11a6 6 0 0 1 6.95 0"/>
|
||||
<circle cx="12" cy="20" r="1" fill="#333" stroke="none"/>
|
||||
</svg>
|
||||
<!-- 电池图标 -->
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2">
|
||||
<rect x="1" y="6" width="18" height="12" rx="2"/>
|
||||
<path d="M21 10v4"/>
|
||||
<rect x="3" y="8" width="12" height="8" rx="1" fill="#333" stroke="none"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 导航栏:返回血氧详情页 -->
|
||||
<div class="nav-bar">
|
||||
<div class="nav-back" onclick="location.href='blood-oxygen.html'">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round">
|
||||
<path d="M15 19l-7-7 7-7"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="nav-title">血氧预警历史</div>
|
||||
</div>
|
||||
|
||||
<!-- 滚动内容区 -->
|
||||
<div class="scroll-content">
|
||||
|
||||
<!-- 预警统计卡片 -->
|
||||
<div class="stats-card">
|
||||
<div class="stats-card__left">
|
||||
<div class="stats-card__label">本月预警</div>
|
||||
<div class="stats-card__count-row">
|
||||
<span class="stats-card__count">0</span>
|
||||
<span class="stats-card__unit">次</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stats-card__right">
|
||||
<!-- 血氧水滴图标,绿色背景表示正常 -->
|
||||
<div class="stats-card__icon">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M12 2C12 2 5 9.5 5 14a7 7 0 0 0 14 0C19 9.5 12 2 12 2z" fill="#52c41a" opacity="0.85"/>
|
||||
<path d="M9 13.5a3 3 0 0 0 3 3" stroke="#fff" stroke-width="1.5" stroke-linecap="round" opacity="0.7"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stats-card__recent-label">最近预警时间</div>
|
||||
<div class="stats-card__recent-time">暂无</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 空状态:本月无预警记录 -->
|
||||
<!-- <div class="empty-state">-->
|
||||
<!-- <!– 大图标:绿色盾牌表示健康安全 –>-->
|
||||
<!-- <div class="empty-state__icon">-->
|
||||
<!-- <svg width="40" height="40" viewBox="0 0 24 24" fill="none">-->
|
||||
<!-- <path d="M12 2L3 7v5c0 5.25 3.75 10.15 9 11.35C17.25 22.15 21 17.25 21 12V7L12 2z" fill="#52c41a" opacity="0.15" stroke="#52c41a" stroke-width="1.5" stroke-linejoin="round"/>-->
|
||||
<!-- <!– 对勾 –>-->
|
||||
<!-- <polyline points="9 12 11 14 15 10" stroke="#52c41a" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>-->
|
||||
<!-- </svg>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="empty-state__text">暂无预警记录,请继续保持</div>-->
|
||||
<!-- </div>-->
|
||||
|
||||
<!-- 预警记录列表标题 -->
|
||||
<div class="section-title">预警记录(共 1 条)</div>
|
||||
|
||||
<!-- 历史预警记录:2026-03-08 严重 -->
|
||||
<div class="alert-card">
|
||||
<!-- 左侧严重等级红点 -->
|
||||
<div class="alert-card__dot-col">
|
||||
<div class="alert-card__dot alert-card__dot--critical"></div>
|
||||
</div>
|
||||
<div class="alert-card__body">
|
||||
<!-- 时间 + 严重等级标签 -->
|
||||
<div class="alert-card__header">
|
||||
<span class="alert-card__time">2026-03-08 03:22</span>
|
||||
<span class="alert-card__badge alert-card__badge--critical">严重</span>
|
||||
</div>
|
||||
<!-- 血氧监测值 -->
|
||||
<div class="alert-card__value-row">
|
||||
<span class="alert-card__value">93</span>
|
||||
<span class="alert-card__value-unit">%</span>
|
||||
</div>
|
||||
<!-- 持续时长 + 血氧标签 -->
|
||||
<div class="alert-card__detail-row">
|
||||
<!-- 时钟图标 + 持续时长 -->
|
||||
<div class="alert-card__detail-item">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<polyline points="12 6 12 12 16 14"/>
|
||||
</svg>
|
||||
<span>持续 8 分钟</span>
|
||||
</div>
|
||||
<!-- 血氧水滴图标 + 标签 -->
|
||||
<div class="alert-card__detail-item">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2">
|
||||
<path d="M12 2C12 2 6 9 6 14a6 6 0 0 0 12 0C18 9 12 2 12 2z"/>
|
||||
</svg>
|
||||
<span>血氧</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 触发原因 -->
|
||||
<div class="alert-card__reason">触发原因:血氧低于 95% 阈值</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部安全区 -->
|
||||
<div class="bottom-safe"></div>
|
||||
</div><!-- /scroll-content -->
|
||||
|
||||
</div><!-- /phone-shell -->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,312 @@
|
||||
<!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; 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; }
|
||||
|
||||
/* 主题色(血氧绿) */
|
||||
:root { --theme: #52c41a; --theme2: #95de64; }
|
||||
|
||||
.top-panel { background: #fff; padding-top: 2px; }
|
||||
.time-tabs { display: flex; justify-content: center; gap: 42px; padding: 2px 0 8px; }
|
||||
.time-tab { position: relative; font-size: 18px; color: #444; cursor: pointer; padding: 0 2px 6px; user-select: none; }
|
||||
.time-tab.active { color: var(--theme); }
|
||||
.time-tab.active::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; margin: auto; width: 22px; height: 3px; border-radius: 2px; background: var(--theme); }
|
||||
|
||||
.summary-area { text-align: center; padding: 12px 24px 6px; }
|
||||
.date-row { display: inline-flex; align-items: center; gap: 6px; font-size: 16px; color: #666; font-weight: 500; }
|
||||
.range-text { margin-top: 4px; font-size: 16px; color: #666; }
|
||||
.main-row { margin-top: 2px; display: inline-flex; align-items: baseline; gap: 4px; }
|
||||
.main-row__value { font-size: 48px; line-height: 1; font-weight: 500; color: #1f1f1f; letter-spacing: -1px; }
|
||||
.main-row__unit { font-size: 18px; color: #333; }
|
||||
.main-badge { display: inline-flex; align-items: center; justify-content: center; margin-top: 6px; padding: 3px 12px; border-radius: 18px; font-size: 12px; font-weight: 600; background: #f6ffed; color: #52c41a; }
|
||||
|
||||
.chart-wrap { position: relative; background: #fff; padding: 6px 16px 0; }
|
||||
.chart-box { position: relative; height: 160px; }
|
||||
.chart-svg { width: 100%; height: 100%; display: block; }
|
||||
.chart-grid line { stroke: #ececec; stroke-width: 1; }
|
||||
.chart-path { fill: none; stroke: var(--theme); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
|
||||
.chart-dot { fill: var(--theme); }
|
||||
.y-axis-labels { position: absolute; top: 6px; right: 0; width: 56px; height: 208px; pointer-events: none; }
|
||||
.y-axis-label { position: absolute; right: 0; transform: translateY(50%); font-size: 12px; color: #666; }
|
||||
.x-axis { display: grid; gap: 0; padding: 8px 14px 0 0; font-size: 12px; color: #666; }
|
||||
.x-axis span { text-align: center; white-space: nowrap; }
|
||||
.x-axis--dense { font-size: 10px; }
|
||||
.timeline-knob-row { position: relative; margin: 0; height: 24px; }
|
||||
.timeline-track { position: absolute; left: 0; right: 0; top: 10px; height: 1px; background: #e8e8e8; }
|
||||
.timeline-knob { position: absolute; right: 16px; top: -4px; width: 24px; height: 24px; border-radius: 50%; background: #fff; box-shadow: 0 2px 10px rgba(0,0,0,0.12); }
|
||||
|
||||
.card { margin: 8px 12px 0; background: #fff; border-radius: 22px; padding: 14px 12px; display: flex; gap: 0; }
|
||||
.metric-row { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 6px 6px; }
|
||||
.metric-left__label { font-size: 12px; color: #777; margin-bottom: 4px; }
|
||||
.metric-left__value { display: flex; align-items: baseline; gap: 2px; }
|
||||
.metric-left__num { font-size: 16px; font-weight: 600; color: #222; }
|
||||
.metric-left__unit { font-size: 12px; color: #777; }
|
||||
.metric-right { font-size: 12px; color: #777; text-align: center; }
|
||||
.metric-split { width: 1px; background: #ececec; margin: 0; }
|
||||
|
||||
.alert-btn { margin: 8px 12px 0; border: 1.5px solid var(--theme); border-radius: 12px; padding: 11px; text-align: center; font-size: 13px; color: var(--theme); font-weight: 600; cursor: pointer; background: #fff; display: flex; align-items: center; justify-content: center; gap: 6px; }
|
||||
|
||||
.foot-note { padding: 10px 0 12px; text-align: center; font-size: 11px; color: #b3b3b3; }
|
||||
.bottom-safe { height: 12px; flex-shrink: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="phone-shell">
|
||||
<div class="status-bar">
|
||||
<span class="time">9:41</span>
|
||||
<div class="icons">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" 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="#333" 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">
|
||||
<div class="nav-back" onclick="location.href='index.html'">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round"><path d="M15 19l-7-7 7-7"/></svg>
|
||||
</div>
|
||||
<div class="nav-title">血氧</div>
|
||||
</div>
|
||||
|
||||
<div class="scroll-content">
|
||||
<div class="top-panel">
|
||||
<div class="time-tabs">
|
||||
<div class="time-tab active" data-mode="day">日</div>
|
||||
<div class="time-tab" data-mode="week">周</div>
|
||||
<div class="time-tab" data-mode="month">月</div>
|
||||
<div class="time-tab" data-mode="year">年</div>
|
||||
</div>
|
||||
<div class="summary-area">
|
||||
<div class="date-row">
|
||||
<span id="dateText">4月30日 周四</span>
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="#666"><path d="M7 10l5 5 5-5z"/></svg>
|
||||
</div>
|
||||
<div class="range-text" id="rangeText">00:00-23:59</div>
|
||||
<div class="main-row">
|
||||
<span class="main-row__value" id="mainValue">98</span>
|
||||
<span class="main-row__unit" id="mainUnit">%</span>
|
||||
</div>
|
||||
<div class="main-badge" id="statusBadge">正常</div>
|
||||
</div>
|
||||
|
||||
<div class="chart-wrap">
|
||||
<div class="chart-box">
|
||||
<svg class="chart-svg" id="chart" viewBox="0 0 358 258" preserveAspectRatio="none">
|
||||
<g class="chart-grid" id="chartGrid"></g>
|
||||
<path id="line" class="chart-path"></path>
|
||||
<circle id="dot" class="chart-dot" r="3.2"></circle>
|
||||
</svg>
|
||||
<div class="y-axis-labels" id="yAxisLabels"></div>
|
||||
</div>
|
||||
<div class="x-axis" id="xAxis"></div>
|
||||
<div class="timeline-knob-row">
|
||||
<div class="timeline-track"></div>
|
||||
<div class="timeline-knob"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="metric-row">
|
||||
<div class="metric-left">
|
||||
<div class="metric-left__label">最高</div>
|
||||
<div class="metric-left__value"><span class="metric-left__num" id="maxValue">99</span><span class="metric-left__unit">%</span></div>
|
||||
</div>
|
||||
<div class="metric-right" id="maxHint">10:10</div>
|
||||
</div>
|
||||
<div class="metric-split"></div>
|
||||
<div class="metric-row">
|
||||
<div class="metric-left">
|
||||
<div class="metric-left__label">最低</div>
|
||||
<div class="metric-left__value"><span class="metric-left__num" id="minValue">95</span><span class="metric-left__unit">%</span></div>
|
||||
</div>
|
||||
<div class="metric-right" id="minHint">02:50</div>
|
||||
</div>
|
||||
<div class="metric-split"></div>
|
||||
<div class="metric-row">
|
||||
<div class="metric-left">
|
||||
<div class="metric-left__label">平均</div>
|
||||
<div class="metric-left__value"><span class="metric-left__num" id="avgValue">97</span><span class="metric-left__unit">%</span></div>
|
||||
</div>
|
||||
<div class="metric-right" id="avgHint">全天</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert-btn" onclick="location.href='blood-oxygen-alerts.html'">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--theme)" stroke-width="2"><path d="M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
查看预警历史 ›
|
||||
</div>
|
||||
|
||||
<div class="foot-note">以上数据为原型示例,实际以设备同步为准</div>
|
||||
<div class="bottom-safe"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var dataMap = {
|
||||
day: {
|
||||
dateText: '4月30日 周四',
|
||||
rangeText: '00:00-23:59',
|
||||
unit: '%',
|
||||
decimals: 0,
|
||||
points: [97,97,96,96,95,96,96,97,98,98,97,97,98,99,98,97,97,96,97,98,98,97,97,97],
|
||||
totalMode: 'last',
|
||||
yTicks: [100, 98, 96, 94],
|
||||
xLabels: ['0:00','6:00','12:00','18:00','24:00'],
|
||||
status: '正常',
|
||||
max: { v:99, hint:'10:10' },
|
||||
min: { v:95, hint:'02:50' },
|
||||
avg: { v:97, hint:'全天' }
|
||||
},
|
||||
week: {
|
||||
dateText: '4月27日-5月3日',
|
||||
rangeText: '周一-周日',
|
||||
unit: '%',
|
||||
decimals: 0,
|
||||
points: [97,96,98,97,97,98,98],
|
||||
totalMode: 'avg',
|
||||
yTicks: [100, 98, 96, 94],
|
||||
xLabels: ['周一','周二','周三','周四','周五','周六','周日'],
|
||||
status: '正常',
|
||||
max: { v:98, hint:'周三' },
|
||||
min: { v:96, hint:'周二' },
|
||||
avg: { v:97, hint:'本周' }
|
||||
},
|
||||
month: {
|
||||
dateText: '2026年4月',
|
||||
rangeText: '4月1日-4月30日',
|
||||
unit: '%',
|
||||
decimals: 0,
|
||||
points: [97,97,96,96,95,96,96,97,98,98,97,97,98,99,98,97,97,96,97,98,98,97,97,97,97,97,96,96,95,96],
|
||||
totalMode: 'avg',
|
||||
yTicks: [100, 98, 96, 94],
|
||||
xLabels: ['1日','7日','14日','21日','30日'],
|
||||
status: '正常',
|
||||
max: { v:99, hint:'04-14' },
|
||||
min: { v:95, hint:'04-05' },
|
||||
avg: { v:97, hint:'本月' }
|
||||
},
|
||||
year: {
|
||||
dateText: '2026年',
|
||||
rangeText: '1月-12月',
|
||||
unit: '%',
|
||||
decimals: 0,
|
||||
points: [97,97,96,96,97,96,96,97,98,97,96,97],
|
||||
totalMode: 'avg',
|
||||
yTicks: [100, 98, 96, 94],
|
||||
xLabels: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
|
||||
status: '正常',
|
||||
max: { v:98, hint:'01月' },
|
||||
min: { v:96, hint:'03月' },
|
||||
avg: { v:97, hint:'全年' }
|
||||
}
|
||||
};
|
||||
|
||||
function avg(arr) {
|
||||
if (!arr.length) return 0;
|
||||
var sum = arr.reduce(function(s, v){ return s + v; }, 0);
|
||||
return sum / arr.length;
|
||||
}
|
||||
|
||||
function getValue(cfg) {
|
||||
if (cfg.totalMode === 'last') return cfg.points[cfg.points.length - 1];
|
||||
if (cfg.totalMode === 'avg') return avg(cfg.points);
|
||||
if (cfg.totalMode === 'max') return Math.max.apply(null, cfg.points);
|
||||
if (cfg.totalMode === 'min') return Math.min.apply(null, cfg.points);
|
||||
return cfg.points[cfg.points.length - 1];
|
||||
}
|
||||
|
||||
function formatValue(val, decimals) {
|
||||
if (typeof val !== 'number') return String(val);
|
||||
if (decimals != null) return val.toFixed(decimals);
|
||||
return String(val);
|
||||
}
|
||||
|
||||
function renderChart(cfg) {
|
||||
var chartWidth = 330;
|
||||
var chartHeight = 208;
|
||||
var startY = 22;
|
||||
var stepX = chartWidth / (cfg.points.length - 1 || 1);
|
||||
var maxY = cfg.yTicks[0];
|
||||
|
||||
var grid = document.getElementById('chartGrid');
|
||||
var yAxis = document.getElementById('yAxisLabels');
|
||||
var xAxis = document.getElementById('xAxis');
|
||||
var lineEl = document.getElementById('line');
|
||||
var dotEl = document.getElementById('dot');
|
||||
|
||||
grid.innerHTML = '';
|
||||
cfg.yTicks.forEach(function(_, index) {
|
||||
var y = startY + (chartHeight / (cfg.yTicks.length - 1)) * index;
|
||||
grid.innerHTML += '<line x1="0" y1="' + y.toFixed(1) + '" x2="330" y2="' + y.toFixed(1) + '"></line>';
|
||||
});
|
||||
|
||||
yAxis.innerHTML = cfg.yTicks.map(function(tick, index) {
|
||||
return '<span class="y-axis-label" style="top:' + (index * 52) + 'px">' + formatValue(tick, 0) + '</span>';
|
||||
}).join('');
|
||||
|
||||
var pts = cfg.points.map(function(v, i) {
|
||||
var x = i * stepX;
|
||||
var y = startY + chartHeight - (v / maxY) * chartHeight;
|
||||
return { x: x, y: y };
|
||||
});
|
||||
|
||||
var d = pts.map(function(p, index) {
|
||||
return (index === 0 ? 'M' : 'L') + p.x.toFixed(1) + ',' + p.y.toFixed(1);
|
||||
}).join(' ');
|
||||
lineEl.setAttribute('d', d);
|
||||
|
||||
var last = pts[pts.length - 1];
|
||||
dotEl.setAttribute('cx', last.x.toFixed(1));
|
||||
dotEl.setAttribute('cy', last.y.toFixed(1));
|
||||
|
||||
xAxis.className = 'x-axis' + (cfg.xLabels.length > 7 ? ' x-axis--dense' : '');
|
||||
xAxis.style.gridTemplateColumns = 'repeat(' + cfg.xLabels.length + ', 1fr)';
|
||||
xAxis.innerHTML = cfg.xLabels.map(function(label) {
|
||||
return '<span>' + label + '</span>';
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function renderMode(mode) {
|
||||
var cfg = dataMap[mode];
|
||||
var value = getValue(cfg);
|
||||
document.getElementById('dateText').textContent = cfg.dateText;
|
||||
document.getElementById('rangeText').textContent = cfg.rangeText;
|
||||
document.getElementById('mainValue').textContent = formatValue(value, cfg.decimals);
|
||||
document.getElementById('mainUnit').textContent = cfg.unit;
|
||||
document.getElementById('statusBadge').textContent = cfg.status;
|
||||
|
||||
document.getElementById('maxValue').textContent = formatValue(cfg.max.v, cfg.decimals);
|
||||
document.getElementById('maxHint').textContent = cfg.max.hint;
|
||||
document.getElementById('minValue').textContent = formatValue(cfg.min.v, cfg.decimals);
|
||||
document.getElementById('minHint').textContent = cfg.min.hint;
|
||||
document.getElementById('avgValue').textContent = formatValue(cfg.avg.v, cfg.decimals);
|
||||
document.getElementById('avgHint').textContent = cfg.avg.hint;
|
||||
|
||||
renderChart(cfg);
|
||||
}
|
||||
|
||||
document.querySelectorAll('.time-tab').forEach(function(tab) {
|
||||
tab.onclick = function() {
|
||||
document.querySelectorAll('.time-tab').forEach(function(item) { item.classList.remove('active'); });
|
||||
tab.classList.add('active');
|
||||
renderMode(tab.getAttribute('data-mode'));
|
||||
};
|
||||
});
|
||||
|
||||
renderMode('day');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,87 @@
|
||||
# 健康监测 - 变更记录
|
||||
|
||||
> 本文档记录「健康监测」模块原型的所有变更,按时间倒序排列。
|
||||
|
||||
---
|
||||
|
||||
## [2026-05-07] refactor: 统一四个预警历史页面布局结构
|
||||
|
||||
**涉及文件(4个修改):**
|
||||
- `blood-oxygen-alerts.html` — 更新 stats-card 结构,添加 stats-card__recent-label 和 stats-card__recent-time,删除 stats-card__sub-label;更新 section-title 文本为"预警记录(共 1 条)"
|
||||
- `temperature-alerts.html` — 完全重构为标准格式,采用与 heart-rate-alerts.html 相同的 stats-card 和 alert-card 结构,颜色主题使用黄色(#faad14)
|
||||
- `stress-alerts.html` — 已符合标准格式(无需修改)
|
||||
- `heart-rate-alerts.html` — 参考标准(无需修改)
|
||||
|
||||
**变更说明:**
|
||||
- 四个预警历史页面现采用统一的布局结构:stats-card(左侧统计数据 + 右侧图标和最近预警时间)+ alert-card(左侧等级圆点 + 右侧卡片内容)
|
||||
- 各页面保持各自的颜色主题:心率红色(#ff7a8a)、血氧绿色(#52c41a)、体温黄色(#faad14)、压力橙色(#fa8c16)
|
||||
- 统一的 CSS 类名和 DOM 结构便于后续维护和扩展
|
||||
|
||||
---
|
||||
|
||||
## [2026-04-30] refactor: 压缩四个详情页面整体布局高度
|
||||
|
||||
**涉及文件(4个修改):**
|
||||
- `heart-rate.html` — 减少主值字体大小(58px → 48px)、图表高度(258px → 160px)、卡片内边距(18px 12px → 14px 12px)
|
||||
- `temperature.html` — 同步应用布局压缩
|
||||
- `blood-oxygen.html` — 同步应用布局压缩
|
||||
- `stress.html` — 同步应用布局压缩
|
||||
|
||||
**变更说明:**
|
||||
- 所有详情页面现可在 844px 手机屏幕内完整显示,无需垂直滚动
|
||||
- 减少了 150+ 像素的垂直空间占用
|
||||
|
||||
---
|
||||
|
||||
## [2026-04-30] refactor: 详情页面最高/最低/平均改为一行三列显示
|
||||
|
||||
**涉及文件(4个修改):**
|
||||
- `heart-rate.html` — 将三个指标从垂直堆叠改为水平三列布局,使用 flex: 1 实现等宽分布
|
||||
- `temperature.html` — 同步应用三列布局
|
||||
- `blood-oxygen.html` — 同步应用三列布局
|
||||
- `stress.html` — 同步应用三列布局
|
||||
|
||||
**变更说明:**
|
||||
- 指标卡片从竖向排列改为横向三列,每列包含标签、数值、单位和时间提示
|
||||
- 使用垂直分隔线(1px 灰色)分隔三列
|
||||
- 提高了空间利用效率
|
||||
|
||||
---
|
||||
|
||||
## [2026-04-27] refactor: 血氧和压力详情页现代化设计
|
||||
|
||||
**涉及文件(2个修改):**
|
||||
- `blood-oxygen.html` — 从旧的 hero-card 布局改为现代 top-panel 结构,新增 CSS 变量(--theme: #52c41a)、Tab 导航、图表、时间模式切换
|
||||
- `stress.html` — 从旧的 hero-card 布局改为现代 top-panel 结构,新增 CSS 变量(--theme: #faad14)、Tab 导航、图表、时间模式切换
|
||||
|
||||
**变更说明:**
|
||||
- 采用与 temperature.html 相同的现代设计风格
|
||||
- 新增日/周/月/年四种时间维度的数据展示
|
||||
- 图表使用 SVG 绘制,支持动态数据切换
|
||||
- 保留各指标的特定说明文案(血氧正常范围、压力等级说明)
|
||||
|
||||
---
|
||||
|
||||
## [2026-04-21] init: 健康监测模块初始化
|
||||
|
||||
**新增文件(10个):**
|
||||
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `index.html` | 模块首页:四个监测指标入口 |
|
||||
| `heart-rate.html` | 心率详情:日/周/月/年数据展示 + 预警历史入口 |
|
||||
| `heart-rate-alerts.html` | 心率预警历史:预警统计 + 预警记录列表 |
|
||||
| `blood-oxygen.html` | 血氧详情:日/周/月/年数据展示 + 预警历史入口 |
|
||||
| `blood-oxygen-alerts.html` | 血氧预警历史:预警统计 + 预警记录列表 |
|
||||
| `temperature.html` | 体温详情:日/周/月/年数据展示 + 预警历史入口 |
|
||||
| `temperature-alerts.html` | 体温预警历史:预警统计 + 预警记录列表 |
|
||||
| `stress.html` | 压力详情:日/周/月/年数据展示 + 预警历史入口 |
|
||||
| `stress-alerts.html` | 压力预警历史:预警统计 + 预警记录列表 |
|
||||
| `exercise.html` | 运动详情:日/周/月/年数据展示 |
|
||||
| `sleep.html` | 睡眠详情:日/周/月/年数据展示 |
|
||||
|
||||
**变更说明:**
|
||||
- 健康监测模块包含 6 个主要监测指标(心率、血氧、体温、压力、运动、睡眠)
|
||||
- 每个指标支持多时间维度数据展示(日/周/月/年)
|
||||
- 前 4 个指标配备预警历史页面,展示预警统计和详细记录
|
||||
- 所有页面采用统一的设计规范和交互模式
|
||||
@@ -0,0 +1,670 @@
|
||||
<!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;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #e5e5e5;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100vh;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif;
|
||||
}
|
||||
|
||||
/* ===== 手机外壳 ===== */
|
||||
.phone-shell {
|
||||
width: 390px;
|
||||
height: 844px;
|
||||
background: #f5f7fa;
|
||||
border-radius: 44px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
/* ===== 状态栏 ===== */
|
||||
.status-bar {
|
||||
height: 44px;
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 20px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.status-bar .time {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
/* 状态栏右侧图标组 */
|
||||
.status-icons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
/* WiFi 图标(内联SVG) */
|
||||
.icon-wifi {
|
||||
width: 16px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
/* 电池图标(内联SVG) */
|
||||
.icon-battery {
|
||||
width: 25px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
/* ===== 导航栏 ===== */
|
||||
.nav-bar {
|
||||
height: 44px;
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 16px;
|
||||
position: relative;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* 返回按钮 */
|
||||
.nav-back {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
cursor: pointer;
|
||||
color: #fa8c16;
|
||||
font-size: 16px;
|
||||
text-decoration: none;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.nav-back svg {
|
||||
width: 10px;
|
||||
height: 17px;
|
||||
}
|
||||
|
||||
/* 导航标题居中 */
|
||||
.nav-title {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
/* ===== 滚动内容区 ===== */
|
||||
.scroll-content {
|
||||
height: calc(844px - 44px - 44px);
|
||||
overflow-y: auto;
|
||||
padding: 16px 16px 20px;
|
||||
/* 隐藏滚动条但保留滚动功能 */
|
||||
-ms-overflow-style: none;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.scroll-content::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ===== 通用卡片样式 ===== */
|
||||
.card {
|
||||
background: #ffffff;
|
||||
border-radius: 16px;
|
||||
padding: 16px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
/* ===== 本周概览卡片 ===== */
|
||||
.overview-card {
|
||||
background: linear-gradient(135deg, #fa8c16 0%, #ff6b00 100%);
|
||||
border-radius: 16px;
|
||||
padding: 18px 16px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: 0 4px 16px rgba(250, 140, 22, 0.35);
|
||||
}
|
||||
|
||||
.overview-card .card-title {
|
||||
color: rgba(255, 255, 255, 0.9);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
/* 概览统计四格布局 */
|
||||
.overview-stats {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.stat-item {
|
||||
background: rgba(255, 255, 255, 0.18);
|
||||
border-radius: 12px;
|
||||
padding: 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: #ffffff;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.stat-unit {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 12px;
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* ===== 时间维度 Tab ===== */
|
||||
.tab-bar {
|
||||
background: #ffffff;
|
||||
border-radius: 16px;
|
||||
padding: 6px;
|
||||
margin-bottom: 12px;
|
||||
display: flex;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.tab-item {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 8px 0;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #8c8c8c;
|
||||
border-radius: 10px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
/* 激活状态的 Tab */
|
||||
.tab-item.active {
|
||||
background: #fa8c16;
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ===== 锻炼记录列表 ===== */
|
||||
.section-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-bottom: 10px;
|
||||
padding-left: 2px;
|
||||
}
|
||||
|
||||
/* 单条锻炼记录卡片 */
|
||||
.exercise-card {
|
||||
background: #ffffff;
|
||||
border-radius: 16px;
|
||||
padding: 14px 16px;
|
||||
margin-bottom: 10px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
/* 记录卡片顶部:图标+名称 + 日期时间 */
|
||||
.exercise-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.exercise-type {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
/* 运动类型图标背景圆 */
|
||||
.exercise-icon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 50%;
|
||||
background: #fff7e6;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 18px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.exercise-name {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.exercise-datetime {
|
||||
font-size: 12px;
|
||||
color: #8c8c8c;
|
||||
}
|
||||
|
||||
/* 记录卡片底部:四项数据指标 */
|
||||
.exercise-metrics {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 8px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid #f5f5f5;
|
||||
}
|
||||
|
||||
.metric-item {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.metric-value {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
|
||||
.metric-unit {
|
||||
font-size: 11px;
|
||||
color: #8c8c8c;
|
||||
}
|
||||
|
||||
.metric-label {
|
||||
font-size: 11px;
|
||||
color: #8c8c8c;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
/* 心率数值用橙色高亮 */
|
||||
.metric-value.heart-rate {
|
||||
color: #fa8c16;
|
||||
}
|
||||
|
||||
/* ===== 锻炼趋势柱状图 ===== */
|
||||
.trend-card {
|
||||
background: #ffffff;
|
||||
border-radius: 16px;
|
||||
padding: 16px;
|
||||
margin-bottom: 12px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
/* 柱状图容器 */
|
||||
.bar-chart {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: space-around;
|
||||
height: 100px;
|
||||
padding: 0 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
/* 单根柱子组(柱体+标签) */
|
||||
.bar-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* 柱体数值标签 */
|
||||
.bar-value-label {
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: #fa8c16;
|
||||
}
|
||||
|
||||
/* 柱体本身 */
|
||||
.bar {
|
||||
width: 32px;
|
||||
border-radius: 6px 6px 0 0;
|
||||
background: #ffe7ba;
|
||||
transition: height 0.3s ease;
|
||||
}
|
||||
|
||||
/* 当前周(最后一根)高亮 */
|
||||
.bar.current {
|
||||
background: #fa8c16;
|
||||
}
|
||||
|
||||
/* X轴周标签 */
|
||||
.bar-x-labels {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.bar-x-label {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 11px;
|
||||
color: #8c8c8c;
|
||||
}
|
||||
|
||||
.bar-x-label.current {
|
||||
color: #fa8c16;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ===== 统计摘要三卡片 ===== */
|
||||
.summary-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 10px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.summary-card {
|
||||
background: #ffffff;
|
||||
border-radius: 14px;
|
||||
padding: 14px 10px;
|
||||
text-align: center;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
.summary-icon {
|
||||
font-size: 22px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.summary-value {
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #1a1a1a;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.summary-sub {
|
||||
font-size: 11px;
|
||||
color: #8c8c8c;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.summary-label {
|
||||
font-size: 11px;
|
||||
color: #8c8c8c;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* ===== 底部安全区 ===== */
|
||||
.bottom-safe {
|
||||
height: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- 手机外壳 -->
|
||||
<div class="phone-shell">
|
||||
|
||||
<!-- 状态栏:时间 + WiFi + 电池 -->
|
||||
<div class="status-bar">
|
||||
<span class="time">9:41</span>
|
||||
<div class="status-icons">
|
||||
<!-- WiFi 图标 -->
|
||||
<svg class="icon-wifi" viewBox="0 0 16 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 9.5C8.69 9.5 9.25 10.06 9.25 10.75S8.69 12 8 12s-1.25-.56-1.25-1.25S7.31 9.5 8 9.5z" fill="#1a1a1a"/>
|
||||
<path d="M8 6.5c1.38 0 2.63.56 3.54 1.46L12.95 6.55A7.47 7.47 0 008 4.5c-1.93 0-3.69.73-5.01 1.93l1.41 1.41A5.47 5.47 0 018 6.5z" fill="#1a1a1a"/>
|
||||
<path d="M8 2.5c2.76 0 5.26 1.12 7.07 2.93L16.5 4A9.97 9.97 0 008 .5C5.24.5 2.74 1.62.93 3.43L2.36 4.86A7.97 7.97 0 018 2.5z" fill="#1a1a1a" opacity="0.4"/>
|
||||
</svg>
|
||||
<!-- 电池图标 -->
|
||||
<svg class="icon-battery" viewBox="0 0 25 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0.5" y="0.5" width="21" height="11" rx="3.5" stroke="#1a1a1a" stroke-opacity="0.35"/>
|
||||
<rect x="2" y="2" width="16" height="8" rx="2" fill="#1a1a1a"/>
|
||||
<path d="M23 4v4a2 2 0 000-4z" fill="#1a1a1a" opacity="0.4"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 导航栏:返回 + 标题"锻炼" -->
|
||||
<div class="nav-bar">
|
||||
<!-- 点击返回健康监测首页 -->
|
||||
<a class="nav-back" onclick="location.href='index.html'">
|
||||
<svg viewBox="0 0 10 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.5 1.5L1.5 8.5L8.5 15.5" stroke="#fa8c16" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</a>
|
||||
<span class="nav-title">锻炼</span>
|
||||
</div>
|
||||
|
||||
<!-- 滚动内容区 -->
|
||||
<div class="scroll-content">
|
||||
|
||||
<!-- ① 本周概览卡片 -->
|
||||
<div class="overview-card">
|
||||
<div class="card-title">本周概览</div>
|
||||
<div class="overview-stats">
|
||||
<!-- 锻炼次数 -->
|
||||
<div class="stat-item">
|
||||
<div class="stat-value">3<span class="stat-unit">次</span></div>
|
||||
<div class="stat-label">锻炼次数</div>
|
||||
</div>
|
||||
<!-- 累计时长 -->
|
||||
<div class="stat-item">
|
||||
<div class="stat-value">2h<span class="stat-unit">15min</span></div>
|
||||
<div class="stat-label">累计时长</div>
|
||||
</div>
|
||||
<!-- 消耗热量 -->
|
||||
<div class="stat-item">
|
||||
<div class="stat-value">680<span class="stat-unit">kcal</span></div>
|
||||
<div class="stat-label">消耗热量</div>
|
||||
</div>
|
||||
<!-- 运动距离 -->
|
||||
<div class="stat-item">
|
||||
<div class="stat-value">4.2<span class="stat-unit">km</span></div>
|
||||
<div class="stat-label">运动距离</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ② 时间维度 Tab:周 / 月 切换 -->
|
||||
<div class="tab-bar">
|
||||
<!-- 默认选中"周" -->
|
||||
<div class="tab-item active" onclick="switchTab(this, 'week')">周</div>
|
||||
<div class="tab-item" onclick="switchTab(this, 'month')">月</div>
|
||||
</div>
|
||||
|
||||
<!-- ③ 本周锻炼记录列表 -->
|
||||
<div class="section-title">本周锻炼记录</div>
|
||||
|
||||
<!-- 记录 a:户外跑步 -->
|
||||
<div class="exercise-card">
|
||||
<div class="exercise-header">
|
||||
<div class="exercise-type">
|
||||
<div class="exercise-icon">🏃</div>
|
||||
<span class="exercise-name">户外跑步</span>
|
||||
</div>
|
||||
<span class="exercise-datetime">4月28日 18:30</span>
|
||||
</div>
|
||||
<!-- 四项指标:时长 / 距离 / 消耗 / 心率 -->
|
||||
<div class="exercise-metrics">
|
||||
<div class="metric-item">
|
||||
<div class="metric-value">45<span class="metric-unit">min</span></div>
|
||||
<div class="metric-label">时长</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-value">5.2<span class="metric-unit">km</span></div>
|
||||
<div class="metric-label">距离</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-value">320<span class="metric-unit">kcal</span></div>
|
||||
<div class="metric-label">消耗</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<!-- 心率用橙色高亮 -->
|
||||
<div class="metric-value heart-rate">138<span class="metric-unit">bpm</span></div>
|
||||
<div class="metric-label">平均心率</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 记录 b:骑行 -->
|
||||
<div class="exercise-card">
|
||||
<div class="exercise-header">
|
||||
<div class="exercise-type">
|
||||
<div class="exercise-icon">🚴</div>
|
||||
<span class="exercise-name">骑行</span>
|
||||
</div>
|
||||
<span class="exercise-datetime">4月26日 07:15</span>
|
||||
</div>
|
||||
<div class="exercise-metrics">
|
||||
<div class="metric-item">
|
||||
<div class="metric-value">50<span class="metric-unit">min</span></div>
|
||||
<div class="metric-label">时长</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-value">12.8<span class="metric-unit">km</span></div>
|
||||
<div class="metric-label">距离</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-value">240<span class="metric-unit">kcal</span></div>
|
||||
<div class="metric-label">消耗</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-value heart-rate">125<span class="metric-unit">bpm</span></div>
|
||||
<div class="metric-label">平均心率</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 记录 c:游泳 -->
|
||||
<div class="exercise-card">
|
||||
<div class="exercise-header">
|
||||
<div class="exercise-type">
|
||||
<div class="exercise-icon">🏊</div>
|
||||
<span class="exercise-name">游泳</span>
|
||||
</div>
|
||||
<span class="exercise-datetime">4月24日 19:00</span>
|
||||
</div>
|
||||
<div class="exercise-metrics">
|
||||
<div class="metric-item">
|
||||
<div class="metric-value">40<span class="metric-unit">min</span></div>
|
||||
<div class="metric-label">时长</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-value">1.2<span class="metric-unit">km</span></div>
|
||||
<div class="metric-label">距离</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-value">280<span class="metric-unit">kcal</span></div>
|
||||
<div class="metric-label">消耗</div>
|
||||
</div>
|
||||
<div class="metric-item">
|
||||
<div class="metric-value heart-rate">132<span class="metric-unit">bpm</span></div>
|
||||
<div class="metric-label">平均心率</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ④ 锻炼趋势:近4周柱状图 -->
|
||||
<div class="trend-card">
|
||||
<div class="card-title">锻炼趋势</div>
|
||||
<!-- 柱状图:数据 [2次, 4次, 3次, 3次],最大值4次对应100px高度 -->
|
||||
<div class="bar-chart">
|
||||
<!-- 第1周:2次,高度 = 2/4 * 80 = 40px -->
|
||||
<div class="bar-group">
|
||||
<span class="bar-value-label">2</span>
|
||||
<div class="bar" style="height: 40px;"></div>
|
||||
</div>
|
||||
<!-- 第2周:4次,高度 = 4/4 * 80 = 80px -->
|
||||
<div class="bar-group">
|
||||
<span class="bar-value-label">4</span>
|
||||
<div class="bar" style="height: 80px;"></div>
|
||||
</div>
|
||||
<!-- 第3周:3次,高度 = 3/4 * 80 = 60px -->
|
||||
<div class="bar-group">
|
||||
<span class="bar-value-label">3</span>
|
||||
<div class="bar" style="height: 60px;"></div>
|
||||
</div>
|
||||
<!-- 第4周(本周):3次,高亮橙色 -->
|
||||
<div class="bar-group">
|
||||
<span class="bar-value-label">3</span>
|
||||
<div class="bar current" style="height: 60px;"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- X轴标签 -->
|
||||
<div class="bar-x-labels">
|
||||
<span class="bar-x-label">第1周</span>
|
||||
<span class="bar-x-label">第2周</span>
|
||||
<span class="bar-x-label">第3周</span>
|
||||
<span class="bar-x-label current">本周</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ⑤ 统计摘要:本月累计 / 总时长 / 总消耗 -->
|
||||
<div class="section-title">本月统计</div>
|
||||
<div class="summary-grid">
|
||||
<!-- 本月累计次数 -->
|
||||
<div class="summary-card">
|
||||
<div class="summary-icon">🏅</div>
|
||||
<div class="summary-value">12</div>
|
||||
<div class="summary-sub">次</div>
|
||||
<div class="summary-label">本月累计</div>
|
||||
</div>
|
||||
<!-- 总时长 -->
|
||||
<div class="summary-card">
|
||||
<div class="summary-icon">⏱️</div>
|
||||
<div class="summary-value">8h</div>
|
||||
<div class="summary-sub">30min</div>
|
||||
<div class="summary-label">总时长</div>
|
||||
</div>
|
||||
<!-- 总消耗 -->
|
||||
<div class="summary-card">
|
||||
<div class="summary-icon">🔥</div>
|
||||
<div class="summary-value">2,450</div>
|
||||
<div class="summary-sub">kcal</div>
|
||||
<div class="summary-label">总消耗</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部安全区 -->
|
||||
<div class="bottom-safe"></div>
|
||||
|
||||
</div><!-- /scroll-content -->
|
||||
|
||||
</div><!-- /phone-shell -->
|
||||
|
||||
<script>
|
||||
/**
|
||||
* Tab 切换:周 / 月
|
||||
* 切换激活样式,实际数据切换可在此扩展
|
||||
*/
|
||||
function switchTab(el, period) {
|
||||
// 移除所有 tab 的激活状态
|
||||
document.querySelectorAll('.tab-item').forEach(function(item) {
|
||||
item.classList.remove('active');
|
||||
});
|
||||
// 激活当前点击的 tab
|
||||
el.classList.add('active');
|
||||
// TODO: 根据 period 切换对应数据('week' | 'month')
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,390 @@
|
||||
<!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;
|
||||
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; }
|
||||
|
||||
/* 预警统计卡片 */
|
||||
.stats-card {
|
||||
margin: 12px 12px 0;
|
||||
background: #fff;
|
||||
border-radius: 14px;
|
||||
padding: 20px 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.stats-card__left { display: flex; flex-direction: column; align-items: flex-start; }
|
||||
.stats-card__label { font-size: 13px; color: #999; margin-bottom: 6px; }
|
||||
.stats-card__count-row { display: flex; align-items: baseline; gap: 4px; }
|
||||
.stats-card__count { font-size: 40px; font-weight: 800; color: #ff4d4f; line-height: 1; }
|
||||
.stats-card__unit { font-size: 14px; color: #ff4d4f; font-weight: 600; }
|
||||
.stats-card__right { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
|
||||
.stats-card__recent-label { font-size: 12px; color: #999; }
|
||||
.stats-card__recent-time { font-size: 13px; font-weight: 600; color: #333; }
|
||||
|
||||
/* 预警图标装饰 */
|
||||
.stats-card__icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background: #fff1f0;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
/* 列表区块标题 */
|
||||
.section-title {
|
||||
font-size: 13px;
|
||||
color: #999;
|
||||
padding: 14px 16px 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 预警记录卡片 */
|
||||
.alert-card {
|
||||
margin: 0 12px 10px;
|
||||
background: #fff;
|
||||
border-radius: 14px;
|
||||
padding: 14px 14px 14px 12px;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
/* 左侧等级圆点 */
|
||||
.alert-card__dot-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding-top: 3px;
|
||||
gap: 4px;
|
||||
}
|
||||
.alert-card__dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.alert-card__dot--critical { background: #ff4d4f; box-shadow: 0 0 0 3px rgba(255,77,79,0.18); }
|
||||
.alert-card__dot--warning { background: #faad14; box-shadow: 0 0 0 3px rgba(250,173,20,0.18); }
|
||||
|
||||
/* 卡片主体内容 */
|
||||
.alert-card__body { flex: 1; min-width: 0; }
|
||||
.alert-card__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.alert-card__time { font-size: 13px; color: #666; }
|
||||
.alert-card__badge {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
padding: 2px 8px;
|
||||
border-radius: 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.alert-card__badge--critical { background: #fff1f0; color: #ff4d4f; }
|
||||
.alert-card__badge--warning { background: #fffbe6; color: #d48806; }
|
||||
|
||||
/* 监测值 */
|
||||
.alert-card__value-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 4px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.alert-card__value { font-size: 24px; font-weight: 800; color: #1a1a1a; line-height: 1; }
|
||||
.alert-card__value-unit { font-size: 13px; color: #999; }
|
||||
|
||||
/* 详情行 */
|
||||
.alert-card__detail-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.alert-card__detail-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
.alert-card__detail-item svg { flex-shrink: 0; }
|
||||
|
||||
/* 触发原因 */
|
||||
.alert-card__reason {
|
||||
margin-top: 8px;
|
||||
font-size: 12px;
|
||||
color: #bbb;
|
||||
background: #fafafa;
|
||||
border-radius: 6px;
|
||||
padding: 6px 8px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 底部安全区 */
|
||||
.bottom-safe { height: 20px; flex-shrink: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="phone-shell">
|
||||
|
||||
<!-- 状态栏 -->
|
||||
<div class="status-bar">
|
||||
<span class="time">9:41</span>
|
||||
<div class="icons">
|
||||
<!-- WiFi 图标 -->
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2">
|
||||
<path d="M5 12.55a11 11 0 0 1 14.08 0"/>
|
||||
<path d="M1.42 9a16 16 0 0 1 21.16 0"/>
|
||||
<path d="M8.53 16.11a6 6 0 0 1 6.95 0"/>
|
||||
<circle cx="12" cy="20" r="1" fill="#333" stroke="none"/>
|
||||
</svg>
|
||||
<!-- 电池图标 -->
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2">
|
||||
<rect x="1" y="6" width="18" height="12" rx="2"/>
|
||||
<path d="M21 10v4"/>
|
||||
<rect x="3" y="8" width="12" height="8" rx="1" fill="#333" stroke="none"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 导航栏:返回心率详情页 -->
|
||||
<div class="nav-bar">
|
||||
<div class="nav-back" onclick="location.href='heart-rate.html'">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round">
|
||||
<path d="M15 19l-7-7 7-7"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="nav-title">心率预警历史</div>
|
||||
</div>
|
||||
|
||||
<!-- 滚动内容区 -->
|
||||
<div class="scroll-content">
|
||||
|
||||
<!-- 预警统计卡片 -->
|
||||
<div class="stats-card">
|
||||
<div class="stats-card__left">
|
||||
<div class="stats-card__label">本月预警</div>
|
||||
<div class="stats-card__count-row">
|
||||
<span class="stats-card__count">3</span>
|
||||
<span class="stats-card__unit">次</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stats-card__right">
|
||||
<!-- 预警心形图标 -->
|
||||
<div class="stats-card__icon">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" fill="#ff4d4f" stroke="#ff4d4f" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stats-card__recent-label">最近预警时间</div>
|
||||
<div class="stats-card__recent-time">2026-04-28 16:32</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 预警记录列表标题 -->
|
||||
<div class="section-title">预警记录(共 3 条)</div>
|
||||
|
||||
<!-- 预警记录 1:严重 - 2026-04-28 -->
|
||||
<div class="alert-card">
|
||||
<!-- 左侧严重等级红点 -->
|
||||
<div class="alert-card__dot-col">
|
||||
<div class="alert-card__dot alert-card__dot--critical"></div>
|
||||
</div>
|
||||
<div class="alert-card__body">
|
||||
<!-- 时间 + 等级标签 -->
|
||||
<div class="alert-card__header">
|
||||
<span class="alert-card__time">2026-04-28 16:32</span>
|
||||
<span class="alert-card__badge alert-card__badge--critical">严重</span>
|
||||
</div>
|
||||
<!-- 监测值 -->
|
||||
<div class="alert-card__value-row">
|
||||
<span class="alert-card__value">142</span>
|
||||
<span class="alert-card__value-unit">bpm</span>
|
||||
</div>
|
||||
<!-- 持续时长 + 心率标签 -->
|
||||
<div class="alert-card__detail-row">
|
||||
<!-- 时钟图标 + 持续时长 -->
|
||||
<div class="alert-card__detail-item">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<polyline points="12 6 12 12 16 14"/>
|
||||
</svg>
|
||||
<span>持续 5 分钟</span>
|
||||
</div>
|
||||
<!-- 心率标签 -->
|
||||
<div class="alert-card__detail-item">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2">
|
||||
<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/>
|
||||
</svg>
|
||||
<span>心率</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 触发原因 -->
|
||||
<div class="alert-card__reason">触发原因:心率超过 140 bpm 阈值</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 预警记录 2:警告 - 2026-04-25 -->
|
||||
<div class="alert-card">
|
||||
<!-- 左侧警告等级黄点 -->
|
||||
<div class="alert-card__dot-col">
|
||||
<div class="alert-card__dot alert-card__dot--warning"></div>
|
||||
</div>
|
||||
<div class="alert-card__body">
|
||||
<!-- 时间 + 等级标签 -->
|
||||
<div class="alert-card__header">
|
||||
<span class="alert-card__time">2026-04-25 14:18</span>
|
||||
<span class="alert-card__badge alert-card__badge--warning">警告</span>
|
||||
</div>
|
||||
<!-- 监测值 -->
|
||||
<div class="alert-card__value-row">
|
||||
<span class="alert-card__value">128</span>
|
||||
<span class="alert-card__value-unit">bpm</span>
|
||||
</div>
|
||||
<!-- 持续时长 + 心率标签 -->
|
||||
<div class="alert-card__detail-row">
|
||||
<div class="alert-card__detail-item">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<polyline points="12 6 12 12 16 14"/>
|
||||
</svg>
|
||||
<span>持续 3 分钟</span>
|
||||
</div>
|
||||
<div class="alert-card__detail-item">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2">
|
||||
<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/>
|
||||
</svg>
|
||||
<span>心率</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 触发原因 -->
|
||||
<div class="alert-card__reason">触发原因:心率超过 120 bpm 阈值</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 预警记录 3:警告 - 2026-04-20 -->
|
||||
<div class="alert-card">
|
||||
<!-- 左侧警告等级黄点 -->
|
||||
<div class="alert-card__dot-col">
|
||||
<div class="alert-card__dot alert-card__dot--warning"></div>
|
||||
</div>
|
||||
<div class="alert-card__body">
|
||||
<!-- 时间 + 等级标签 -->
|
||||
<div class="alert-card__header">
|
||||
<span class="alert-card__time">2026-04-20 09:45</span>
|
||||
<span class="alert-card__badge alert-card__badge--warning">警告</span>
|
||||
</div>
|
||||
<!-- 监测值 -->
|
||||
<div class="alert-card__value-row">
|
||||
<span class="alert-card__value">126</span>
|
||||
<span class="alert-card__value-unit">bpm</span>
|
||||
</div>
|
||||
<!-- 持续时长 + 心率标签 -->
|
||||
<div class="alert-card__detail-row">
|
||||
<div class="alert-card__detail-item">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<polyline points="12 6 12 12 16 14"/>
|
||||
</svg>
|
||||
<span>持续 2 分钟</span>
|
||||
</div>
|
||||
<div class="alert-card__detail-item">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2">
|
||||
<polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/>
|
||||
</svg>
|
||||
<span>心率</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 触发原因 -->
|
||||
<div class="alert-card__reason">触发原因:心率超过 120 bpm 阈值</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部安全区 -->
|
||||
<div class="bottom-safe"></div>
|
||||
</div><!-- /scroll-content -->
|
||||
|
||||
</div><!-- /phone-shell -->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,316 @@
|
||||
<!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; 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; }
|
||||
|
||||
/* 主题色(心率红) */
|
||||
:root { --theme: #ff7a8a; --theme2:#ffb3bd; }
|
||||
|
||||
.top-panel { background: #fff; padding-top: 2px; }
|
||||
.time-tabs { display: flex; justify-content: center; gap: 42px; padding: 2px 0 8px; }
|
||||
.time-tab { position: relative; font-size: 18px; color: #444; cursor: pointer; padding: 0 2px 6px; user-select: none; }
|
||||
.time-tab.active { color: var(--theme); }
|
||||
.time-tab.active::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; margin: auto; width: 22px; height: 3px; border-radius: 2px; background: var(--theme); }
|
||||
|
||||
.summary-area { text-align: center; padding: 12px 24px 6px; }
|
||||
.date-row { display: inline-flex; align-items: center; gap: 6px; font-size: 16px; color: #666; font-weight: 500; }
|
||||
.range-text { margin-top: 4px; font-size: 16px; color: #666; }
|
||||
.main-row { margin-top: 2px; display: inline-flex; align-items: baseline; gap: 4px; }
|
||||
.main-row__value { font-size: 48px; line-height: 1; font-weight: 500; color: #1f1f1f; letter-spacing: -1px; }
|
||||
.main-row__unit { font-size: 18px; color: #333; }
|
||||
.main-badge { display: inline-flex; align-items: center; justify-content: center; margin-top: 6px; padding: 3px 12px; border-radius: 18px; font-size: 12px; font-weight: 600; background: #f6ffed; color: #52c41a; }
|
||||
|
||||
.chart-wrap { position: relative; background: #fff; padding: 6px 16px 0; }
|
||||
.chart-box { position: relative; height: 160px; }
|
||||
.chart-svg { width: 100%; height: 100%; display: block; }
|
||||
.chart-grid line { stroke: #ececec; stroke-width: 1; }
|
||||
.chart-path { fill: none; stroke: var(--theme); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
|
||||
.chart-dot { fill: var(--theme); }
|
||||
.y-axis-labels { position: absolute; top: 6px; right: 0; width: 56px; height: 208px; pointer-events: none; }
|
||||
.y-axis-label { position: absolute; right: 0; transform: translateY(50%); font-size: 12px; color: #666; }
|
||||
.x-axis { display: grid; gap: 0; padding: 8px 14px 0 0; font-size: 12px; color: #666; }
|
||||
.x-axis span { text-align: center; white-space: nowrap; }
|
||||
.x-axis--dense { font-size: 10px; }
|
||||
.timeline-knob-row { position: relative; margin: 0; height: 24px; }
|
||||
.timeline-track { position: absolute; left: 0; right: 0; top: 10px; height: 1px; background: #e8e8e8; }
|
||||
.timeline-knob { position: absolute; right: 16px; top: -4px; width: 24px; height: 24px; border-radius: 50%; background: #fff; box-shadow: 0 2px 10px rgba(0,0,0,0.12); }
|
||||
|
||||
.card { margin: 8px 12px 0; background: #fff; border-radius: 22px; padding: 14px 12px; display: flex; gap: 0; }
|
||||
.metric-row { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 6px 6px; }
|
||||
.metric-left__label { font-size: 12px; color: #777; margin-bottom: 4px; }
|
||||
.metric-left__value { display: flex; align-items: baseline; gap: 2px; }
|
||||
.metric-left__num { font-size: 16px; font-weight: 600; color: #222; }
|
||||
.metric-left__unit { font-size: 12px; color: #777; }
|
||||
.metric-right { font-size: 12px; color: #777; text-align: center; }
|
||||
.metric-split { width: 1px; background: #ececec; margin: 0; }
|
||||
|
||||
.alert-btn { margin: 8px 12px 0; border: 1.5px solid var(--theme); border-radius: 12px; padding: 11px; text-align: center; font-size: 13px; color: var(--theme); font-weight: 600; cursor: pointer; background: #fff; display: flex; align-items: center; justify-content: center; gap: 6px; }
|
||||
|
||||
.foot-note { padding: 10px 0 12px; text-align: center; font-size: 11px; color: #b3b3b3; }
|
||||
.bottom-safe { height: 12px; flex-shrink: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="phone-shell">
|
||||
<div class="status-bar">
|
||||
<span class="time">9:41</span>
|
||||
<div class="icons">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" 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="#333" 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">
|
||||
<div class="nav-back" onclick="location.href='index.html'">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round"><path d="M15 19l-7-7 7-7"/></svg>
|
||||
</div>
|
||||
<div class="nav-title">心率</div>
|
||||
</div>
|
||||
|
||||
<div class="scroll-content">
|
||||
<div class="top-panel">
|
||||
<div class="time-tabs">
|
||||
<div class="time-tab active" data-mode="day">日</div>
|
||||
<div class="time-tab" data-mode="week">周</div>
|
||||
<div class="time-tab" data-mode="month">月</div>
|
||||
<div class="time-tab" data-mode="year">年</div>
|
||||
</div>
|
||||
<div class="summary-area">
|
||||
<div class="date-row">
|
||||
<span id="dateText">4月30日 周四</span>
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="#666"><path d="M7 10l5 5 5-5z"/></svg>
|
||||
</div>
|
||||
<div class="range-text" id="rangeText">00:00-23:59</div>
|
||||
<div class="main-row">
|
||||
<span class="main-row__value" id="mainValue">72</span>
|
||||
<span class="main-row__unit" id="mainUnit">bpm</span>
|
||||
</div>
|
||||
<div class="main-badge" id="statusBadge">正常</div>
|
||||
</div>
|
||||
|
||||
<div class="chart-wrap">
|
||||
<div class="chart-box">
|
||||
<svg class="chart-svg" id="chart" viewBox="0 0 358 258" preserveAspectRatio="none">
|
||||
<g class="chart-grid" id="chartGrid"></g>
|
||||
<path id="line" class="chart-path"></path>
|
||||
<circle id="dot" class="chart-dot" r="3.2"></circle>
|
||||
</svg>
|
||||
<div class="y-axis-labels" id="yAxisLabels"></div>
|
||||
</div>
|
||||
<div class="x-axis" id="xAxis"></div>
|
||||
<div class="timeline-knob-row">
|
||||
<div class="timeline-track"></div>
|
||||
<div class="timeline-knob"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="metric-row">
|
||||
<div class="metric-left">
|
||||
<div class="metric-left__label">最高</div>
|
||||
<div class="metric-left__value"><span class="metric-left__num" id="maxValue">126</span><span class="metric-left__unit">bpm</span></div>
|
||||
</div>
|
||||
<div class="metric-right" id="maxHint">14:20</div>
|
||||
</div>
|
||||
<div class="metric-split"></div>
|
||||
<div class="metric-row">
|
||||
<div class="metric-left">
|
||||
<div class="metric-left__label">最低</div>
|
||||
<div class="metric-left__value"><span class="metric-left__num" id="minValue">68</span><span class="metric-left__unit">bpm</span></div>
|
||||
</div>
|
||||
<div class="metric-right" id="minHint">03:40</div>
|
||||
</div>
|
||||
<div class="metric-split"></div>
|
||||
<div class="metric-row">
|
||||
<div class="metric-left">
|
||||
<div class="metric-left__label">平均</div>
|
||||
<div class="metric-left__value"><span class="metric-left__num" id="avgValue">82</span><span class="metric-left__unit">bpm</span></div>
|
||||
</div>
|
||||
<div class="metric-right" id="avgHint">全天</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert-btn" onclick="location.href='heart-rate-alerts.html'">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--theme)" stroke-width="2"><path d="M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
查看预警历史 ›
|
||||
</div>
|
||||
|
||||
<div class="foot-note">以上数据为原型示例,实际以设备同步为准</div>
|
||||
<div class="bottom-safe"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var dataMap = {
|
||||
day: {
|
||||
dateText: '4月30日 周四',
|
||||
rangeText: '00:00-23:59',
|
||||
unit: 'bpm',
|
||||
decimals: 0,
|
||||
points: [84,82,80,78,76,74,72,70,68,75,79,83,88,96,102,126,108,94,90,87,85,84,83,72],
|
||||
totalMode: 'last',
|
||||
yTicks: [140, 110, 80, 60, 40],
|
||||
xLabels: ['00:00','06:00','12:00','18:00','24:00'],
|
||||
status: '正常',
|
||||
resting: 62,
|
||||
max: { v:126, hint:'14:20' },
|
||||
min: { v:68, hint:'03:40' },
|
||||
avg: { v:82, hint:'全天' }
|
||||
},
|
||||
week: {
|
||||
dateText: '4月27日-5月3日',
|
||||
rangeText: '周一-周日',
|
||||
unit: 'bpm',
|
||||
decimals: 0,
|
||||
points: [78, 80, 82, 79, 83, 81, 80],
|
||||
totalMode: 'avg',
|
||||
yTicks: [120, 100, 80, 60, 40],
|
||||
xLabels: ['周一','周二','周三','周四','周五','周六','周日'],
|
||||
status: '正常',
|
||||
resting: 63,
|
||||
max: { v:118, hint:'周三 18:10' },
|
||||
min: { v:61, hint:'周二 03:50' },
|
||||
avg: { v:80, hint:'本周' }
|
||||
},
|
||||
month: {
|
||||
dateText: '2026年4月',
|
||||
rangeText: '4月1日-4月30日',
|
||||
unit: 'bpm',
|
||||
decimals: 0,
|
||||
points: [79,81,80,82,83,78,80,81,82,79,80,81,82,83,79,80,81,82,80,79,81,82,80,79,81,82,80,79,81,80],
|
||||
totalMode: 'avg',
|
||||
yTicks: [120, 100, 80, 60, 40],
|
||||
xLabels: ['1日','7日','14日','21日','30日'],
|
||||
status: '正常',
|
||||
resting: 64,
|
||||
max: { v:126, hint:'04-15 14:20' },
|
||||
min: { v:58, hint:'04-08 03:40' },
|
||||
avg: { v:80, hint:'本月' }
|
||||
},
|
||||
year: {
|
||||
dateText: '2026年',
|
||||
rangeText: '1月-12月',
|
||||
unit: 'bpm',
|
||||
decimals: 0,
|
||||
points: [79,80,81,80,79,78,79,80,81,80,79,80],
|
||||
totalMode: 'avg',
|
||||
yTicks: [120, 100, 80, 60, 40],
|
||||
xLabels: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
|
||||
status: '正常',
|
||||
resting: 64,
|
||||
max: { v:132, hint:'03月' },
|
||||
min: { v:57, hint:'02月' },
|
||||
avg: { v:80, hint:'全年' }
|
||||
}
|
||||
};
|
||||
|
||||
function avg(arr) {
|
||||
if (!arr.length) return 0;
|
||||
var sum = arr.reduce(function(s, v){ return s + v; }, 0);
|
||||
return sum / arr.length;
|
||||
}
|
||||
|
||||
function getValue(cfg) {
|
||||
if (cfg.totalMode === 'last') return cfg.points[cfg.points.length - 1];
|
||||
if (cfg.totalMode === 'avg') return avg(cfg.points);
|
||||
if (cfg.totalMode === 'max') return Math.max.apply(null, cfg.points);
|
||||
if (cfg.totalMode === 'min') return Math.min.apply(null, cfg.points);
|
||||
return cfg.points[cfg.points.length - 1];
|
||||
}
|
||||
|
||||
function formatValue(val, decimals) {
|
||||
if (typeof val !== 'number') return String(val);
|
||||
if (decimals != null) return val.toFixed(decimals);
|
||||
return String(val);
|
||||
}
|
||||
|
||||
function renderChart(cfg) {
|
||||
var chartWidth = 330;
|
||||
var chartHeight = 208;
|
||||
var startY = 22;
|
||||
var stepX = chartWidth / (cfg.points.length - 1 || 1);
|
||||
var maxY = cfg.yTicks[0];
|
||||
|
||||
var grid = document.getElementById('chartGrid');
|
||||
var yAxis = document.getElementById('yAxisLabels');
|
||||
var xAxis = document.getElementById('xAxis');
|
||||
var lineEl = document.getElementById('line');
|
||||
var dotEl = document.getElementById('dot');
|
||||
|
||||
grid.innerHTML = '';
|
||||
cfg.yTicks.forEach(function(_, index) {
|
||||
var y = startY + (chartHeight / (cfg.yTicks.length - 1)) * index;
|
||||
grid.innerHTML += '<line x1="0" y1="' + y.toFixed(1) + '" x2="330" y2="' + y.toFixed(1) + '"></line>';
|
||||
});
|
||||
|
||||
yAxis.innerHTML = cfg.yTicks.map(function(tick, index) {
|
||||
return '<span class="y-axis-label" style="top:' + (index * 52) + 'px">' + formatValue(tick, 0) + '</span>';
|
||||
}).join('');
|
||||
|
||||
var pts = cfg.points.map(function(v, i) {
|
||||
var x = i * stepX;
|
||||
var y = startY + chartHeight - (v / maxY) * chartHeight;
|
||||
return { x: x, y: y };
|
||||
});
|
||||
|
||||
var d = pts.map(function(p, index) {
|
||||
return (index === 0 ? 'M' : 'L') + p.x.toFixed(1) + ',' + p.y.toFixed(1);
|
||||
}).join(' ');
|
||||
lineEl.setAttribute('d', d);
|
||||
|
||||
var last = pts[pts.length - 1];
|
||||
dotEl.setAttribute('cx', last.x.toFixed(1));
|
||||
dotEl.setAttribute('cy', last.y.toFixed(1));
|
||||
|
||||
xAxis.className = 'x-axis' + (cfg.xLabels.length > 7 ? ' x-axis--dense' : '');
|
||||
xAxis.style.gridTemplateColumns = 'repeat(' + cfg.xLabels.length + ', 1fr)';
|
||||
xAxis.innerHTML = cfg.xLabels.map(function(label) {
|
||||
return '<span>' + label + '</span>';
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function renderMode(mode) {
|
||||
var cfg = dataMap[mode];
|
||||
var value = getValue(cfg);
|
||||
document.getElementById('dateText').textContent = cfg.dateText;
|
||||
document.getElementById('rangeText').textContent = cfg.rangeText;
|
||||
document.getElementById('mainValue').textContent = formatValue(value, cfg.decimals);
|
||||
document.getElementById('mainUnit').textContent = cfg.unit;
|
||||
document.getElementById('statusBadge').textContent = cfg.status;
|
||||
|
||||
document.getElementById('maxValue').textContent = formatValue(cfg.max.v, 0);
|
||||
document.getElementById('maxHint').textContent = cfg.max.hint;
|
||||
document.getElementById('minValue').textContent = formatValue(cfg.min.v, 0);
|
||||
document.getElementById('minHint').textContent = cfg.min.hint;
|
||||
document.getElementById('avgValue').textContent = formatValue(cfg.avg.v, 0);
|
||||
document.getElementById('avgHint').textContent = cfg.avg.hint;
|
||||
|
||||
renderChart(cfg);
|
||||
}
|
||||
|
||||
document.querySelectorAll('.time-tab').forEach(function(tab) {
|
||||
tab.onclick = function() {
|
||||
document.querySelectorAll('.time-tab').forEach(function(item) { item.classList.remove('active'); });
|
||||
tab.classList.add('active');
|
||||
renderMode(tab.getAttribute('data-mode'));
|
||||
};
|
||||
});
|
||||
|
||||
renderMode('day');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,278 @@
|
||||
<!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; 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; }
|
||||
/* 设备状态 */
|
||||
.device-bar { margin: 12px 12px 0; background: linear-gradient(135deg, #13c2c2 0%, #0d9b9b 100%); border-radius: 12px; padding: 14px 16px; display: flex; align-items: center; gap: 12px; color: #fff; }
|
||||
.device-icon { width: 44px; height: 44px; background: rgba(255,255,255,0.2); border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 24px; flex-shrink: 0; }
|
||||
.device-info { flex: 1; }
|
||||
.device-name { font-size: 15px; font-weight: 600; }
|
||||
.device-meta { font-size: 12px; opacity: 0.85; margin-top: 2px; }
|
||||
.device-battery { display: flex; align-items: center; gap: 4px; font-size: 13px; font-weight: 600; }
|
||||
.battery-icon { width: 22px; height: 12px; border: 1.5px solid #fff; border-radius: 2px; position: relative; }
|
||||
.battery-icon::after { content: ''; position: absolute; right: -4px; top: 2.5px; width: 2px; height: 5px; background: #fff; border-radius: 0 1px 1px 0; }
|
||||
.battery-fill { height: 100%; background: #fff; border-radius: 1px; }
|
||||
/* 监测卡片网格 */
|
||||
.monitor-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; padding: 12px; }
|
||||
.monitor-card { background: #fff; border-radius: 12px; padding: 16px; cursor: pointer; position: relative; transition: transform 0.15s; }
|
||||
.monitor-card:active { transform: scale(0.97); }
|
||||
.monitor-card--full { grid-column: 1 / -1; }
|
||||
.card-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
|
||||
.card-header__left { display: flex; align-items: center; min-width: 0; flex: 1; }
|
||||
.card-header__right { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
|
||||
.card-icon { width: 32px; height: 32px; border-radius: 8px; display: flex; align-items: center; justify-content: center; font-size: 18px; flex-shrink: 0; }
|
||||
.card-label { font-size: 13px; color: #666; margin-left: 8px; flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.card-meta { font-size: 12px; color: #999; }
|
||||
.card-alert-badge { width: 18px; height: 18px; background: #ff4d4f; border-radius: 50%; font-size: 10px; color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 700; }
|
||||
.card-arrow { width: 16px; height: 16px; display: flex; align-items: center; justify-content: center; }
|
||||
.card-arrow svg { width: 16px; height: 16px; display: block; }
|
||||
.card-sync { font-size: 10px; color: #bbb; margin-top: 8px; }
|
||||
.card-value { font-size: 28px; font-weight: 800; color: #1a1a1a; line-height: 1.1; }
|
||||
.card-unit { font-size: 13px; color: #999; font-weight: 400; margin-left: 2px; }
|
||||
.card-status { display: inline-block; font-size: 11px; padding: 2px 8px; border-radius: 4px; margin-top: 6px; }
|
||||
.card-status--normal { color: #52c41a; background: #f6ffed; }
|
||||
.card-status--warn { color: #faad14; background: #fffbe6; }
|
||||
.card-status--danger { color: #ff4d4f; background: #fff2f0; }
|
||||
.card-sub { font-size: 11px; color: #999; margin-top: 6px; }
|
||||
.card-progress { margin-top: 8px; }
|
||||
.card-progress__bar { height: 6px; background: #f0f0f0; border-radius: 3px; overflow: hidden; }
|
||||
.card-progress__fill { height: 100%; border-radius: 3px; transition: width 0.3s; }
|
||||
.card-progress__text { font-size: 11px; color: #999; margin-top: 4px; }
|
||||
/* 睡眠分段 */
|
||||
.sleep-segments { display: flex; gap: 4px; margin-top: 8px; height: 6px; border-radius: 3px; overflow: hidden; }
|
||||
.sleep-seg { height: 100%; border-radius: 3px; }
|
||||
.sleep-seg--deep { background: #1890ff; }
|
||||
.sleep-seg--light { background: #91d5ff; }
|
||||
.sleep-seg--rem { background: #b37feb; }
|
||||
.sleep-seg--awake { background: #ffd591; }
|
||||
.sleep-legend { display: flex; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
|
||||
.sleep-legend__item { display: flex; align-items: center; gap: 3px; font-size: 10px; color: #999; }
|
||||
.sleep-legend__dot { width: 6px; height: 6px; border-radius: 50%; }
|
||||
/* 锻炼卡片 */
|
||||
.exercise-stats { display: flex; gap: 12px; margin-top: 8px; }
|
||||
.exercise-stat { flex: 1; text-align: center; background: #f5f7fa; border-radius: 8px; padding: 8px 4px; }
|
||||
.exercise-stat__val { font-size: 16px; font-weight: 700; color: #1a1a1a; }
|
||||
.exercise-stat__label { font-size: 10px; color: #999; margin-top: 2px; }
|
||||
/* 预警入口 */
|
||||
.card-alert-link { display: flex; align-items: center; justify-content: center; gap: 4px; font-size: 11px; color: #ff4d4f; margin-top: 8px; padding-top: 8px; border-top: 1px solid #f5f5f5; cursor: pointer; }
|
||||
/* 底部安全区 */
|
||||
.bottom-safe { height: 20px; flex-shrink: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="phone-shell">
|
||||
<div class="status-bar">
|
||||
<span class="time">9:41</span>
|
||||
<div class="icons">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" 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="#333" 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">
|
||||
<div class="nav-back" onclick="history.back()">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round"><path d="M15 19l-7-7 7-7"/></svg>
|
||||
</div>
|
||||
<div class="nav-title">健康监测</div>
|
||||
</div>
|
||||
<div class="scroll-content">
|
||||
<!-- 设备连接状态 -->
|
||||
<div class="device-bar">
|
||||
<div class="device-icon">⌚</div>
|
||||
<div class="device-info">
|
||||
<div class="device-name">华为 WATCH GT5 Pro</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>-->
|
||||
<!-- 72%-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
<!-- 监测卡片网格 -->
|
||||
<div class="monitor-grid">
|
||||
<!-- 步数 -->
|
||||
<div class="monitor-card" onclick="location.href='steps.html'">
|
||||
<div class="card-header">
|
||||
<div class="card-header__left">
|
||||
<div class="card-icon" style="background:#e6f7ff">🏃</div>
|
||||
<span class="card-label">步数</span>
|
||||
</div>
|
||||
<div class="card-header__right">
|
||||
<div class="card-arrow">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18l6-6-6-6"/></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-value">8,562<span class="card-unit">步</span></div>
|
||||
<div class="card-progress">
|
||||
<div class="card-progress__text">相当于步行5.2公里</div>
|
||||
</div>
|
||||
<div class="card-sync">同步至 04-30 09:38</div>
|
||||
</div>
|
||||
<!-- 睡眠 -->
|
||||
<div class="monitor-card" onclick="location.href='sleep.html'">
|
||||
<div class="card-header">
|
||||
<div class="card-header__left">
|
||||
<div class="card-icon" style="background:#f0e6ff">🌙</div>
|
||||
<span class="card-label">睡眠</span>
|
||||
</div>
|
||||
<div class="card-header__right">
|
||||
<div class="card-arrow">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18l6-6-6-6"/></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-value">7<span class="card-unit">h</span>32<span class="card-unit">min</span></div>
|
||||
<div class="card-progress__text">平均睡眠8小时57分</div>
|
||||
<div class="card-sync">同步至 04-30 07:05</div>
|
||||
<!-- <div class="sleep-segments">-->
|
||||
<!-- <div class="sleep-seg sleep-seg--deep" style="width:28%"></div>-->
|
||||
<!-- <div class="sleep-seg sleep-seg--light" style="width:42%"></div>-->
|
||||
<!-- <div class="sleep-seg sleep-seg--rem" style="width:20%"></div>-->
|
||||
<!-- <div class="sleep-seg sleep-seg--awake" style="width:10%"></div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="sleep-legend">-->
|
||||
<!-- <div class="sleep-legend__item"><div class="sleep-legend__dot" style="background:#1890ff"></div>深睡</div>-->
|
||||
<!-- <div class="sleep-legend__item"><div class="sleep-legend__dot" style="background:#91d5ff"></div>浅睡</div>-->
|
||||
<!-- <div class="sleep-legend__item"><div class="sleep-legend__dot" style="background:#b37feb"></div>REM</div>-->
|
||||
<!-- <div class="sleep-legend__item"><div class="sleep-legend__dot" style="background:#ffd591"></div>清醒</div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
<!-- 心率 -->
|
||||
<div class="monitor-card" onclick="location.href='heart-rate.html'">
|
||||
<div class="card-header">
|
||||
<div class="card-header__left">
|
||||
<div class="card-icon" style="background:#fff1f0">❤️</div>
|
||||
<span class="card-label">心率</span>
|
||||
</div>
|
||||
<div class="card-header__right">
|
||||
<div class="card-arrow">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18l6-6-6-6"/></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-value">72<span class="card-unit">bpm</span></div>
|
||||
<div class="card-sub">范围:89~120</div>
|
||||
<div class="card-sync">同步至 04-30 09:37</div>
|
||||
<div class="card-alert-link" onclick="event.stopPropagation();location.href='heart-rate-alerts.html'">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#ff4d4f" stroke-width="2"><path d="M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
查看预警历史
|
||||
</div>
|
||||
</div>
|
||||
<!-- 体温 -->
|
||||
<div class="monitor-card" onclick="location.href='temperature.html'">
|
||||
<div class="card-header">
|
||||
<div class="card-header__left">
|
||||
<div class="card-icon" style="background:#f9f0ff">🌡️</div>
|
||||
<span class="card-label">体温</span>
|
||||
</div>
|
||||
<div class="card-header__right">
|
||||
<div class="card-arrow">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18l6-6-6-6"/></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-value">36.5<span class="card-unit">°C</span></div>
|
||||
<div class="card-sub">范围 36.2~37.1°C</div>
|
||||
<div class="card-sync">同步至 04-30 09:30</div>
|
||||
<div class="card-alert-link" onclick="event.stopPropagation();location.href='temperature-alerts.html'">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#ff4d4f" stroke-width="2"><path d="M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
查看预警历史
|
||||
</div>
|
||||
</div>
|
||||
<!-- 血氧 -->
|
||||
<div class="monitor-card" onclick="location.href='blood-oxygen.html'">
|
||||
<div class="card-header">
|
||||
<div class="card-header__left">
|
||||
<div class="card-icon" style="background:#f6ffed">💧</div>
|
||||
<span class="card-label">血氧</span>
|
||||
</div>
|
||||
<div class="card-header__right">
|
||||
<div class="card-arrow">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18l6-6-6-6"/></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-value">98<span class="card-unit">%</span></div>
|
||||
<div class="card-sub">范围 95~99%</div>
|
||||
<div class="card-sync">同步至 04-30 09:35</div>
|
||||
<div class="card-alert-link" onclick="event.stopPropagation();location.href='blood-oxygen-alerts.html'">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#ff4d4f" stroke-width="2"><path d="M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
查看预警历史
|
||||
</div>
|
||||
</div>
|
||||
<!-- 压力 -->
|
||||
<div class="monitor-card" onclick="location.href='stress.html'">
|
||||
<div class="card-header">
|
||||
<div class="card-header__left">
|
||||
<div class="card-icon" style="background:#fffbe6">🧠</div>
|
||||
<span class="card-label">压力</span>
|
||||
</div>
|
||||
<div class="card-header__right">
|
||||
<div class="card-arrow">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18l6-6-6-6"/></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-value">42</div>
|
||||
<div class="card-sub">范围 18~82</div>
|
||||
<div class="card-sync">同步至 04-30 09:36</div>
|
||||
<div class="card-alert-link" onclick="event.stopPropagation();location.href='stress-alerts.html'">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#ff4d4f" stroke-width="2"><path d="M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
查看预警历史
|
||||
</div>
|
||||
</div>
|
||||
<!-- 锻炼 -->
|
||||
<!-- <div class="monitor-card monitor-card--full" onclick="location.href='exercise.html'">-->
|
||||
<!-- <div class="card-header">-->
|
||||
<!-- <div class="card-header__left">-->
|
||||
<!-- <div class="card-icon" style="background:#fff7e6">🏋️</div>-->
|
||||
<!-- <span class="card-label">锻炼</span>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="card-header__right">-->
|
||||
<!-- <span class="card-meta">本周</span>-->
|
||||
<!-- <div class="card-arrow">-->
|
||||
<!-- <svg viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18l6-6-6-6"/></svg>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="exercise-stats">-->
|
||||
<!-- <div class="exercise-stat">-->
|
||||
<!-- <div class="exercise-stat__val">3<span style="font-size:12px;color:#999;font-weight:400"> 次</span></div>-->
|
||||
<!-- <div class="exercise-stat__label">锻炼次数</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="exercise-stat">-->
|
||||
<!-- <div class="exercise-stat__val">2h15<span style="font-size:12px;color:#999;font-weight:400"> min</span></div>-->
|
||||
<!-- <div class="exercise-stat__label">累计时长</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="exercise-stat">-->
|
||||
<!-- <div class="exercise-stat__val">680<span style="font-size:12px;color:#999;font-weight:400"> kcal</span></div>-->
|
||||
<!-- <div class="exercise-stat__label">消耗热量</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="exercise-stat">-->
|
||||
<!-- <div class="exercise-stat__val">4.2<span style="font-size:12px;color:#999;font-weight:400"> km</span></div>-->
|
||||
<!-- <div class="exercise-stat__label">运动距离</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="card-sync">同步至 04-30 09:20</div>-->
|
||||
<!-- </div>-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-safe"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,309 @@
|
||||
<!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; 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; }
|
||||
/* 核心数据区 */
|
||||
.hero { background: #fff; padding: 24px 16px 20px; text-align: center; }
|
||||
/* 评分圆环 */
|
||||
.hero__ring { width: 160px; height: 160px; margin: 0 auto 12px; position: relative; }
|
||||
.hero__ring svg { width: 100%; height: 100%; transform: rotate(-90deg); }
|
||||
.hero__ring-center { position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%); text-align: center; }
|
||||
.hero__score { font-size: 38px; font-weight: 800; color: #1a1a1a; line-height: 1; }
|
||||
.hero__score-label { font-size: 12px; color: #999; margin-top: 2px; }
|
||||
/* 睡眠时长 */
|
||||
.hero__duration { font-size: 22px; font-weight: 700; color: #1a1a1a; margin-bottom: 4px; }
|
||||
.hero__duration span { font-size: 14px; font-weight: 400; color: #666; }
|
||||
/* 入睡/起床时间 */
|
||||
.hero-times { display: flex; justify-content: center; gap: 40px; margin-top: 14px; }
|
||||
.hero-time { text-align: center; }
|
||||
.hero-time__val { font-size: 20px; font-weight: 700; color: #1a1a1a; }
|
||||
.hero-time__label { font-size: 11px; color: #999; margin-top: 2px; }
|
||||
.hero-time__icon { font-size: 16px; margin-bottom: 2px; }
|
||||
/* 分隔线 */
|
||||
.divider { width: 1px; height: 40px; background: #f0f0f0; align-self: center; }
|
||||
/* 睡眠分段条形图区 */
|
||||
.section { margin: 10px 12px 0; background: #fff; border-radius: 12px; padding: 16px; }
|
||||
.section-title { font-size: 14px; font-weight: 600; color: #1a1a1a; margin-bottom: 14px; }
|
||||
/* 横向分段条 */
|
||||
.stage-bar-wrap { display: flex; border-radius: 6px; overflow: hidden; height: 14px; margin-bottom: 14px; }
|
||||
.stage-bar-seg { height: 100%; transition: width 0.4s; }
|
||||
/* 图例列表 */
|
||||
.stage-legend { display: flex; flex-direction: column; gap: 8px; }
|
||||
.stage-item { display: flex; align-items: center; gap: 8px; }
|
||||
.stage-dot { width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0; }
|
||||
.stage-name { font-size: 12px; color: #666; width: 36px; }
|
||||
.stage-bar-bg { flex: 1; height: 6px; background: #f5f7fa; border-radius: 3px; overflow: hidden; }
|
||||
.stage-bar-fill { height: 100%; border-radius: 3px; }
|
||||
.stage-pct { font-size: 12px; color: #999; width: 30px; text-align: right; }
|
||||
.stage-dur { font-size: 12px; font-weight: 600; color: #1a1a1a; width: 56px; text-align: right; }
|
||||
/* 时间维度Tab */
|
||||
.time-tabs { display: flex; margin: 10px 12px 0; background: #fff; border-radius: 10px; overflow: hidden; }
|
||||
.time-tab { flex: 1; text-align: center; padding: 10px 0; font-size: 13px; color: #666; cursor: pointer; }
|
||||
.time-tab.active { background: #1890ff; color: #fff; border-radius: 10px; font-weight: 600; }
|
||||
/* 睡眠深度曲线 */
|
||||
.depth-chart { width: 100%; height: 80px; }
|
||||
.depth-axis { display: flex; justify-content: space-between; font-size: 10px; color: #bbb; margin-top: 4px; }
|
||||
/* 近7天趋势 */
|
||||
.trend-chart { width: 100%; height: 100px; }
|
||||
.trend-axis { display: flex; justify-content: space-between; font-size: 10px; color: #bbb; margin-top: 4px; }
|
||||
/* 统计摘要 */
|
||||
.summary { display: flex; gap: 8px; margin: 10px 12px 0; }
|
||||
.summary-card { flex: 1; background: #fff; border-radius: 12px; padding: 14px 8px; text-align: center; }
|
||||
.summary-card__val { font-size: 18px; font-weight: 700; color: #1a1a1a; line-height: 1.2; }
|
||||
.summary-card__unit { font-size: 11px; color: #999; }
|
||||
.summary-card__label { font-size: 11px; color: #999; margin-top: 4px; }
|
||||
/* 底部安全区 */
|
||||
.bottom-safe { height: 20px; flex-shrink: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="phone-shell">
|
||||
<!-- 状态栏 -->
|
||||
<div class="status-bar">
|
||||
<span class="time">9:41</span>
|
||||
<div class="icons">
|
||||
<!-- WiFi图标 -->
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" 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="#333" 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">
|
||||
<div class="nav-back" onclick="location.href='index.html'">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round"><path d="M15 19l-7-7 7-7"/></svg>
|
||||
</div>
|
||||
<div class="nav-title">睡眠</div>
|
||||
</div>
|
||||
<!-- 滚动内容区 -->
|
||||
<div class="scroll-content">
|
||||
<!-- 核心数据区:评分圆环 + 时长 + 入睡/起床 -->
|
||||
<div class="hero">
|
||||
<!-- 睡眠评分圆环 -->
|
||||
<div class="hero__ring">
|
||||
<svg viewBox="0 0 160 160">
|
||||
<defs>
|
||||
<linearGradient id="sleepGrad" x1="0" y1="0" x2="1" y2="1">
|
||||
<stop offset="0%" stop-color="#1890ff"/>
|
||||
<stop offset="100%" stop-color="#b37feb"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<!-- 背景圆环 -->
|
||||
<circle cx="80" cy="80" r="70" fill="none" stroke="#f0f0f0" stroke-width="10"/>
|
||||
<!-- 评分圆弧:85分 = 85% 周长,周长=2π×70≈439.8,85%≈373.8,偏移=439.8-373.8=66 -->
|
||||
<circle cx="80" cy="80" r="70" fill="none" stroke="url(#sleepGrad)" stroke-width="10" stroke-linecap="round" stroke-dasharray="439.8" stroke-dashoffset="66"/>
|
||||
</svg>
|
||||
<div class="hero__ring-center">
|
||||
<div class="hero__score">85</div>
|
||||
<div class="hero__score-label">睡眠评分</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 睡眠时长 -->
|
||||
<div class="hero__duration">7<span>h</span> 32<span>min</span></div>
|
||||
<!-- 入睡 / 起床时间 -->
|
||||
<div class="hero-times">
|
||||
<div class="hero-time">
|
||||
<div class="hero-time__icon">🌙</div>
|
||||
<div class="hero-time__val">23:12</div>
|
||||
<div class="hero-time__label">入睡</div>
|
||||
</div>
|
||||
<div class="divider"></div>
|
||||
<div class="hero-time">
|
||||
<div class="hero-time__icon">☀️</div>
|
||||
<div class="hero-time__val">06:44</div>
|
||||
<div class="hero-time__label">起床</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 睡眠分段条形图 -->
|
||||
<div class="section">
|
||||
<div class="section-title">睡眠阶段</div>
|
||||
<!-- 横向分段总条 -->
|
||||
<div class="stage-bar-wrap">
|
||||
<!-- 深睡 28% -->
|
||||
<div class="stage-bar-seg" style="width:28%;background:#1890ff;"></div>
|
||||
<!-- 浅睡 42% -->
|
||||
<div class="stage-bar-seg" style="width:42%;background:#91d5ff;"></div>
|
||||
<!-- REM 20% -->
|
||||
<div class="stage-bar-seg" style="width:20%;background:#b37feb;"></div>
|
||||
<!-- 清醒 10% -->
|
||||
<div class="stage-bar-seg" style="width:10%;background:#ffd591;"></div>
|
||||
</div>
|
||||
<!-- 各阶段图例 + 进度条 -->
|
||||
<div class="stage-legend">
|
||||
<!-- 深睡 -->
|
||||
<div class="stage-item">
|
||||
<div class="stage-dot" style="background:#1890ff;"></div>
|
||||
<div class="stage-name">深睡</div>
|
||||
<div class="stage-bar-bg"><div class="stage-bar-fill" style="width:28%;background:#1890ff;"></div></div>
|
||||
<div class="stage-pct">28%</div>
|
||||
<div class="stage-dur">2h 06min</div>
|
||||
</div>
|
||||
<!-- 浅睡 -->
|
||||
<div class="stage-item">
|
||||
<div class="stage-dot" style="background:#91d5ff;"></div>
|
||||
<div class="stage-name">浅睡</div>
|
||||
<div class="stage-bar-bg"><div class="stage-bar-fill" style="width:42%;background:#91d5ff;"></div></div>
|
||||
<div class="stage-pct">42%</div>
|
||||
<div class="stage-dur">3h 10min</div>
|
||||
</div>
|
||||
<!-- REM -->
|
||||
<div class="stage-item">
|
||||
<div class="stage-dot" style="background:#b37feb;"></div>
|
||||
<div class="stage-name">REM</div>
|
||||
<div class="stage-bar-bg"><div class="stage-bar-fill" style="width:20%;background:#b37feb;"></div></div>
|
||||
<div class="stage-pct">20%</div>
|
||||
<div class="stage-dur">1h 30min</div>
|
||||
</div>
|
||||
<!-- 清醒 -->
|
||||
<div class="stage-item">
|
||||
<div class="stage-dot" style="background:#ffd591;"></div>
|
||||
<div class="stage-name">清醒</div>
|
||||
<div class="stage-bar-bg"><div class="stage-bar-fill" style="width:10%;background:#ffd591;"></div></div>
|
||||
<div class="stage-pct">10%</div>
|
||||
<div class="stage-dur">46min</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 时间维度Tab -->
|
||||
<div class="time-tabs">
|
||||
<div class="time-tab active">日</div>
|
||||
<div class="time-tab">周</div>
|
||||
<div class="time-tab">月</div>
|
||||
</div>
|
||||
<!-- 24h睡眠深度曲线 -->
|
||||
<div class="section">
|
||||
<div class="section-title">睡眠深度曲线</div>
|
||||
<svg class="depth-chart" id="depthChart" viewBox="0 0 320 80" preserveAspectRatio="none"></svg>
|
||||
<div class="depth-axis"><span>22:00</span><span>00:00</span><span>02:00</span><span>04:00</span><span>06:00</span><span>07:00</span></div>
|
||||
</div>
|
||||
<!-- 近7天趋势 -->
|
||||
<div class="section">
|
||||
<div class="section-title">近 7 天趋势</div>
|
||||
<svg class="trend-chart" id="trendChart" viewBox="0 0 320 100" preserveAspectRatio="none"></svg>
|
||||
<div class="trend-axis"><span>4/24</span><span>4/25</span><span>4/26</span><span>4/27</span><span>4/28</span><span>4/29</span><span>4/30</span></div>
|
||||
</div>
|
||||
<!-- 统计摘要 -->
|
||||
<div class="summary">
|
||||
<div class="summary-card">
|
||||
<div class="summary-card__val">7h<br>20min</div>
|
||||
<div class="summary-card__label">7日平均</div>
|
||||
</div>
|
||||
<div class="summary-card">
|
||||
<div class="summary-card__val">8h<br>06min</div>
|
||||
<div class="summary-card__label">最长睡眠</div>
|
||||
</div>
|
||||
<div class="summary-card">
|
||||
<div class="summary-card__val">82</div>
|
||||
<div class="summary-card__unit">分</div>
|
||||
<div class="summary-card__label">睡眠规律性</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-safe"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
/* ---- 24h睡眠深度曲线(SVG路径,模拟真实睡眠波形) ---- */
|
||||
(function() {
|
||||
/* 睡眠深度数据:0=清醒, 1=浅睡, 2=深睡, 3=REM,共48个采样点(每15分钟一个) */
|
||||
/* 时间范围:22:00 ~ 07:00,共9小时 = 36个15分钟 */
|
||||
var depthData = [
|
||||
0, 0, 1, 1, 2, 2, 2, 3, 3, 2, /* 22:00-24:30 入睡过渡 */
|
||||
2, 2, 3, 3, 1, 1, 2, 2, 2, 3, /* 00:30-03:00 深睡阶段 */
|
||||
3, 2, 1, 1, 0, 1, 2, 2, 3, 3, /* 03:00-05:30 REM循环 */
|
||||
2, 1, 1, 0, 0, 0 /* 05:30-07:00 浅睡至清醒 */
|
||||
];
|
||||
var n = depthData.length;
|
||||
var w = 320, h = 80;
|
||||
var padT = 8, padB = 8;
|
||||
var chartH = h - padT - padB;
|
||||
/* 深度值映射:0=清醒(顶部), 3=深睡(底部) */
|
||||
function yOf(d) { return padT + (d / 3) * chartH; }
|
||||
/* 生成平滑路径点 */
|
||||
var pts = depthData.map(function(d, i) {
|
||||
return { x: (i / (n - 1)) * w, y: yOf(d) };
|
||||
});
|
||||
/* 构建平滑曲线(使用三次贝塞尔近似) */
|
||||
var path = 'M ' + pts[0].x.toFixed(1) + ',' + pts[0].y.toFixed(1);
|
||||
for (var i = 1; i < pts.length; i++) {
|
||||
var prev = pts[i - 1], cur = pts[i];
|
||||
var cpx = (prev.x + cur.x) / 2;
|
||||
path += ' C ' + cpx.toFixed(1) + ',' + prev.y.toFixed(1) + ' ' + cpx.toFixed(1) + ',' + cur.y.toFixed(1) + ' ' + cur.x.toFixed(1) + ',' + cur.y.toFixed(1);
|
||||
}
|
||||
/* 填充区域路径 */
|
||||
var areaPath = path + ' L ' + w + ',' + h + ' L 0,' + h + ' Z';
|
||||
var svg = document.getElementById('depthChart');
|
||||
svg.innerHTML =
|
||||
'<defs>' +
|
||||
'<linearGradient id="depthGrad" x1="0" y1="0" x2="0" y2="1">' +
|
||||
'<stop offset="0%" stop-color="#1890ff" stop-opacity="0.35"/>' +
|
||||
'<stop offset="100%" stop-color="#1890ff" stop-opacity="0.04"/>' +
|
||||
'</linearGradient>' +
|
||||
'</defs>' +
|
||||
'<path d="' + areaPath + '" fill="url(#depthGrad)"/>' +
|
||||
'<path d="' + path + '" fill="none" stroke="#1890ff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>';
|
||||
})();
|
||||
|
||||
/* ---- 近7天睡眠时长趋势折线图 ---- */
|
||||
(function() {
|
||||
/* 单位:小时 */
|
||||
var weekData = [7.2, 6.8, 7.5, 8.1, 6.5, 7.8, 7.5];
|
||||
var n = weekData.length;
|
||||
var w = 320, h = 100;
|
||||
var padT = 10, padB = 10;
|
||||
var chartH = h - padT - padB;
|
||||
var wMax = Math.max.apply(null, weekData);
|
||||
var wMin = Math.min.apply(null, weekData);
|
||||
var range = wMax - wMin || 1;
|
||||
/* 计算各点坐标 */
|
||||
var pts = weekData.map(function(v, i) {
|
||||
return {
|
||||
x: (i / (n - 1)) * w,
|
||||
y: padT + (1 - (v - wMin) / range) * chartH
|
||||
};
|
||||
});
|
||||
var line = pts.map(function(p) { return p.x.toFixed(1) + ',' + p.y.toFixed(1); }).join(' ');
|
||||
var area = '0,' + h + ' ' + line + ' ' + w + ',' + h;
|
||||
var svg = document.getElementById('trendChart');
|
||||
svg.innerHTML =
|
||||
'<defs>' +
|
||||
'<linearGradient id="trendGrad" x1="0" y1="0" x2="0" y2="1">' +
|
||||
'<stop offset="0%" stop-color="#1890ff" stop-opacity="0.3"/>' +
|
||||
'<stop offset="100%" stop-color="#1890ff" stop-opacity="0.02"/>' +
|
||||
'</linearGradient>' +
|
||||
'</defs>' +
|
||||
'<polygon points="' + area + '" fill="url(#trendGrad)"/>' +
|
||||
'<polyline points="' + line + '" fill="none" stroke="#1890ff" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>';
|
||||
/* 数据点圆圈 */
|
||||
pts.forEach(function(p) {
|
||||
svg.innerHTML += '<circle cx="' + p.x.toFixed(1) + '" cy="' + p.y.toFixed(1) + '" r="4" fill="#fff" stroke="#1890ff" stroke-width="2"/>';
|
||||
});
|
||||
})();
|
||||
|
||||
/* ---- 时间维度Tab切换 ---- */
|
||||
document.querySelectorAll('.time-tab').forEach(function(tab) {
|
||||
tab.onclick = function() {
|
||||
document.querySelectorAll('.time-tab').forEach(function(t) { t.classList.remove('active'); });
|
||||
tab.classList.add('active');
|
||||
};
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,283 @@
|
||||
<!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; 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; }
|
||||
.top-panel { background: #fff; padding-top: 4px; }
|
||||
.time-tabs { display: flex; justify-content: center; gap: 42px; padding: 4px 0 14px; }
|
||||
.time-tab { position: relative; font-size: 18px; color: #444; cursor: pointer; padding: 0 2px 8px; user-select: none; }
|
||||
.time-tab.active { color: #68be5a; }
|
||||
.time-tab.active::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; margin: auto; width: 22px; height: 3px; border-radius: 2px; background: #68be5a; }
|
||||
.summary-area { text-align: center; padding: 18px 24px 8px; }
|
||||
.date-row { display: inline-flex; align-items: center; gap: 6px; font-size: 18px; color: #666; font-weight: 500; }
|
||||
.range-text { margin-top: 8px; font-size: 18px; color: #666; }
|
||||
.steps-main { margin-top: 4px; display: inline-flex; align-items: baseline; gap: 4px; }
|
||||
.steps-main__value { font-size: 58px; line-height: 1; font-weight: 500; color: #1f1f1f; letter-spacing: -1px; }
|
||||
.steps-main__unit { font-size: 21px; color: #333; }
|
||||
.chart-wrap { position: relative; background: #fff; padding: 10px 16px 0; }
|
||||
.chart-box { position: relative; height: 258px; }
|
||||
.chart-svg { width: 100%; height: 100%; display: block; }
|
||||
.chart-grid line { stroke: #ececec; stroke-width: 1; }
|
||||
.chart-path { fill: none; stroke: #74c26b; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
|
||||
.chart-dot { fill: #74c26b; }
|
||||
.y-axis-labels { position: absolute; top: 6px; right: 0; width: 56px; height: 208px; pointer-events: none; }
|
||||
.y-axis-label { position: absolute; right: 0; transform: translateY(50%); font-size: 12px; color: #666; }
|
||||
.x-axis { display: grid; gap: 0; padding: 8px 14px 0 0; font-size: 12px; color: #666; }
|
||||
.x-axis span { text-align: center; white-space: nowrap; }
|
||||
.x-axis--dense { font-size: 10px; }
|
||||
.timeline-knob-row { position: relative; margin: 2px 0 0; height: 30px; }
|
||||
.timeline-track { position: absolute; left: 0; right: 0; top: 14px; height: 1px; background: #e8e8e8; }
|
||||
.timeline-knob { position: absolute; right: 16px; top: 1px; width: 32px; height: 32px; border-radius: 50%; background: #fff; box-shadow: 0 2px 10px rgba(0,0,0,0.12); }
|
||||
.card { margin: 12px 12px 0; background: #fff; border-radius: 22px; padding: 20px 18px 18px; }
|
||||
.card-head { display: flex; align-items: center; justify-content: space-between; }
|
||||
.card-title { font-size: 16px; font-weight: 600; color: #222; }
|
||||
.edit-link { display: inline-flex; align-items: center; gap: 4px; font-size: 14px; color: #555; }
|
||||
.goal-row { margin-top: 18px; display: flex; align-items: baseline; gap: 2px; color: #1f1f1f; }
|
||||
.goal-row__current { font-size: 22px; font-weight: 600; }
|
||||
.goal-row__divider, .goal-row__target, .goal-row__unit { font-size: 14px; color: #666; }
|
||||
.goal-progress { margin-top: 18px; height: 26px; background: #f1f1f1; border-radius: 13px; position: relative; overflow: hidden; }
|
||||
.goal-progress__fill { position: absolute; left: 0; top: 0; bottom: 0; width: 0; border-radius: 13px; background: linear-gradient(90deg, #58c45c 0%, #86df75 100%); }
|
||||
.goal-progress__marker { position: absolute; left: 0; top: 50%; width: 18px; height: 18px; border-radius: 50%; transform: translate(-50%, -50%); background: #fff; box-shadow: 0 1px 4px rgba(0,0,0,0.14); border: 1px solid #ededed; display: flex; align-items: center; justify-content: center; }
|
||||
.goal-progress__marker::before { content: '🏃'; font-size: 9px; line-height: 1; filter: grayscale(1); opacity: 0.55; }
|
||||
.motivation-row { margin-top: 22px; display: flex; align-items: center; justify-content: space-between; gap: 12px; }
|
||||
.motivation-text { font-size: 15px; color: #333; }
|
||||
.walk-btn { flex-shrink: 0; min-width: 92px; height: 36px; border-radius: 18px; background: #f4f8ef; color: #7bc86b; display: flex; align-items: center; justify-content: center; font-size: 16px; font-weight: 500; }
|
||||
.section-divider { height: 1px; background: #ececec; margin: 18px 0 14px; }
|
||||
.metric-row { display: flex; align-items: flex-end; justify-content: space-between; padding: 10px 0; }
|
||||
.metric-left__label { font-size: 14px; color: #777; margin-bottom: 6px; }
|
||||
.metric-left__value { display: flex; align-items: baseline; gap: 4px; }
|
||||
.metric-left__num { font-size: 18px; font-weight: 600; color: #222; }
|
||||
.metric-left__unit { font-size: 14px; color: #777; }
|
||||
.metric-right { font-size: 14px; color: #777; text-align: right; }
|
||||
.metric-split { height: 1px; background: #ececec; }
|
||||
.foot-note { padding: 14px 0 20px; text-align: center; font-size: 12px; color: #b3b3b3; }
|
||||
.bottom-safe { height: 20px; flex-shrink: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="phone-shell">
|
||||
<div class="status-bar">
|
||||
<span class="time">9:41</span>
|
||||
<div class="icons">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" 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="#333" 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">
|
||||
<div class="nav-back" onclick="location.href='index.html'">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round"><path d="M15 19l-7-7 7-7"/></svg>
|
||||
</div>
|
||||
<div class="nav-title">步数</div>
|
||||
</div>
|
||||
<div class="scroll-content">
|
||||
<div class="top-panel">
|
||||
<div class="time-tabs">
|
||||
<div class="time-tab active" data-mode="day">日</div>
|
||||
<div class="time-tab" data-mode="week">周</div>
|
||||
<div class="time-tab" data-mode="month">月</div>
|
||||
<div class="time-tab" data-mode="year">年</div>
|
||||
</div>
|
||||
<div class="summary-area">
|
||||
<div class="date-row">
|
||||
<span id="dateText">4月30日 周四</span>
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="#666"><path d="M7 10l5 5 5-5z"/></svg>
|
||||
</div>
|
||||
<div class="range-text" id="rangeText">00:00-23:59</div>
|
||||
<div class="steps-main">
|
||||
<span class="steps-main__value" id="totalSteps">1,869</span>
|
||||
<span class="steps-main__unit">步</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-wrap">
|
||||
<div class="chart-box">
|
||||
<svg class="chart-svg" id="stepChart" viewBox="0 0 358 258" preserveAspectRatio="none">
|
||||
<g class="chart-grid" id="chartGrid"></g>
|
||||
<path id="stepLine" class="chart-path"></path>
|
||||
<circle id="stepDot" class="chart-dot" r="3.2"></circle>
|
||||
</svg>
|
||||
<div class="y-axis-labels" id="yAxisLabels"></div>
|
||||
</div>
|
||||
<div class="x-axis" id="xAxis"></div>
|
||||
<div class="timeline-knob-row">
|
||||
<div class="timeline-track"></div>
|
||||
<div class="timeline-knob"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
|
||||
<div class="metric-row">
|
||||
<div class="metric-left">
|
||||
<div class="metric-left__label">消耗</div>
|
||||
<div class="metric-left__value">
|
||||
<span class="metric-left__num" id="calorieValue">55</span>
|
||||
<span class="metric-left__unit">千卡</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="metric-right" id="calorieCompare">相当于消耗 1 个鸡蛋</div>
|
||||
</div>
|
||||
|
||||
<div class="metric-split"></div>
|
||||
|
||||
<div class="metric-row">
|
||||
<div class="metric-left">
|
||||
<div class="metric-left__label">距离</div>
|
||||
<div class="metric-left__value">
|
||||
<span class="metric-left__num" id="distanceValue">1.33</span>
|
||||
<span class="metric-left__unit">公里</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="metric-right" id="distanceCompare">相当于走了 3.34 圈标准操场</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="foot-note">以上数据由步数换算而成</div>
|
||||
<div class="bottom-safe"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var dataMap = {
|
||||
day: {
|
||||
dateText: '4月30日 周四',
|
||||
rangeText: '00:00-23:59',
|
||||
goal: 10000,
|
||||
points: [0,0,0,0,0,0,0,30,60,80,90,110,130,180,240,320,420,560,720,960,1210,1480,1680,1869],
|
||||
totalMode: 'last',
|
||||
yTicks: [12000, 9000, 6000, 3000, 0],
|
||||
xLabels: ['00:00','06:00','12:00','18:00','24:00']
|
||||
},
|
||||
week: {
|
||||
dateText: '4月27日-5月3日',
|
||||
rangeText: '周一-周日',
|
||||
goal: 70000,
|
||||
points: [8320, 9640, 10280, 1869, 7560, 5410, 5660],
|
||||
totalMode: 'sum',
|
||||
yTicks: [12000, 9000, 6000, 3000, 0],
|
||||
xLabels: ['周一','周二','周三','周四','周五','周六','周日']
|
||||
},
|
||||
month: {
|
||||
dateText: '2026年4月',
|
||||
rangeText: '4月1日-4月30日',
|
||||
goal: 300000,
|
||||
points: [6820,7540,8930,10220,11840,9650,8420,7340,9680,10420,8890,9120,10330,11540,10980,8450,7920,9380,10110,12040,11420,9860,8750,9640,10820,11360,9240,10150,8350,1869],
|
||||
totalMode: 'sum',
|
||||
yTicks: [12000, 9000, 6000, 3000, 0],
|
||||
xLabels: ['1日','7日','14日','21日','30日']
|
||||
},
|
||||
year: {
|
||||
dateText: '2026年',
|
||||
rangeText: '1月-12月',
|
||||
goal: 3650000,
|
||||
points: [86210, 91420, 95860, 278509, 102340, 98760, 104220, 109680, 113450, 118020, 110340, 106580],
|
||||
totalMode: 'sum',
|
||||
yTicks: [300000, 225000, 150000, 75000, 0],
|
||||
xLabels: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月']
|
||||
}
|
||||
};
|
||||
|
||||
function formatNumber(num) {
|
||||
return Number(num).toLocaleString('zh-CN');
|
||||
}
|
||||
|
||||
function getTotal(cfg) {
|
||||
if (cfg.totalMode === 'last') return cfg.points[cfg.points.length - 1];
|
||||
return cfg.points.reduce(function(sum, item) { return sum + item; }, 0);
|
||||
}
|
||||
|
||||
function getDistance(total) {
|
||||
return (total * 0.0007116).toFixed(2);
|
||||
}
|
||||
|
||||
function getCalories(total) {
|
||||
return Math.round(total * 0.02943);
|
||||
}
|
||||
|
||||
function renderChart(cfg) {
|
||||
var chartWidth = 330;
|
||||
var chartHeight = 208;
|
||||
var startY = 22;
|
||||
var stepX = chartWidth / (cfg.points.length - 1 || 1);
|
||||
var maxY = cfg.yTicks[0];
|
||||
var grid = document.getElementById('chartGrid');
|
||||
var yAxis = document.getElementById('yAxisLabels');
|
||||
var xAxis = document.getElementById('xAxis');
|
||||
var lineEl = document.getElementById('stepLine');
|
||||
var dotEl = document.getElementById('stepDot');
|
||||
|
||||
grid.innerHTML = '';
|
||||
cfg.yTicks.forEach(function(item, index) {
|
||||
var y = startY + (chartHeight / (cfg.yTicks.length - 1)) * index;
|
||||
grid.innerHTML += '<line x1="0" y1="' + y.toFixed(1) + '" x2="330" y2="' + y.toFixed(1) + '"></line>';
|
||||
});
|
||||
|
||||
yAxis.innerHTML = cfg.yTicks.map(function(item, index) {
|
||||
return '<span class="y-axis-label" style="top:' + (index * 52) + 'px">' + formatNumber(item) + '</span>';
|
||||
}).join('');
|
||||
|
||||
var points = cfg.points.map(function(v, i) {
|
||||
var x = i * stepX;
|
||||
var y = startY + chartHeight - (v / maxY) * chartHeight;
|
||||
return { x: x, y: y };
|
||||
});
|
||||
|
||||
var d = points.map(function(point, index) {
|
||||
return (index === 0 ? 'M' : 'L') + point.x.toFixed(1) + ',' + point.y.toFixed(1);
|
||||
}).join(' ');
|
||||
lineEl.setAttribute('d', d);
|
||||
|
||||
var last = points[points.length - 1];
|
||||
dotEl.setAttribute('cx', last.x.toFixed(1));
|
||||
dotEl.setAttribute('cy', last.y.toFixed(1));
|
||||
|
||||
xAxis.className = 'x-axis' + (cfg.xLabels.length > 7 ? ' x-axis--dense' : '');
|
||||
xAxis.style.gridTemplateColumns = 'repeat(' + cfg.xLabels.length + ', 1fr)';
|
||||
xAxis.innerHTML = cfg.xLabels.map(function(label) {
|
||||
return '<span>' + label + '</span>';
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function renderMode(mode) {
|
||||
var cfg = dataMap[mode];
|
||||
var total = getTotal(cfg);
|
||||
var distance = getDistance(total);
|
||||
var calories = getCalories(total);
|
||||
var eggs = Math.max(1, Math.round(calories / 55));
|
||||
var laps = (Number(distance) / 0.4).toFixed(2);
|
||||
|
||||
document.getElementById('dateText').textContent = cfg.dateText;
|
||||
document.getElementById('rangeText').textContent = cfg.rangeText;
|
||||
document.getElementById('totalSteps').textContent = formatNumber(total);
|
||||
document.getElementById('calorieValue').textContent = formatNumber(calories);
|
||||
document.getElementById('distanceValue').textContent = distance;
|
||||
document.getElementById('calorieCompare').textContent = '相当于消耗 ' + eggs + ' 个鸡蛋';
|
||||
document.getElementById('distanceCompare').textContent = '相当于走了 ' + laps + ' 圈标准操场';
|
||||
|
||||
renderChart(cfg);
|
||||
}
|
||||
|
||||
document.querySelectorAll('.time-tab').forEach(function(tab) {
|
||||
tab.onclick = function() {
|
||||
document.querySelectorAll('.time-tab').forEach(function(item) { item.classList.remove('active'); });
|
||||
tab.classList.add('active');
|
||||
renderMode(tab.getAttribute('data-mode'));
|
||||
};
|
||||
});
|
||||
|
||||
renderMode('day');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,362 @@
|
||||
<!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;
|
||||
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; }
|
||||
|
||||
/* 预警统计卡片 */
|
||||
.stats-card {
|
||||
margin: 12px 12px 0;
|
||||
background: #fff;
|
||||
border-radius: 14px;
|
||||
padding: 20px 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.stats-card__left { display: flex; flex-direction: column; align-items: flex-start; }
|
||||
.stats-card__label { font-size: 13px; color: #999; margin-bottom: 6px; }
|
||||
.stats-card__count-row { display: flex; align-items: baseline; gap: 4px; }
|
||||
/* 压力预警统计数字使用橙色 */
|
||||
.stats-card__count { font-size: 40px; font-weight: 800; color: #fa8c16; line-height: 1; }
|
||||
.stats-card__unit { font-size: 14px; color: #fa8c16; font-weight: 600; }
|
||||
.stats-card__right { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
|
||||
.stats-card__recent-label { font-size: 12px; color: #999; }
|
||||
.stats-card__recent-time { font-size: 13px; font-weight: 600; color: #333; }
|
||||
|
||||
/* 预警图标装饰(橙色背景圆形) */
|
||||
.stats-card__icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background: #fff7e6;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
/* 列表区块标题 */
|
||||
.section-title {
|
||||
font-size: 13px;
|
||||
color: #999;
|
||||
padding: 14px 16px 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 预警记录卡片 */
|
||||
.alert-card {
|
||||
margin: 0 12px 10px;
|
||||
background: #fff;
|
||||
border-radius: 14px;
|
||||
padding: 14px 14px 14px 12px;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
/* 左侧等级圆点列 */
|
||||
.alert-card__dot-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding-top: 3px;
|
||||
gap: 4px;
|
||||
}
|
||||
.alert-card__dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/* 严重:红色圆点 */
|
||||
.alert-card__dot--critical { background: #ff4d4f; box-shadow: 0 0 0 3px rgba(255,77,79,0.18); }
|
||||
/* 警告:黄色圆点 */
|
||||
.alert-card__dot--warning { background: #faad14; box-shadow: 0 0 0 3px rgba(250,173,20,0.18); }
|
||||
|
||||
/* 卡片主体内容 */
|
||||
.alert-card__body { flex: 1; min-width: 0; }
|
||||
.alert-card__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.alert-card__time { font-size: 13px; color: #666; }
|
||||
.alert-card__badge {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
padding: 2px 8px;
|
||||
border-radius: 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
/* 严重标签:红色 */
|
||||
.alert-card__badge--critical { background: #fff1f0; color: #ff4d4f; }
|
||||
/* 警告标签:黄色 */
|
||||
.alert-card__badge--warning { background: #fffbe6; color: #d48806; }
|
||||
|
||||
/* 监测值行 */
|
||||
.alert-card__value-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 4px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.alert-card__value { font-size: 24px; font-weight: 800; color: #1a1a1a; line-height: 1; }
|
||||
.alert-card__value-unit { font-size: 13px; color: #999; }
|
||||
|
||||
/* 详情行(持续时长等) */
|
||||
.alert-card__detail-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.alert-card__detail-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
.alert-card__detail-item svg { flex-shrink: 0; }
|
||||
|
||||
/* 触发原因说明框 */
|
||||
.alert-card__reason {
|
||||
margin-top: 8px;
|
||||
font-size: 12px;
|
||||
color: #bbb;
|
||||
background: #fafafa;
|
||||
border-radius: 6px;
|
||||
padding: 6px 8px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 底部安全区 */
|
||||
.bottom-safe { height: 20px; flex-shrink: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="phone-shell">
|
||||
|
||||
<!-- 状态栏 -->
|
||||
<div class="status-bar">
|
||||
<span class="time">9:41</span>
|
||||
<div class="icons">
|
||||
<!-- WiFi 图标 -->
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2">
|
||||
<path d="M5 12.55a11 11 0 0 1 14.08 0"/>
|
||||
<path d="M1.42 9a16 16 0 0 1 21.16 0"/>
|
||||
<path d="M8.53 16.11a6 6 0 0 1 6.95 0"/>
|
||||
<circle cx="12" cy="20" r="1" fill="#333" stroke="none"/>
|
||||
</svg>
|
||||
<!-- 电池图标 -->
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2">
|
||||
<rect x="1" y="6" width="18" height="12" rx="2"/>
|
||||
<path d="M21 10v4"/>
|
||||
<rect x="3" y="8" width="12" height="8" rx="1" fill="#333" stroke="none"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 导航栏:返回压力详情页 -->
|
||||
<div class="nav-bar">
|
||||
<div class="nav-back" onclick="location.href='stress.html'">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round">
|
||||
<path d="M15 19l-7-7 7-7"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="nav-title">压力预警历史</div>
|
||||
</div>
|
||||
|
||||
<!-- 滚动内容区 -->
|
||||
<div class="scroll-content">
|
||||
|
||||
<!-- 预警统计卡片 -->
|
||||
<div class="stats-card">
|
||||
<div class="stats-card__left">
|
||||
<div class="stats-card__label">本月预警</div>
|
||||
<!-- 本月预警次数:橙色大字 -->
|
||||
<div class="stats-card__count-row">
|
||||
<span class="stats-card__count">2</span>
|
||||
<span class="stats-card__unit">次</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stats-card__right">
|
||||
<!-- 压力预警图标:橙色脑波/压力符号 -->
|
||||
<div class="stats-card__icon">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<!-- 简化压力波形图标 -->
|
||||
<path d="M3 12 L6 7 L9 15 L12 9 L15 14 L18 10 L21 12"
|
||||
stroke="#fa8c16" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stats-card__recent-label">最近预警时间</div>
|
||||
<div class="stats-card__recent-time">2026-04-30 16:30</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 预警记录列表标题 -->
|
||||
<div class="section-title">预警记录(共 2 条)</div>
|
||||
|
||||
<!-- 预警记录 1:警告 - 2026-04-30 16:30,压力值 82 -->
|
||||
<div class="alert-card">
|
||||
<!-- 左侧警告等级黄色圆点 -->
|
||||
<div class="alert-card__dot-col">
|
||||
<div class="alert-card__dot alert-card__dot--warning"></div>
|
||||
</div>
|
||||
<div class="alert-card__body">
|
||||
<!-- 时间 + 警告等级标签 -->
|
||||
<div class="alert-card__header">
|
||||
<span class="alert-card__time">2026-04-30 16:30</span>
|
||||
<span class="alert-card__badge alert-card__badge--warning">警告</span>
|
||||
</div>
|
||||
<!-- 压力监测值 -->
|
||||
<div class="alert-card__value-row">
|
||||
<span class="alert-card__value">82</span>
|
||||
<span class="alert-card__value-unit">压力值</span>
|
||||
</div>
|
||||
<!-- 持续时长 + 压力标签 -->
|
||||
<div class="alert-card__detail-row">
|
||||
<!-- 时钟图标 + 持续时长 -->
|
||||
<div class="alert-card__detail-item">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<polyline points="12 6 12 12 16 14"/>
|
||||
</svg>
|
||||
<span>持续 25 分钟</span>
|
||||
</div>
|
||||
<!-- 压力类型标签 -->
|
||||
<div class="alert-card__detail-item">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2">
|
||||
<path d="M3 12 L6 8 L9 14 L12 9 L15 13 L18 10 L21 12"/>
|
||||
</svg>
|
||||
<span>压力</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 触发原因 -->
|
||||
<div class="alert-card__reason">触发原因:压力值超过 80 阈值</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 预警记录 2:严重 - 2026-04-22 15:10,压力值 88 -->
|
||||
<div class="alert-card">
|
||||
<!-- 左侧严重等级红色圆点 -->
|
||||
<div class="alert-card__dot-col">
|
||||
<div class="alert-card__dot alert-card__dot--critical"></div>
|
||||
</div>
|
||||
<div class="alert-card__body">
|
||||
<!-- 时间 + 严重等级标签 -->
|
||||
<div class="alert-card__header">
|
||||
<span class="alert-card__time">2026-04-22 15:10</span>
|
||||
<span class="alert-card__badge alert-card__badge--critical">严重</span>
|
||||
</div>
|
||||
<!-- 压力监测值 -->
|
||||
<div class="alert-card__value-row">
|
||||
<span class="alert-card__value">88</span>
|
||||
<span class="alert-card__value-unit">压力值</span>
|
||||
</div>
|
||||
<!-- 持续时长 + 压力标签 -->
|
||||
<div class="alert-card__detail-row">
|
||||
<!-- 时钟图标 + 持续时长 -->
|
||||
<div class="alert-card__detail-item">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<polyline points="12 6 12 12 16 14"/>
|
||||
</svg>
|
||||
<span>持续 40 分钟</span>
|
||||
</div>
|
||||
<!-- 压力类型标签 -->
|
||||
<div class="alert-card__detail-item">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2">
|
||||
<path d="M3 12 L6 8 L9 14 L12 9 L15 13 L18 10 L21 12"/>
|
||||
</svg>
|
||||
<span>压力</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 触发原因 -->
|
||||
<div class="alert-card__reason">触发原因:压力值超过 85 阈值</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部安全区 -->
|
||||
<div class="bottom-safe"></div>
|
||||
</div><!-- /scroll-content -->
|
||||
|
||||
</div><!-- /phone-shell -->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,315 @@
|
||||
<!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; 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; }
|
||||
|
||||
/* 主题色(压力橙) */
|
||||
:root { --theme: #faad14; --theme2: #ffc53d; }
|
||||
|
||||
.top-panel { background: #fff; padding-top: 2px; }
|
||||
.time-tabs { display: flex; justify-content: center; gap: 42px; padding: 2px 0 8px; }
|
||||
.time-tab { position: relative; font-size: 18px; color: #444; cursor: pointer; padding: 0 2px 6px; user-select: none; }
|
||||
.time-tab.active { color: var(--theme); }
|
||||
.time-tab.active::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; margin: auto; width: 22px; height: 3px; border-radius: 2px; background: var(--theme); }
|
||||
|
||||
.summary-area { text-align: center; padding: 12px 24px 6px; }
|
||||
.date-row { display: inline-flex; align-items: center; gap: 6px; font-size: 16px; color: #666; font-weight: 500; }
|
||||
.range-text { margin-top: 4px; font-size: 16px; color: #666; }
|
||||
.main-row { margin-top: 2px; display: inline-flex; align-items: baseline; gap: 4px; }
|
||||
.main-row__value { font-size: 48px; line-height: 1; font-weight: 500; color: #1f1f1f; letter-spacing: -1px; }
|
||||
.main-row__unit { font-size: 18px; color: #333; }
|
||||
.main-badge { display: inline-flex; align-items: center; justify-content: center; margin-top: 6px; padding: 3px 12px; border-radius: 18px; font-size: 12px; font-weight: 600; background: #fffbe6; color: #d48806; }
|
||||
|
||||
.level-tip { margin-top: 12px; padding: 12px 0; font-size: 12px; line-height: 1.6; color: #666; }
|
||||
|
||||
.chart-wrap { position: relative; background: #fff; padding: 6px 16px 0; }
|
||||
.chart-box { position: relative; height: 160px; }
|
||||
.chart-svg { width: 100%; height: 100%; display: block; }
|
||||
.chart-grid line { stroke: #ececec; stroke-width: 1; }
|
||||
.chart-path { fill: none; stroke: var(--theme); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
|
||||
.chart-dot { fill: var(--theme); }
|
||||
.y-axis-labels { position: absolute; top: 6px; right: 0; width: 56px; height: 208px; pointer-events: none; }
|
||||
.y-axis-label { position: absolute; right: 0; transform: translateY(50%); font-size: 12px; color: #666; }
|
||||
.x-axis { display: grid; gap: 0; padding: 8px 14px 0 0; font-size: 12px; color: #666; }
|
||||
.x-axis span { text-align: center; white-space: nowrap; }
|
||||
.x-axis--dense { font-size: 10px; }
|
||||
.timeline-knob-row { position: relative; margin: 0; height: 24px; }
|
||||
.timeline-track { position: absolute; left: 0; right: 0; top: 10px; height: 1px; background: #e8e8e8; }
|
||||
.timeline-knob { position: absolute; right: 16px; top: -4px; width: 24px; height: 24px; border-radius: 50%; background: #fff; box-shadow: 0 2px 10px rgba(0,0,0,0.12); }
|
||||
|
||||
.card { margin: 8px 12px 0; background: #fff; border-radius: 22px; padding: 14px 12px; display: flex; gap: 0; }
|
||||
.metric-row { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 6px 6px; }
|
||||
.metric-left__label { font-size: 12px; color: #777; margin-bottom: 4px; }
|
||||
.metric-left__value { display: flex; align-items: baseline; gap: 2px; }
|
||||
.metric-left__num { font-size: 16px; font-weight: 600; color: #222; }
|
||||
.metric-left__unit { font-size: 12px; color: #777; }
|
||||
.metric-right { font-size: 12px; color: #777; text-align: center; }
|
||||
.metric-split { width: 1px; background: #ececec; margin: 0; }
|
||||
|
||||
.alert-btn { margin: 8px 12px 0; border: 1.5px solid var(--theme); border-radius: 12px; padding: 11px; text-align: center; font-size: 13px; color: var(--theme); font-weight: 600; cursor: pointer; background: #fff; display: flex; align-items: center; justify-content: center; gap: 6px; }
|
||||
|
||||
.foot-note { padding: 10px 0 12px; text-align: center; font-size: 11px; color: #b3b3b3; }
|
||||
.bottom-safe { height: 12px; flex-shrink: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="phone-shell">
|
||||
<div class="status-bar">
|
||||
<span class="time">9:41</span>
|
||||
<div class="icons">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" 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="#333" 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">
|
||||
<div class="nav-back" onclick="location.href='index.html'">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round"><path d="M15 19l-7-7 7-7"/></svg>
|
||||
</div>
|
||||
<div class="nav-title">压力</div>
|
||||
</div>
|
||||
|
||||
<div class="scroll-content">
|
||||
<div class="top-panel">
|
||||
<div class="time-tabs">
|
||||
<div class="time-tab active" data-mode="day">日</div>
|
||||
<div class="time-tab" data-mode="week">周</div>
|
||||
<div class="time-tab" data-mode="month">月</div>
|
||||
<div class="time-tab" data-mode="year">年</div>
|
||||
</div>
|
||||
<div class="summary-area">
|
||||
<div class="date-row">
|
||||
<span id="dateText">4月30日 周四</span>
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="#666"><path d="M7 10l5 5 5-5z"/></svg>
|
||||
</div>
|
||||
<div class="range-text" id="rangeText">00:00-23:59</div>
|
||||
<div class="main-row">
|
||||
<span class="main-row__value" id="mainValue">42</span>
|
||||
<span class="main-row__unit" id="mainUnit">分</span>
|
||||
</div>
|
||||
<div class="main-badge" id="statusBadge">放松</div>
|
||||
<div class="level-tip">压力等级说明:1-29放松 / 30-59正常 / 60-79中等 / 80-100偏高</div>
|
||||
</div>
|
||||
|
||||
<div class="chart-wrap">
|
||||
<div class="chart-box">
|
||||
<svg class="chart-svg" id="chart" viewBox="0 0 358 258" preserveAspectRatio="none">
|
||||
<g class="chart-grid" id="chartGrid"></g>
|
||||
<path id="line" class="chart-path"></path>
|
||||
<circle id="dot" class="chart-dot" r="3.2"></circle>
|
||||
</svg>
|
||||
<div class="y-axis-labels" id="yAxisLabels"></div>
|
||||
</div>
|
||||
<div class="x-axis" id="xAxis"></div>
|
||||
<div class="timeline-knob-row">
|
||||
<div class="timeline-track"></div>
|
||||
<div class="timeline-knob"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="metric-row">
|
||||
<div class="metric-left">
|
||||
<div class="metric-left__label">最高</div>
|
||||
<div class="metric-left__value"><span class="metric-left__num" id="maxValue">82</span><span class="metric-left__unit">分</span></div>
|
||||
</div>
|
||||
<div class="metric-right" id="maxHint">16:30</div>
|
||||
</div>
|
||||
<div class="metric-split"></div>
|
||||
<div class="metric-row">
|
||||
<div class="metric-left">
|
||||
<div class="metric-left__label">最低</div>
|
||||
<div class="metric-left__value"><span class="metric-left__num" id="minValue">18</span><span class="metric-left__unit">分</span></div>
|
||||
</div>
|
||||
<div class="metric-right" id="minHint">05:10</div>
|
||||
</div>
|
||||
<div class="metric-split"></div>
|
||||
<div class="metric-row">
|
||||
<div class="metric-left">
|
||||
<div class="metric-left__label">平均</div>
|
||||
<div class="metric-left__value"><span class="metric-left__num" id="avgValue">46</span><span class="metric-left__unit">分</span></div>
|
||||
</div>
|
||||
<div class="metric-right" id="avgHint">全天</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert-btn" onclick="location.href='stress-alerts.html'">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--theme)" stroke-width="2"><path d="M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
查看预警历史 ›
|
||||
</div>
|
||||
|
||||
<div class="foot-note">以上数据为原型示例,实际以设备同步为准</div>
|
||||
<div class="bottom-safe"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var dataMap = {
|
||||
day: {
|
||||
dateText: '4月30日 周四',
|
||||
rangeText: '00:00-23:59',
|
||||
unit: '分',
|
||||
decimals: 0,
|
||||
points: [35,32,30,28,24,18,22,26,34,40,52,60,68,74,82,78,66,58,49,45,41,38,36,34],
|
||||
totalMode: 'last',
|
||||
yTicks: [100, 80, 60, 40, 20, 0],
|
||||
xLabels: ['0:00','6:00','12:00','18:00','24:00'],
|
||||
status: '放松',
|
||||
max: { v:82, hint:'16:30' },
|
||||
min: { v:18, hint:'05:10' },
|
||||
avg: { v:46, hint:'全天' }
|
||||
},
|
||||
week: {
|
||||
dateText: '4月27日-5月3日',
|
||||
rangeText: '周一-周日',
|
||||
unit: '分',
|
||||
decimals: 0,
|
||||
points: [45,52,38,61,42,55,42],
|
||||
totalMode: 'avg',
|
||||
yTicks: [100, 80, 60, 40, 20, 0],
|
||||
xLabels: ['周一','周二','周三','周四','周五','周六','周日'],
|
||||
status: '正常',
|
||||
max: { v:61, hint:'周四' },
|
||||
min: { v:38, hint:'周三' },
|
||||
avg: { v:48, hint:'本周' }
|
||||
},
|
||||
month: {
|
||||
dateText: '2026年4月',
|
||||
rangeText: '4月1日-4月30日',
|
||||
unit: '分',
|
||||
decimals: 0,
|
||||
points: [42,45,38,48,41,52,39,44,47,50,48,45,41,38,51,53,49,46,43,40,38,42,45,48,51,48,45,42,39,46],
|
||||
totalMode: 'avg',
|
||||
yTicks: [100, 80, 60, 40, 20, 0],
|
||||
xLabels: ['1日','7日','14日','21日','30日'],
|
||||
status: '正常',
|
||||
max: { v:53, hint:'04-16' },
|
||||
min: { v:38, hint:'04-08' },
|
||||
avg: { v:45, hint:'本月' }
|
||||
},
|
||||
year: {
|
||||
dateText: '2026年',
|
||||
rangeText: '1月-12月',
|
||||
unit: '分',
|
||||
decimals: 0,
|
||||
points: [48,45,42,46,48,45,42,45,48,51,49,46],
|
||||
totalMode: 'avg',
|
||||
yTicks: [100, 80, 60, 40, 20, 0],
|
||||
xLabels: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
|
||||
status: '正常',
|
||||
max: { v:51, hint:'10月' },
|
||||
min: { v:42, hint:'03月' },
|
||||
avg: { v:46, hint:'全年' }
|
||||
}
|
||||
};
|
||||
|
||||
function avg(arr) {
|
||||
if (!arr.length) return 0;
|
||||
var sum = arr.reduce(function(s, v){ return s + v; }, 0);
|
||||
return sum / arr.length;
|
||||
}
|
||||
|
||||
function getValue(cfg) {
|
||||
if (cfg.totalMode === 'last') return cfg.points[cfg.points.length - 1];
|
||||
if (cfg.totalMode === 'avg') return avg(cfg.points);
|
||||
if (cfg.totalMode === 'max') return Math.max.apply(null, cfg.points);
|
||||
if (cfg.totalMode === 'min') return Math.min.apply(null, cfg.points);
|
||||
return cfg.points[cfg.points.length - 1];
|
||||
}
|
||||
|
||||
function formatValue(val, decimals) {
|
||||
if (typeof val !== 'number') return String(val);
|
||||
if (decimals != null) return val.toFixed(decimals);
|
||||
return String(val);
|
||||
}
|
||||
|
||||
function renderChart(cfg) {
|
||||
var chartWidth = 330;
|
||||
var chartHeight = 208;
|
||||
var startY = 22;
|
||||
var stepX = chartWidth / (cfg.points.length - 1 || 1);
|
||||
var maxY = cfg.yTicks[0];
|
||||
|
||||
var grid = document.getElementById('chartGrid');
|
||||
var yAxis = document.getElementById('yAxisLabels');
|
||||
var xAxis = document.getElementById('xAxis');
|
||||
var lineEl = document.getElementById('line');
|
||||
var dotEl = document.getElementById('dot');
|
||||
|
||||
grid.innerHTML = '';
|
||||
cfg.yTicks.forEach(function(_, index) {
|
||||
var y = startY + (chartHeight / (cfg.yTicks.length - 1)) * index;
|
||||
grid.innerHTML += '<line x1="0" y1="' + y.toFixed(1) + '" x2="330" y2="' + y.toFixed(1) + '"></line>';
|
||||
});
|
||||
|
||||
yAxis.innerHTML = cfg.yTicks.map(function(tick, index) {
|
||||
return '<span class="y-axis-label" style="top:' + (index * 52) + 'px">' + formatValue(tick, 0) + '</span>';
|
||||
}).join('');
|
||||
|
||||
var pts = cfg.points.map(function(v, i) {
|
||||
var x = i * stepX;
|
||||
var y = startY + chartHeight - (v / maxY) * chartHeight;
|
||||
return { x: x, y: y };
|
||||
});
|
||||
|
||||
var d = pts.map(function(p, index) {
|
||||
return (index === 0 ? 'M' : 'L') + p.x.toFixed(1) + ',' + p.y.toFixed(1);
|
||||
}).join(' ');
|
||||
lineEl.setAttribute('d', d);
|
||||
|
||||
var last = pts[pts.length - 1];
|
||||
dotEl.setAttribute('cx', last.x.toFixed(1));
|
||||
dotEl.setAttribute('cy', last.y.toFixed(1));
|
||||
|
||||
xAxis.className = 'x-axis' + (cfg.xLabels.length > 7 ? ' x-axis--dense' : '');
|
||||
xAxis.style.gridTemplateColumns = 'repeat(' + cfg.xLabels.length + ', 1fr)';
|
||||
xAxis.innerHTML = cfg.xLabels.map(function(label) {
|
||||
return '<span>' + label + '</span>';
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function renderMode(mode) {
|
||||
var cfg = dataMap[mode];
|
||||
var value = getValue(cfg);
|
||||
document.getElementById('dateText').textContent = cfg.dateText;
|
||||
document.getElementById('rangeText').textContent = cfg.rangeText;
|
||||
document.getElementById('mainValue').textContent = formatValue(value, cfg.decimals);
|
||||
document.getElementById('mainUnit').textContent = cfg.unit;
|
||||
document.getElementById('statusBadge').textContent = cfg.status;
|
||||
|
||||
document.getElementById('maxValue').textContent = formatValue(cfg.max.v, cfg.decimals);
|
||||
document.getElementById('maxHint').textContent = cfg.max.hint;
|
||||
document.getElementById('minValue').textContent = formatValue(cfg.min.v, cfg.decimals);
|
||||
document.getElementById('minHint').textContent = cfg.min.hint;
|
||||
document.getElementById('avgValue').textContent = formatValue(cfg.avg.v, cfg.decimals);
|
||||
document.getElementById('avgHint').textContent = cfg.avg.hint;
|
||||
|
||||
renderChart(cfg);
|
||||
}
|
||||
|
||||
document.querySelectorAll('.time-tab').forEach(function(tab) {
|
||||
tab.onclick = function() {
|
||||
document.querySelectorAll('.time-tab').forEach(function(item) { item.classList.remove('active'); });
|
||||
tab.classList.add('active');
|
||||
renderMode(tab.getAttribute('data-mode'));
|
||||
};
|
||||
});
|
||||
|
||||
renderMode('day');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,314 @@
|
||||
<!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;
|
||||
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; }
|
||||
|
||||
/* 预警统计卡片 */
|
||||
.stats-card {
|
||||
margin: 12px 12px 0;
|
||||
background: #fff;
|
||||
border-radius: 14px;
|
||||
padding: 20px 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.stats-card__left { display: flex; flex-direction: column; align-items: flex-start; }
|
||||
.stats-card__label { font-size: 13px; color: #999; margin-bottom: 6px; }
|
||||
.stats-card__count-row { display: flex; align-items: baseline; gap: 4px; }
|
||||
.stats-card__count { font-size: 40px; font-weight: 800; color: #faad14; line-height: 1; }
|
||||
.stats-card__unit { font-size: 14px; color: #faad14; font-weight: 600; }
|
||||
.stats-card__right { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
|
||||
.stats-card__recent-label { font-size: 12px; color: #999; }
|
||||
.stats-card__recent-time { font-size: 13px; font-weight: 600; color: #333; }
|
||||
|
||||
/* 预警图标装饰 */
|
||||
.stats-card__icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background: #fffbe6;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
/* 列表区块标题 */
|
||||
.section-title {
|
||||
font-size: 13px;
|
||||
color: #999;
|
||||
padding: 14px 16px 8px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 预警记录卡片 */
|
||||
.alert-card {
|
||||
margin: 0 12px 10px;
|
||||
background: #fff;
|
||||
border-radius: 14px;
|
||||
padding: 14px 14px 14px 12px;
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
/* 左侧等级圆点 */
|
||||
.alert-card__dot-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding-top: 3px;
|
||||
gap: 4px;
|
||||
}
|
||||
.alert-card__dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.alert-card__dot--critical { background: #ff4d4f; box-shadow: 0 0 0 3px rgba(255,77,79,0.18); }
|
||||
.alert-card__dot--warning { background: #faad14; box-shadow: 0 0 0 3px rgba(250,173,20,0.18); }
|
||||
|
||||
/* 卡片主体内容 */
|
||||
.alert-card__body { flex: 1; min-width: 0; }
|
||||
.alert-card__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.alert-card__time { font-size: 13px; color: #666; }
|
||||
.alert-card__badge {
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
padding: 2px 8px;
|
||||
border-radius: 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.alert-card__badge--critical { background: #fff1f0; color: #ff4d4f; }
|
||||
.alert-card__badge--warning { background: #fffbe6; color: #d48806; }
|
||||
|
||||
/* 监测值 */
|
||||
.alert-card__value-row {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 4px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.alert-card__value { font-size: 24px; font-weight: 800; color: #1a1a1a; line-height: 1; }
|
||||
.alert-card__value-unit { font-size: 13px; color: #999; }
|
||||
|
||||
/* 详情行 */
|
||||
.alert-card__detail-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.alert-card__detail-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
.alert-card__detail-item svg { flex-shrink: 0; }
|
||||
|
||||
/* 触发原因 */
|
||||
.alert-card__reason {
|
||||
margin-top: 8px;
|
||||
font-size: 12px;
|
||||
color: #bbb;
|
||||
background: #fafafa;
|
||||
border-radius: 6px;
|
||||
padding: 6px 8px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* 底部安全区 */
|
||||
.bottom-safe { height: 20px; flex-shrink: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="phone-shell">
|
||||
|
||||
<!-- 状态栏 -->
|
||||
<div class="status-bar">
|
||||
<span class="time">9:41</span>
|
||||
<div class="icons">
|
||||
<!-- WiFi 图标 -->
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2">
|
||||
<path d="M5 12.55a11 11 0 0 1 14.08 0"/>
|
||||
<path d="M1.42 9a16 16 0 0 1 21.16 0"/>
|
||||
<path d="M8.53 16.11a6 6 0 0 1 6.95 0"/>
|
||||
<circle cx="12" cy="20" r="1" fill="#333" stroke="none"/>
|
||||
</svg>
|
||||
<!-- 电池图标 -->
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2">
|
||||
<rect x="1" y="6" width="18" height="12" rx="2"/>
|
||||
<path d="M21 10v4"/>
|
||||
<rect x="3" y="8" width="12" height="8" rx="1" fill="#333" stroke="none"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 导航栏:返回体温详情页 -->
|
||||
<div class="nav-bar">
|
||||
<div class="nav-back" onclick="location.href='temperature.html'">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round">
|
||||
<path d="M15 19l-7-7 7-7"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="nav-title">体温预警历史</div>
|
||||
</div>
|
||||
|
||||
<!-- 滚动内容区 -->
|
||||
<div class="scroll-content">
|
||||
|
||||
<!-- 预警统计卡片 -->
|
||||
<div class="stats-card">
|
||||
<div class="stats-card__left">
|
||||
<div class="stats-card__label">本月预警</div>
|
||||
<div class="stats-card__count-row">
|
||||
<span class="stats-card__count">1</span>
|
||||
<span class="stats-card__unit">次</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stats-card__right">
|
||||
<!-- 体温预警图标 -->
|
||||
<div class="stats-card__icon">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M14 14.76V3.5a2.5 2.5 0 0 0-5 0v11.26a4.5 4.5 0 1 0 5 0z" stroke="#faad14" stroke-width="1.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stats-card__recent-label">最近预警时间</div>
|
||||
<div class="stats-card__recent-time">2026-04-15 13:28</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 预警记录列表标题 -->
|
||||
<div class="section-title">预警记录(共 1 条)</div>
|
||||
|
||||
<!-- 预警记录:警告 - 2026-04-15 -->
|
||||
<div class="alert-card">
|
||||
<!-- 左侧警告等级黄点 -->
|
||||
<div class="alert-card__dot-col">
|
||||
<div class="alert-card__dot alert-card__dot--warning"></div>
|
||||
</div>
|
||||
<div class="alert-card__body">
|
||||
<!-- 时间 + 警告等级标签 -->
|
||||
<div class="alert-card__header">
|
||||
<span class="alert-card__time">2026-04-15 13:28</span>
|
||||
<span class="alert-card__badge alert-card__badge--warning">警告</span>
|
||||
</div>
|
||||
<!-- 体温监测值 -->
|
||||
<div class="alert-card__value-row">
|
||||
<span class="alert-card__value">37.8</span>
|
||||
<span class="alert-card__value-unit">°C</span>
|
||||
</div>
|
||||
<!-- 持续时长 + 体温标签 -->
|
||||
<div class="alert-card__detail-row">
|
||||
<!-- 时钟图标 + 持续时长 -->
|
||||
<div class="alert-card__detail-item">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2">
|
||||
<circle cx="12" cy="12" r="10"/>
|
||||
<polyline points="12 6 12 12 16 14"/>
|
||||
</svg>
|
||||
<span>持续 45 分钟</span>
|
||||
</div>
|
||||
<!-- 体温标签 -->
|
||||
<div class="alert-card__detail-item">
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="#bbb" stroke-width="2">
|
||||
<path d="M14 14.76V3.5a2.5 2.5 0 0 0-5 0v11.26a4.5 4.5 0 1 0 5 0z"/>
|
||||
</svg>
|
||||
<span>体温</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 触发原因 -->
|
||||
<div class="alert-card__reason">触发原因:体温超过 37.3°C 阈值</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部安全区 -->
|
||||
<div class="bottom-safe"></div>
|
||||
</div><!-- /scroll-content -->
|
||||
|
||||
</div><!-- /phone-shell -->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,312 @@
|
||||
<!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; 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; }
|
||||
|
||||
/* 主题色(体温紫) */
|
||||
:root { --theme: #722ed1; --theme2: #b37feb; }
|
||||
|
||||
.top-panel { background: #fff; padding-top: 2px; }
|
||||
.time-tabs { display: flex; justify-content: center; gap: 42px; padding: 2px 0 8px; }
|
||||
.time-tab { position: relative; font-size: 18px; color: #444; cursor: pointer; padding: 0 2px 6px; user-select: none; }
|
||||
.time-tab.active { color: var(--theme); }
|
||||
.time-tab.active::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; margin: auto; width: 22px; height: 3px; border-radius: 2px; background: var(--theme); }
|
||||
|
||||
.summary-area { text-align: center; padding: 12px 24px 6px; }
|
||||
.date-row { display: inline-flex; align-items: center; gap: 6px; font-size: 16px; color: #666; font-weight: 500; }
|
||||
.range-text { margin-top: 4px; font-size: 16px; color: #666; }
|
||||
.main-row { margin-top: 2px; display: inline-flex; align-items: baseline; gap: 4px; }
|
||||
.main-row__value { font-size: 48px; line-height: 1; font-weight: 500; color: #1f1f1f; letter-spacing: -1px; }
|
||||
.main-row__unit { font-size: 18px; color: #333; }
|
||||
.main-badge { display: inline-flex; align-items: center; justify-content: center; margin-top: 6px; padding: 3px 12px; border-radius: 18px; font-size: 12px; font-weight: 600; background: #f6ffed; color: #52c41a; }
|
||||
|
||||
.chart-wrap { position: relative; background: #fff; padding: 6px 16px 0; }
|
||||
.chart-box { position: relative; height: 160px; }
|
||||
.chart-svg { width: 100%; height: 100%; display: block; }
|
||||
.chart-grid line { stroke: #ececec; stroke-width: 1; }
|
||||
.chart-path { fill: none; stroke: var(--theme); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
|
||||
.chart-dot { fill: var(--theme); }
|
||||
.y-axis-labels { position: absolute; top: 6px; right: 0; width: 56px; height: 208px; pointer-events: none; }
|
||||
.y-axis-label { position: absolute; right: 0; transform: translateY(50%); font-size: 12px; color: #666; }
|
||||
.x-axis { display: grid; gap: 0; padding: 8px 14px 0 0; font-size: 12px; color: #666; }
|
||||
.x-axis span { text-align: center; white-space: nowrap; }
|
||||
.x-axis--dense { font-size: 10px; }
|
||||
.timeline-knob-row { position: relative; margin: 0; height: 24px; }
|
||||
.timeline-track { position: absolute; left: 0; right: 0; top: 10px; height: 1px; background: #e8e8e8; }
|
||||
.timeline-knob { position: absolute; right: 16px; top: -4px; width: 24px; height: 24px; border-radius: 50%; background: #fff; box-shadow: 0 2px 10px rgba(0,0,0,0.12); }
|
||||
|
||||
.card { margin: 8px 12px 0; background: #fff; border-radius: 22px; padding: 14px 12px; display: flex; gap: 0; }
|
||||
.metric-row { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 6px 6px; }
|
||||
.metric-left__label { font-size: 12px; color: #777; margin-bottom: 4px; }
|
||||
.metric-left__value { display: flex; align-items: baseline; gap: 2px; }
|
||||
.metric-left__num { font-size: 16px; font-weight: 600; color: #222; }
|
||||
.metric-left__unit { font-size: 12px; color: #777; }
|
||||
.metric-right { font-size: 12px; color: #777; text-align: center; }
|
||||
.metric-split { width: 1px; background: #ececec; margin: 0; }
|
||||
|
||||
.alert-btn { margin: 8px 12px 0; border: 1.5px solid var(--theme); border-radius: 12px; padding: 11px; text-align: center; font-size: 13px; color: var(--theme); font-weight: 600; cursor: pointer; background: #fff; display: flex; align-items: center; justify-content: center; gap: 6px; }
|
||||
|
||||
.foot-note { padding: 10px 0 12px; text-align: center; font-size: 11px; color: #b3b3b3; }
|
||||
.bottom-safe { height: 12px; flex-shrink: 0; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="phone-shell">
|
||||
<div class="status-bar">
|
||||
<span class="time">9:41</span>
|
||||
<div class="icons">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#333" 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="#333" 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">
|
||||
<div class="nav-back" onclick="location.href='index.html'">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round"><path d="M15 19l-7-7 7-7"/></svg>
|
||||
</div>
|
||||
<div class="nav-title">体温</div>
|
||||
</div>
|
||||
|
||||
<div class="scroll-content">
|
||||
<div class="top-panel">
|
||||
<div class="time-tabs">
|
||||
<div class="time-tab active" data-mode="day">日</div>
|
||||
<div class="time-tab" data-mode="week">周</div>
|
||||
<div class="time-tab" data-mode="month">月</div>
|
||||
<div class="time-tab" data-mode="year">年</div>
|
||||
</div>
|
||||
<div class="summary-area">
|
||||
<div class="date-row">
|
||||
<span id="dateText">4月30日 周四</span>
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="#666"><path d="M7 10l5 5 5-5z"/></svg>
|
||||
</div>
|
||||
<div class="range-text" id="rangeText">00:00-23:59</div>
|
||||
<div class="main-row">
|
||||
<span class="main-row__value" id="mainValue">36.5</span>
|
||||
<span class="main-row__unit" id="mainUnit">°C</span>
|
||||
</div>
|
||||
<div class="main-badge" id="statusBadge">正常</div>
|
||||
</div>
|
||||
|
||||
<div class="chart-wrap">
|
||||
<div class="chart-box">
|
||||
<svg class="chart-svg" id="chart" viewBox="0 0 358 258" preserveAspectRatio="none">
|
||||
<g class="chart-grid" id="chartGrid"></g>
|
||||
<path id="line" class="chart-path"></path>
|
||||
<circle id="dot" class="chart-dot" r="3.2"></circle>
|
||||
</svg>
|
||||
<div class="y-axis-labels" id="yAxisLabels"></div>
|
||||
</div>
|
||||
<div class="x-axis" id="xAxis"></div>
|
||||
<div class="timeline-knob-row">
|
||||
<div class="timeline-track"></div>
|
||||
<div class="timeline-knob"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="metric-row">
|
||||
<div class="metric-left">
|
||||
<div class="metric-left__label">最高</div>
|
||||
<div class="metric-left__value"><span class="metric-left__num" id="maxValue">37.1</span><span class="metric-left__unit">°C</span></div>
|
||||
</div>
|
||||
<div class="metric-right" id="maxHint">13:00</div>
|
||||
</div>
|
||||
<div class="metric-split"></div>
|
||||
<div class="metric-row">
|
||||
<div class="metric-left">
|
||||
<div class="metric-left__label">最低</div>
|
||||
<div class="metric-left__value"><span class="metric-left__num" id="minValue">36.2</span><span class="metric-left__unit">°C</span></div>
|
||||
</div>
|
||||
<div class="metric-right" id="minHint">04:20</div>
|
||||
</div>
|
||||
<div class="metric-split"></div>
|
||||
<div class="metric-row">
|
||||
<div class="metric-left">
|
||||
<div class="metric-left__label">平均</div>
|
||||
<div class="metric-left__value"><span class="metric-left__num" id="avgValue">36.6</span><span class="metric-left__unit">°C</span></div>
|
||||
</div>
|
||||
<div class="metric-right" id="avgHint">全天</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="alert-btn" onclick="location.href='temperature-alerts.html'">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="var(--theme)" stroke-width="2"><path d="M12 9v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
|
||||
查看预警历史 ›
|
||||
</div>
|
||||
|
||||
<div class="foot-note">以上数据为原型示例,实际以设备同步为准</div>
|
||||
<div class="bottom-safe"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
var dataMap = {
|
||||
day: {
|
||||
dateText: '4月30日 周四',
|
||||
rangeText: '00:00-23:59',
|
||||
unit: '°C',
|
||||
decimals: 1,
|
||||
points: [36.5,36.4,36.4,36.3,36.2,36.2,36.3,36.4,36.5,36.5,36.6,36.7,36.8,37.1,36.9,36.8,36.7,36.6,36.6,36.5,36.5,36.4,36.4,36.5],
|
||||
totalMode: 'last',
|
||||
yTicks: [37.5, 37.0, 36.5, 36.0, 35.5],
|
||||
xLabels: ['00:00','06:00','12:00','18:00','24:00'],
|
||||
status: '正常',
|
||||
max: { v:37.1, hint:'13:00' },
|
||||
min: { v:36.2, hint:'04:20' },
|
||||
avg: { v:36.6, hint:'全天' }
|
||||
},
|
||||
week: {
|
||||
dateText: '4月27日-5月3日',
|
||||
rangeText: '周一-周日',
|
||||
unit: '°C',
|
||||
decimals: 1,
|
||||
points: [36.5, 36.6, 36.4, 36.7, 36.5, 36.8, 36.5],
|
||||
totalMode: 'avg',
|
||||
yTicks: [37.5, 37.0, 36.5, 36.0, 35.5],
|
||||
xLabels: ['周一','周二','周三','周四','周五','周六','周日'],
|
||||
status: '正常',
|
||||
max: { v:36.8, hint:'周六' },
|
||||
min: { v:36.4, hint:'周三' },
|
||||
avg: { v:36.6, hint:'本周' }
|
||||
},
|
||||
month: {
|
||||
dateText: '2026年4月',
|
||||
rangeText: '4月1日-4月30日',
|
||||
unit: '°C',
|
||||
decimals: 1,
|
||||
points: [36.5,36.6,36.4,36.7,36.5,36.8,36.5,36.6,36.4,36.7,36.5,36.8,36.5,36.6,36.4,36.7,36.5,36.8,36.5,36.6,36.4,36.7,36.5,36.8,36.5,36.6,36.4,36.7,36.5,36.6],
|
||||
totalMode: 'avg',
|
||||
yTicks: [37.5, 37.0, 36.5, 36.0, 35.5],
|
||||
xLabels: ['1日','7日','14日','21日','30日'],
|
||||
status: '正常',
|
||||
max: { v:37.1, hint:'04-15' },
|
||||
min: { v:36.2, hint:'04-08' },
|
||||
avg: { v:36.6, hint:'本月' }
|
||||
},
|
||||
year: {
|
||||
dateText: '2026年',
|
||||
rangeText: '1月-12月',
|
||||
unit: '°C',
|
||||
decimals: 1,
|
||||
points: [36.5,36.6,36.4,36.7,36.5,36.8,36.5,36.6,36.4,36.7,36.5,36.6],
|
||||
totalMode: 'avg',
|
||||
yTicks: [37.5, 37.0, 36.5, 36.0, 35.5],
|
||||
xLabels: ['1月','2月','3月','4月','5月','6月','7月','8月','9月','10月','11月','12月'],
|
||||
status: '正常',
|
||||
max: { v:37.2, hint:'03月' },
|
||||
min: { v:36.2, hint:'02月' },
|
||||
avg: { v:36.6, hint:'全年' }
|
||||
}
|
||||
};
|
||||
|
||||
function avg(arr) {
|
||||
if (!arr.length) return 0;
|
||||
var sum = arr.reduce(function(s, v){ return s + v; }, 0);
|
||||
return sum / arr.length;
|
||||
}
|
||||
|
||||
function getValue(cfg) {
|
||||
if (cfg.totalMode === 'last') return cfg.points[cfg.points.length - 1];
|
||||
if (cfg.totalMode === 'avg') return avg(cfg.points);
|
||||
if (cfg.totalMode === 'max') return Math.max.apply(null, cfg.points);
|
||||
if (cfg.totalMode === 'min') return Math.min.apply(null, cfg.points);
|
||||
return cfg.points[cfg.points.length - 1];
|
||||
}
|
||||
|
||||
function formatValue(val, decimals) {
|
||||
if (typeof val !== 'number') return String(val);
|
||||
if (decimals != null) return val.toFixed(decimals);
|
||||
return String(val);
|
||||
}
|
||||
|
||||
function renderChart(cfg) {
|
||||
var chartWidth = 330;
|
||||
var chartHeight = 208;
|
||||
var startY = 22;
|
||||
var stepX = chartWidth / (cfg.points.length - 1 || 1);
|
||||
var maxY = cfg.yTicks[0];
|
||||
|
||||
var grid = document.getElementById('chartGrid');
|
||||
var yAxis = document.getElementById('yAxisLabels');
|
||||
var xAxis = document.getElementById('xAxis');
|
||||
var lineEl = document.getElementById('line');
|
||||
var dotEl = document.getElementById('dot');
|
||||
|
||||
grid.innerHTML = '';
|
||||
cfg.yTicks.forEach(function(_, index) {
|
||||
var y = startY + (chartHeight / (cfg.yTicks.length - 1)) * index;
|
||||
grid.innerHTML += '<line x1="0" y1="' + y.toFixed(1) + '" x2="330" y2="' + y.toFixed(1) + '"></line>';
|
||||
});
|
||||
|
||||
yAxis.innerHTML = cfg.yTicks.map(function(tick, index) {
|
||||
return '<span class="y-axis-label" style="top:' + (index * 52) + 'px">' + formatValue(tick, 1) + '</span>';
|
||||
}).join('');
|
||||
|
||||
var pts = cfg.points.map(function(v, i) {
|
||||
var x = i * stepX;
|
||||
var y = startY + chartHeight - (v / maxY) * chartHeight;
|
||||
return { x: x, y: y };
|
||||
});
|
||||
|
||||
var d = pts.map(function(p, index) {
|
||||
return (index === 0 ? 'M' : 'L') + p.x.toFixed(1) + ',' + p.y.toFixed(1);
|
||||
}).join(' ');
|
||||
lineEl.setAttribute('d', d);
|
||||
|
||||
var last = pts[pts.length - 1];
|
||||
dotEl.setAttribute('cx', last.x.toFixed(1));
|
||||
dotEl.setAttribute('cy', last.y.toFixed(1));
|
||||
|
||||
xAxis.className = 'x-axis' + (cfg.xLabels.length > 7 ? ' x-axis--dense' : '');
|
||||
xAxis.style.gridTemplateColumns = 'repeat(' + cfg.xLabels.length + ', 1fr)';
|
||||
xAxis.innerHTML = cfg.xLabels.map(function(label) {
|
||||
return '<span>' + label + '</span>';
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function renderMode(mode) {
|
||||
var cfg = dataMap[mode];
|
||||
var value = getValue(cfg);
|
||||
document.getElementById('dateText').textContent = cfg.dateText;
|
||||
document.getElementById('rangeText').textContent = cfg.rangeText;
|
||||
document.getElementById('mainValue').textContent = formatValue(value, cfg.decimals);
|
||||
document.getElementById('mainUnit').textContent = cfg.unit;
|
||||
document.getElementById('statusBadge').textContent = cfg.status;
|
||||
|
||||
document.getElementById('maxValue').textContent = formatValue(cfg.max.v, cfg.decimals);
|
||||
document.getElementById('maxHint').textContent = cfg.max.hint;
|
||||
document.getElementById('minValue').textContent = formatValue(cfg.min.v, cfg.decimals);
|
||||
document.getElementById('minHint').textContent = cfg.min.hint;
|
||||
document.getElementById('avgValue').textContent = formatValue(cfg.avg.v, cfg.decimals);
|
||||
document.getElementById('avgHint').textContent = cfg.avg.hint;
|
||||
|
||||
renderChart(cfg);
|
||||
}
|
||||
|
||||
document.querySelectorAll('.time-tab').forEach(function(tab) {
|
||||
tab.onclick = function() {
|
||||
document.querySelectorAll('.time-tab').forEach(function(item) { item.classList.remove('active'); });
|
||||
tab.classList.add('active');
|
||||
renderMode(tab.getAttribute('data-mode'));
|
||||
};
|
||||
});
|
||||
|
||||
renderMode('day');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user