feat: 健康体检胃肠镜预选与预约流程完善(新增胃肠镜医院预选征集页与已提交页、检前首页预选通知条,唐都医院问卷新增就诊卡必填题与办理流程弹窗,选日期页新增预约状态条与可约窗口限制(常规近30天/胃肠镜7~30天)与提交loading过渡,预约结果页新增成功/失败演示切换与取消预约二次确认弹窗,预约类型/我的预约页精简,胃肠镜报告页影像报告整合并新增下载入口,首页站点地图同步)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
fengpu
2026-09-03 14:25:13 +08:00
co-authored by Claude Opus 4.7
parent a443c61907
commit 37ae0543a1
13 changed files with 1111 additions and 131 deletions
@@ -68,6 +68,95 @@
.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); }
/* 原型演示状态下拉框(导航栏右上角) */
.demo-select {
margin-left: auto; flex-shrink: 0; font-family: inherit;
font-size: 11px; font-weight: 600; color: var(--text-secondary);
border: 1px solid #e8e8e8; border-radius: 12px; padding: 3px 6px;
background: #f5f5f5; cursor: pointer; outline: none;
}
/* 预约结果横幅 */
.result-banner {
display: flex; align-items: flex-start; gap: 12px;
border-radius: 20px; padding: 16px; margin-bottom: 14px;
}
.result-banner--success { background: linear-gradient(135deg, #f6ffed 0%, #ffffff 100%); border: 1px solid #b7eb8f; }
.result-banner--fail { background: linear-gradient(135deg, #fff1f0 0%, #ffffff 100%); border: 1px solid #ffccc7; }
.result-banner__icon {
width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0;
display: flex; align-items: center; justify-content: center;
}
.result-banner--success .result-banner__icon { background: #52c41a; }
.result-banner--fail .result-banner__icon { background: #ff4d4f; }
.result-banner--success .icon-cross { display: none; }
.result-banner--fail .icon-check { display: none; }
.result-banner__title { font-size: 18px; font-weight: 800; margin-bottom: 4px; }
.result-banner--success .result-banner__title { color: #389e0d; }
.result-banner--fail .result-banner__title { color: #cf1322; }
.result-banner__sub { font-size: 12px; color: var(--text-muted); line-height: 1.5; }
.result-banner__reason {
display: none; align-items: center; gap: 6px; margin-top: 6px;
font-size: 13px; color: var(--text-secondary);
}
.result-banner--fail .result-banner__reason { display: flex; }
.reason-help {
width: 16px; height: 16px; border-radius: 50%; border: 1px solid #ff4d4f; color: #ff4d4f;
display: inline-flex; align-items: center; justify-content: center;
font-size: 11px; font-weight: 700; cursor: pointer; flex-shrink: 0; transition: all 0.2s;
}
.reason-help:hover { background: #ff4d4f; color: #fff; }
/* 失败原因详情弹窗 */
.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; }
.reason-modal {
width: 100%; background: #fff; border-radius: 24px; padding: 22px 20px 18px;
box-shadow: 0 20px 50px rgba(0,0,0,0.16);
}
.reason-modal__title { font-size: 17px; font-weight: 700; text-align: center; margin-bottom: 16px; }
.reason-modal__item { margin-bottom: 14px; }
.reason-modal__label { font-size: 12px; color: var(--text-muted); margin-bottom: 4px; }
.reason-modal__text { font-size: 14px; font-weight: 600; color: var(--text-primary); line-height: 1.6; }
.reason-modal__text--danger { color: #cf1322; }
.reason-modal__btn {
width: 100%; height: 44px; border-radius: 22px; border: none; cursor: pointer;
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%); color: #fff;
font-size: 15px; font-weight: 600; margin-top: 4px;
}
/* 取消预约确认弹窗 */
.cancel-modal {
width: 100%; background: #fff; border-radius: 24px; padding: 22px 20px 18px;
box-shadow: 0 20px 50px rgba(0,0,0,0.16);
}
.cancel-modal__title { font-size: 17px; font-weight: 700; text-align: center; margin-bottom: 6px; }
.cancel-modal__desc { font-size: 12px; color: var(--text-muted); text-align: center; line-height: 1.6; margin-bottom: 14px; }
.cancel-modal__order {
background: #f7f9fb; border-radius: 12px; padding: 10px 14px; margin-bottom: 16px;
font-size: 13px; font-weight: 600; color: var(--text-secondary); text-align: center;
}
.cancel-modal__label { font-size: 13px; font-weight: 600; margin-bottom: 10px; }
.cancel-modal__label em { color: var(--danger); font-style: normal; }
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.chip {
padding: 7px 14px; border-radius: 16px; border: 1px solid #e8e8e8; background: #fafafa;
font-size: 13px; color: var(--text-secondary); cursor: pointer; transition: all 0.2s; user-select: none;
}
.chip.selected { background: var(--primary-light); border-color: var(--primary); color: var(--primary-dark); font-weight: 600; }
.other-input {
display: none; width: 100%; border: 1px solid #e8e8e8; border-radius: 12px;
padding: 10px 12px; font-size: 13px; font-family: inherit; line-height: 1.6;
resize: none; outline: none; margin-bottom: 6px; color: var(--text-primary);
}
.other-input.show { display: block; }
.other-input:focus { border-color: var(--primary); }
.cancel-modal__err { display: none; font-size: 12px; color: var(--danger); margin-bottom: 6px; }
.cancel-modal__err.show { display: block; }
.cancel-modal__actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 10px; }
.cancel-modal__btn { height: 44px; border-radius: 22px; font-size: 15px; font-weight: 600; border: none; cursor: pointer; }
.cancel-modal__btn--ghost { background: #f5f5f5; color: var(--text-secondary); }
.cancel-modal__btn--danger { background: var(--danger); color: #fff; box-shadow: 0 6px 16px rgba(255,77,79,0.28); }
.section-title { font-size: 16px; font-weight: 700; margin-bottom: 14px; }
/* 信息卡片 */
.info-card {
@@ -135,6 +224,11 @@
<div class="nav-bar">
<a class="nav-back" href="index.html">&#8249;</a>
<span class="nav-title">体检预约</span>
<!-- [交互] 原型演示:切换预约成功/失败两态 -->
<select class="demo-select" id="demoSelect" title="原型演示:切换预约结果状态" onchange="setResult(this.value)">
<option value="success">预约成功</option>
<option value="fail">预约失败</option>
</select>
</div>
<div class="scroll-content">
<div class="page-body">
@@ -148,7 +242,23 @@
<div class="stepper__item stepper__item--active"><div class="stepper__dot">&#10003;</div><div class="stepper__label">预约日期</div></div>
</div>
<!-- 预约成功信息 -->
<!-- [交互] 预约结果横幅:成功/失败两态,由右上角演示切换器控制 -->
<div class="result-banner result-banner--success" id="resultBanner">
<div class="result-banner__icon">
<svg class="icon-check" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg>
<svg class="icon-cross" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round"><path d="M18 6L6 18M6 6l12 12"/></svg>
</div>
<div>
<div class="result-banner__title" id="resultTitle">预约成功</div>
<div class="result-banner__sub" id="resultSub">已为您锁定体检名额,请按预约日期准时到检</div>
<div class="result-banner__reason">
<span>失败原因:所选日期号源已约满</span>
<span class="reason-help" onclick="openReasonModal()">?</span>
</div>
</div>
</div>
<!-- 预约信息 -->
<div class="info-card">
<div class="section-title">预约信息</div>
<div class="info-card__row">
@@ -184,13 +294,61 @@
</div>
</div>
<div class="bottom-actions">
<!-- [交互] 取消预约 -->
<button class="bottom-actions__btn bottom-actions__btn--ghost" onclick="window.location.href='booking-date.html'">取消预约</button>
<!-- [交互] 预约成功态底部按钮 -->
<div class="bottom-actions" id="actionsSuccess">
<!-- [交互] 取消预约改为二次确认弹窗,需选择或填写取消原因 -->
<button class="bottom-actions__btn bottom-actions__btn--ghost" onclick="openCancelModal()">取消预约</button>
<!-- [交互] 查看预约详情,跳转至 my-appointments-all.html(常规·待体检) -->
<button class="bottom-actions__btn bottom-actions__btn--primary" onclick="window.location.href='my-appointments-all.html?type=routine&status=pending'">查看预约详情</button>
</div>
<!-- [交互] 预约失败态底部按钮:重新预约,跳回预约日期页 -->
<div class="bottom-actions" id="actionsFail" style="display: none;">
<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 class="modal-overlay hidden" id="reasonModal">
<div class="reason-modal">
<div class="reason-modal__title">失败原因详情</div>
<div class="reason-modal__item">
<div class="reason-modal__label">失败原因</div>
<div class="reason-modal__text reason-modal__text--danger">号源争抢失败:宁夏宝石花医院 2026年3月23日 体检号源已被其他员工约满</div>
</div>
<div class="reason-modal__item">
<div class="reason-modal__label">发生时间</div>
<div class="reason-modal__text">2026-03-16 12:00:35</div>
</div>
<div class="reason-modal__item">
<div class="reason-modal__label">处理建议</div>
<div class="reason-modal__text">请点击「重新预约」选择其他可约日期;若长期无可用号源,可联系健康管理专员协调加号。</div>
</div>
<button class="reason-modal__btn" onclick="closeReasonModal()">知道了</button>
</div>
</div>
<!-- [交互] 取消预约二次确认:单选原因chips,选「其他」时填写具体原因 -->
<div class="modal-overlay hidden" id="cancelModal">
<div class="cancel-modal">
<div class="cancel-modal__title">确认取消预约</div>
<div class="cancel-modal__desc">取消后名额将释放,如仍需体检请重新预约</div>
<div class="cancel-modal__order">宁夏宝石花医院 · 2026年3月23日</div>
<div class="cancel-modal__label">请选择取消原因 <em>*</em></div>
<div class="chips" id="cancelChips">
<span class="chip" data-reason="时间冲突" onclick="selectChip(this)">时间冲突</span>
<span class="chip" data-reason="医院选择不当" onclick="selectChip(this)">医院选择不当</span>
<span class="chip" data-reason="日期选择不当" onclick="selectChip(this)">日期选择不当</span>
<span class="chip" data-reason="个人健康原因" onclick="selectChip(this)">个人健康原因</span>
<span class="chip" data-reason="other" onclick="selectChip(this)">其他</span>
</div>
<textarea class="other-input" id="otherInput" rows="2" maxlength="100" placeholder="请填写取消原因(必填)"></textarea>
<div class="cancel-modal__err" id="cancelErr">请选择或填写取消原因</div>
<div class="cancel-modal__actions">
<button class="cancel-modal__btn cancel-modal__btn--ghost" onclick="closeCancelModal()">再想想</button>
<button class="cancel-modal__btn cancel-modal__btn--danger" onclick="confirmCancel()">确认取消</button>
</div>
</div>
</div>
</div>
<script>
let toastTimer = null;
@@ -200,6 +358,65 @@
clearTimeout(toastTimer);
toastTimer = setTimeout(() => { toast.classList.remove('show'); }, 2200);
}
// [交互] 原型演示:切换预约成功/失败两态(横幅、底部按钮、步骤条提示联动)
function setResult(state) {
const fail = state === 'fail';
const banner = document.getElementById('resultBanner');
banner.classList.toggle('result-banner--fail', fail);
banner.classList.toggle('result-banner--success', !fail);
document.getElementById('resultTitle').textContent = fail ? '预约失败' : '预约成功';
document.getElementById('resultSub').style.display = fail ? 'none' : '';
document.getElementById('actionsSuccess').style.display = fail ? 'none' : 'flex';
document.getElementById('actionsFail').style.display = fail ? 'flex' : 'none';
document.getElementById('stepToast').textContent = fail
? '预约未成功,请点击下方「重新预约」按钮重新预约'
: '当前已预约体检,无法重新选择,请先取消预约';
}
function openReasonModal() {
document.getElementById('reasonModal').classList.remove('hidden');
}
function closeReasonModal() {
document.getElementById('reasonModal').classList.add('hidden');
}
// [交互] 取消预约二次确认:原因单选 + 其他原因填写 + 校验 + 确认后跳转重新预约
let cancelReason = null;
function selectChip(el) {
document.querySelectorAll('#cancelChips .chip').forEach(c => c.classList.remove('selected'));
el.classList.add('selected');
cancelReason = el.dataset.reason;
document.getElementById('otherInput').classList.toggle('show', cancelReason === 'other');
hideCancelErr();
}
function hideCancelErr() {
document.getElementById('cancelErr').classList.remove('show');
}
function openCancelModal() {
cancelReason = null;
document.querySelectorAll('#cancelChips .chip').forEach(c => c.classList.remove('selected'));
const input = document.getElementById('otherInput');
input.value = '';
input.classList.remove('show');
hideCancelErr();
document.getElementById('cancelModal').classList.remove('hidden');
}
function closeCancelModal() {
document.getElementById('cancelModal').classList.add('hidden');
}
function confirmCancel() {
const input = document.getElementById('otherInput');
if (!cancelReason || (cancelReason === 'other' && !input.value.trim())) {
document.getElementById('cancelErr').classList.add('show');
return;
}
closeCancelModal();
const toast = document.getElementById('stepToast');
toast.textContent = '预约已取消';
showToast();
setTimeout(() => { window.location.href = 'booking-date.html'; }, 1200);
}
</script>
</body>
</html>
+67 -7
View File
@@ -75,6 +75,24 @@
.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; }
/* 预约状态条 */
.status-card {
background: #fff; border-radius: 20px; padding: 14px 16px; margin-bottom: 14px;
box-shadow: var(--shadow); border: 1px solid rgba(19,194,194,0.06);
}
.status-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.status-badge {
display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 700;
padding: 4px 12px; border-radius: 12px; flex-shrink: 0;
}
.status-badge--open { background: #f6ffed; color: #389e0d; border: 1px solid #b7eb8f; }
.status-badge__dot { width: 6px; height: 6px; border-radius: 50%; background: #52c41a; }
.status-range { font-size: 12px; color: var(--text-secondary); font-weight: 600; }
.status-tip {
display: flex; align-items: center; gap: 6px; margin-top: 10px; padding-top: 10px;
border-top: 1px dashed #f0f0f0; font-size: 12px; color: var(--text-muted); line-height: 1.5;
}
.status-tip svg { flex-shrink: 0; }
.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);
@@ -196,6 +214,19 @@
.confirm-modal__btn--primary {
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%); color: #fff;
}
/* 预约提交 loading */
.loading-overlay {
position: absolute; inset: 0; background: rgba(255,255,255,0.88); z-index: 150;
display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px;
}
.loading-overlay.hidden { display: none; }
.loading-spinner {
width: 44px; height: 44px; border-radius: 50%;
border: 4px solid rgba(19,194,194,0.15); border-top-color: var(--primary);
animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.loading-text { font-size: 14px; color: var(--text-secondary); font-weight: 600; }
.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;
@@ -241,6 +272,17 @@
<!-- <div class="summary-item"><div class="summary-item__label">预计费用</div><div class="summary-item__value">&yen;680</div></div>-->
</div>
</div>
<!-- [交互] 预约状态与可预约日期范围,日期范围由脚本按「近30天」规则动态生成 -->
<div class="status-card">
<div class="status-row">
<span class="status-badge status-badge--open"><span class="status-badge__dot"></span>可预约</span>
<span class="status-range" id="rangeText"></span>
</div>
<div class="status-tip">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#8c8c8c" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>
<span>至多可预约近30天内的体检日期,超出范围日期不可选择</span>
</div>
</div>
<div class="date-card">
<div class="calendar-header">
<span class="calendar-header__month" id="calendarMonth"></span>
@@ -279,10 +321,6 @@
<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>
@@ -290,14 +328,25 @@
</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>
<button class="confirm-modal__btn confirm-modal__btn--primary" onclick="submitBooking()">确认预约</button>
</div>
</div>
</div>
<!-- [交互] 确认预约后圆圈loading过渡,约1.8秒后跳转预约结果页 -->
<div class="loading-overlay hidden" id="loadingOverlay">
<div class="loading-spinner"></div>
<div class="loading-text">正在为您预约体检...</div>
</div>
<div class="toast" id="stepToast">当前已提交项目,如需重新选择医院,请先点击下方重选项目按钮</div>
</div>
<script>
const today = new Date(2026, 2, 16); // 2026-03-16
// 近30天可预约范围:今天 ~ 今天+30天
const maxBookDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 30);
function fmtDate(d) {
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
}
document.getElementById('rangeText').textContent = `可预约日期:${fmtDate(today)}${fmtDate(maxBookDate)}`;
let currentYear = today.getFullYear();
let currentMonth = today.getMonth();
let selectedDate = null;
@@ -321,8 +370,9 @@
function getSlots(year, month, day) {
const d = new Date(year, month, day);
const dow = d.getDay();
// 已过日期
// 已过日期或超出近30天范围
if (d < new Date(today.getFullYear(), today.getMonth(), today.getDate())) return -1;
if (d > maxBookDate) return -1;
// 周末不可约
if (dow === 0 || dow === 6) return 0;
// 模拟剩余人数(用日期做伪随机)
@@ -334,8 +384,10 @@
function renderCalendar() {
grid.innerHTML = '';
monthLabel.textContent = `${currentYear}${currentMonth + 1}`;
// 不允许切换到当月之前
// 不允许切换到当月之前,也不允许翻过近30天范围所在月份
prevBtn.disabled = (currentYear === today.getFullYear() && currentMonth <= today.getMonth());
nextBtn.disabled = (currentYear > maxBookDate.getFullYear()) ||
(currentYear === maxBookDate.getFullYear() && currentMonth >= maxBookDate.getMonth());
const firstDay = new Date(currentYear, currentMonth, 1);
// 周一为起始(getDay: 0=周日,转为周一起始)
@@ -412,6 +464,14 @@
function closeConfirm() {
document.getElementById('confirmModal').classList.add('hidden');
}
// 提交预约:关闭弹窗 → 圆圈loading → 1.8秒后跳转预约结果页
function submitBooking() {
closeConfirm();
document.getElementById('loadingOverlay').classList.remove('hidden');
setTimeout(() => {
window.location.href = 'booking-date-selected.html';
}, 1800);
}
</script>
</body>
</html>
@@ -258,8 +258,6 @@
<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">
@@ -274,14 +272,6 @@
<div class="radio-dot"></div>
</div>
<div class="type-card__info">
<div class="info-row">
<span class="info-row__label">组织单位</span>
<span class="info-row__value">CQ能源第一采油厂</span>
</div>
<div class="info-row">
<span class="info-row__label">体检年度</span>
<span class="info-row__value">2026</span>
</div>
<div class="info-row">
<span class="info-row__label">体检时间</span>
<span class="info-row__value">2026-06-23 至 2026-08-31</span>
@@ -314,14 +304,6 @@
<div class="radio-dot"></div>
</div>
<div class="type-card__info">
<div class="info-row">
<span class="info-row__label">组织单位</span>
<span class="info-row__value">CQ能源第一采油厂</span>
</div>
<div class="info-row">
<span class="info-row__label">体检年度</span>
<span class="info-row__value">2026</span>
</div>
<div class="info-row">
<span class="info-row__label">体检时间</span>
<span class="info-row__value">2026-06-23 至 2026-08-31</span>
@@ -104,6 +104,43 @@
opacity: 0; pointer-events: none; transition: all 0.25s ease; max-width: 280px;
}
.toast.show { opacity: 1; transform: translate(-50%, -50%) scale(1); }
/* 取消预约确认弹窗 */
.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; }
.cancel-modal {
width: 100%; background: #fff; border-radius: 24px; padding: 22px 20px 18px;
box-shadow: 0 20px 50px rgba(0,0,0,0.16);
}
.cancel-modal__title { font-size: 17px; font-weight: 700; text-align: center; margin-bottom: 6px; }
.cancel-modal__desc { font-size: 12px; color: var(--text-muted); text-align: center; line-height: 1.6; margin-bottom: 14px; }
.cancel-modal__order {
background: #f7f9fb; border-radius: 12px; padding: 10px 14px; margin-bottom: 16px;
font-size: 13px; font-weight: 600; color: var(--text-secondary); text-align: center;
}
.cancel-modal__label { font-size: 13px; font-weight: 600; margin-bottom: 10px; }
.cancel-modal__label em { color: var(--danger); font-style: normal; }
.chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.chip {
padding: 7px 14px; border-radius: 16px; border: 1px solid #e8e8e8; background: #fafafa;
font-size: 13px; color: var(--text-secondary); cursor: pointer; transition: all 0.2s; user-select: none;
}
.chip.selected { background: var(--primary-light); border-color: var(--primary); color: var(--primary-dark); font-weight: 600; }
.other-input {
display: none; width: 100%; border: 1px solid #e8e8e8; border-radius: 12px;
padding: 10px 12px; font-size: 13px; font-family: inherit; line-height: 1.6;
resize: none; outline: none; margin-bottom: 6px; color: var(--text-primary);
}
.other-input.show { display: block; }
.other-input:focus { border-color: var(--primary); }
.cancel-modal__err { display: none; font-size: 12px; color: var(--danger); margin-bottom: 6px; }
.cancel-modal__err.show { display: block; }
.cancel-modal__actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 10px; }
.cancel-modal__btn { height: 44px; border-radius: 22px; font-size: 15px; font-weight: 600; border: none; cursor: pointer; }
.cancel-modal__btn--ghost { background: #f5f5f5; color: var(--text-secondary); }
.cancel-modal__btn--danger { background: var(--danger); color: #fff; box-shadow: 0 6px 16px rgba(255,77,79,0.28); }
</style>
</head>
<body>
@@ -169,10 +206,34 @@
</div>
<div class="bottom-actions">
<button class="bottom-actions__btn bottom-actions__btn--ghost" onclick="window.location.href='gastro-date.html'">取消预约</button>
<button class="bottom-actions__btn bottom-actions__btn--primary" onclick="window.location.href='index.html'">返回首页</button>
<!-- [交互] 取消预约改为二次确认弹窗,需选择或填写取消原因 -->
<button class="bottom-actions__btn bottom-actions__btn--ghost" onclick="openCancelModal()">取消预约</button>
<button class="bottom-actions__btn bottom-actions__btn--primary" onclick="window.location.href='my-appointments-all.html?type=gastro'">查看预约详情</button>
</div>
<div class="toast" id="stepToast">当前已预约胃肠镜检查,无法重新选择,请先取消预约</div>
<!-- [交互] 取消预约二次确认:单选原因chips,选「其他」时填写具体原因 -->
<div class="modal-overlay hidden" id="cancelModal">
<div class="cancel-modal">
<div class="cancel-modal__title">确认取消预约</div>
<div class="cancel-modal__desc">取消后名额将释放,如仍需检查请重新预约</div>
<div class="cancel-modal__order">宁夏宝石花医院 · 2026年3月23日</div>
<div class="cancel-modal__label">请选择取消原因 <em>*</em></div>
<div class="chips" id="cancelChips">
<span class="chip" data-reason="时间冲突" onclick="selectChip(this)">时间冲突</span>
<span class="chip" data-reason="医院选择不当" onclick="selectChip(this)">医院选择不当</span>
<span class="chip" data-reason="日期选择不当" onclick="selectChip(this)">日期选择不当</span>
<span class="chip" data-reason="个人健康原因" onclick="selectChip(this)">个人健康原因</span>
<span class="chip" data-reason="other" onclick="selectChip(this)">其他</span>
</div>
<textarea class="other-input" id="otherInput" rows="2" maxlength="100" placeholder="请填写取消原因(必填)"></textarea>
<div class="cancel-modal__err" id="cancelErr">请选择或填写取消原因</div>
<div class="cancel-modal__actions">
<button class="cancel-modal__btn cancel-modal__btn--ghost" onclick="closeCancelModal()">再想想</button>
<button class="cancel-modal__btn cancel-modal__btn--danger" onclick="confirmCancel()">确认取消</button>
</div>
</div>
</div>
</div>
<script>
var toastTimer = null;
@@ -182,6 +243,47 @@
clearTimeout(toastTimer);
toastTimer = setTimeout(function() { toast.classList.remove('show'); }, 2200);
}
// [交互] 取消预约二次确认:原因单选 + 其他原因填写 + 校验 + 确认后返回预约日期页重新选择
var cancelReason = null;
function selectChip(el) {
var chips = document.querySelectorAll('#cancelChips .chip');
for (var i = 0; i < chips.length; i++) chips[i].classList.remove('selected');
el.classList.add('selected');
cancelReason = el.dataset.reason;
document.getElementById('otherInput').classList.toggle('show', cancelReason === 'other');
hideCancelErr();
}
function hideCancelErr() {
document.getElementById('cancelErr').classList.remove('show');
}
function openCancelModal() {
cancelReason = null;
var chips = document.querySelectorAll('#cancelChips .chip');
for (var i = 0; i < chips.length; i++) chips[i].classList.remove('selected');
var input = document.getElementById('otherInput');
input.value = '';
input.classList.remove('show');
hideCancelErr();
document.getElementById('cancelModal').classList.remove('hidden');
}
function closeCancelModal() {
document.getElementById('cancelModal').classList.add('hidden');
}
function confirmCancel() {
var input = document.getElementById('otherInput');
if (!cancelReason || (cancelReason === 'other' && !input.value.trim())) {
document.getElementById('cancelErr').classList.add('show');
return;
}
closeCancelModal();
var toast = document.getElementById('stepToast');
toast.textContent = '预约已取消';
showToast();
setTimeout(function() {
window.location.href = 'gastro-date.html';
}, 1200);
}
</script>
</body>
</html>
+47 -3
View File
@@ -77,6 +77,24 @@
.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; }
/* 预约状态条 */
.status-card {
background: #fff; border-radius: 20px; padding: 14px 16px; margin-bottom: 14px;
box-shadow: var(--shadow); border: 1px solid rgba(19,194,194,0.06);
}
.status-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.status-badge {
display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 700;
padding: 4px 12px; border-radius: 12px; flex-shrink: 0;
}
.status-badge--open { background: #f6ffed; color: #389e0d; border: 1px solid #b7eb8f; }
.status-badge__dot { width: 6px; height: 6px; border-radius: 50%; background: #52c41a; }
.status-range { font-size: 12px; color: var(--text-secondary); font-weight: 600; }
.status-tip {
display: flex; align-items: center; gap: 6px; margin-top: 10px; padding-top: 10px;
border-top: 1px dashed #f0f0f0; font-size: 12px; color: var(--text-muted); line-height: 1.5;
}
.status-tip svg { flex-shrink: 0; }
.date-card {
background: #fff; border-radius: 20px; padding: 18px 16px;
box-shadow: var(--shadow); border: 1px solid rgba(19,194,194,0.06);
@@ -178,6 +196,18 @@
</div>
</div>
<!-- [交互] 预约状态与可预约日期范围,日期范围由脚本按「最早7天后」规则动态生成 -->
<div class="status-card">
<div class="status-row">
<span class="status-badge status-badge--open"><span class="status-badge__dot"></span>可预约</span>
<span class="status-range" id="rangeText"></span>
</div>
<div class="status-tip">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#8c8c8c" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>
<span>胃肠镜检查需提前预约,最早仅可预约7天后的日期,超出范围日期不可选择</span>
</div>
</div>
<div class="date-card">
<div class="calendar-header">
<span class="calendar-header__month" id="calendarMonth"></span>
@@ -219,6 +249,15 @@
</div>
<script>
var today = new Date(2026, 2, 16);
// 胃肠镜预约窗口:最早7天后,最晚30天后
var minBookDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 7);
var maxBookDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 30);
function fmtDate(d) {
var m = d.getMonth() + 1; var day = d.getDate();
return d.getFullYear() + '-' + (m < 10 ? '0' + m : m) + '-' + (day < 10 ? '0' + day : day);
}
document.getElementById('rangeText').textContent =
'可预约日期:' + fmtDate(minBookDate) + ' 至 ' + fmtDate(maxBookDate);
var currentYear = today.getFullYear();
var currentMonth = today.getMonth();
var selectedDate = null;
@@ -231,7 +270,9 @@
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;
// 早于7天后或超出30天窗口均不可约
if (d < minBookDate) return -1;
if (d > maxBookDate) return -1;
if (dow === 0 || dow === 6) return 0;
var seed = (day * 7 + month * 13) % 20;
if (seed < 3) return 0;
@@ -241,7 +282,9 @@
function renderCalendar() {
grid.innerHTML = '';
monthLabel.textContent = currentYear + '年' + (currentMonth + 1) + '月';
prevBtn.disabled = (currentYear === today.getFullYear() && currentMonth <= today.getMonth());
prevBtn.disabled = (currentYear === minBookDate.getFullYear() && currentMonth <= minBookDate.getMonth());
nextBtn.disabled = (currentYear > maxBookDate.getFullYear()) ||
(currentYear === maxBookDate.getFullYear() && currentMonth >= maxBookDate.getMonth());
var firstDay = new Date(currentYear, currentMonth, 1);
var startDow = firstDay.getDay();
startDow = startDow === 0 ? 6 : startDow - 1;
@@ -291,7 +334,8 @@
renderCalendar();
});
selectedDate = { y: today.getFullYear(), m: today.getMonth(), d: today.getDate() };
// 默认选中最早可预约日期(7天后)
selectedDate = { y: minBookDate.getFullYear(), m: minBookDate.getMonth(), d: minBookDate.getDate() };
renderCalendar();
function openConfirm() {
@@ -185,14 +185,15 @@
</div>
<div class="radio-dot"></div>
</div>
<div class="hospital-card" onclick="selectHospital(this)">
<!-- [交互] 唐都医院胃肠镜预约需先办理就诊卡,问卷首页出现就诊卡题 -->
<div class="hospital-card" data-hospital="tangdu" onclick="selectHospital(this)">
<div class="hospital-card__info">
<div class="hospital-card__icon">🏥</div>
<div>
<div class="hospital-card__name">西安CQ医院</div>
<div class="hospital-card__name">唐都医院</div>
<div class="hospital-card__addr">陕西西安市</div>
<div class="hospital-card__tags">
<span class="htag htag--routine">常规体检</span>
<span class="htag htag--gastro">胃肠镜体检</span>
</div>
</div>
</div>
@@ -202,7 +203,7 @@
</div>
<div class="bottom-actions">
<button class="bottom-actions__btn" onclick="location.href='gastro-questionnaire.html'">下一步</button>
<button class="bottom-actions__btn" onclick="goNext()">下一步</button>
</div>
<div class="modal-overlay hidden" id="personModal">
@@ -227,6 +228,15 @@
document.querySelectorAll('.hospital-card').forEach(c => c.classList.remove('active'));
el.classList.add('active');
}
// [交互] 选中唐都医院时携带参数进入问卷,问卷页展示就诊卡题;其他医院维持原问卷
function goNext() {
var active = document.querySelector('.hospital-card.active');
if (active && active.dataset.hospital === 'tangdu') {
location.href = 'gastro-questionnaire.html?hospital=tangdu';
} else {
location.href = 'gastro-questionnaire.html';
}
}
function openModal() { document.getElementById('personModal').classList.remove('hidden'); }
function closeModal() { document.getElementById('personModal').classList.add('hidden'); }
</script>
@@ -0,0 +1,171 @@
<!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 220px, #f7f9fb 100%); padding-bottom: 120px; }
.scroll-content::-webkit-scrollbar { display: none; }
.page-body { padding: 16px; }
/* 提交成功卡:绿色对勾 + 提交时间 + 不可修改说明 */
.success-card {
background: #fff; border-radius: 18px; padding: 24px 16px 18px; margin-bottom: 18px;
box-shadow: var(--shadow); border: 1px solid var(--border); text-align: center;
}
.success-card__icon {
width: 64px; height: 64px; border-radius: 50%; margin: 0 auto 12px;
background: linear-gradient(135deg, #52c41a 0%, #73d13d 100%);
display: flex; align-items: center; justify-content: center;
box-shadow: 0 10px 24px rgba(82, 196, 26, 0.28);
}
.success-card__title { font-size: 18px; font-weight: 700; margin-bottom: 6px; }
.success-card__time { font-size: 12px; color: var(--text-muted); margin-bottom: 12px; }
.success-card__note {
display: inline-block; padding: 6px 12px; border-radius: 12px;
background: #f6ffed; border: 1px solid #b7eb8f;
font-size: 12px; color: #52c41a; line-height: 1.6;
}
.section-title { font-size: 16px; font-weight: 700; margin-bottom: 6px; }
.section-sub { font-size: 12px; color: var(--text-muted); margin-bottom: 12px; }
/* 已选医院只读卡片:不可点击,右侧固定绿色对勾 */
.hospital-card {
background: #fff; border-radius: 18px; padding: 16px; margin-bottom: 12px;
border: 2px solid var(--primary); box-shadow: var(--shadow);
display: flex; align-items: center; justify-content: space-between;
}
.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); }
.hospital-card__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.htag { font-size: 10px; line-height: 16px; padding: 0 8px; border-radius: 8px; }
.htag--gastro { background: #f6ffed; color: #52c41a; }
.htag--routine { background: #e6f7ff; color: #1890ff; }
.checked-mark {
width: 22px; height: 22px; border-radius: 6px; background: var(--primary);
display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.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">
<!-- [交互] 返回首页: index.html -->
<a class="nav-back" href="index.html">&#8249;</a>
<span class="nav-title">胃肠镜医院预选</span>
</div>
<div class="scroll-content">
<div class="page-body">
<div class="success-card">
<div class="success-card__icon">
<svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg>
</div>
<div class="success-card__title">预选提交成功</div>
<div class="success-card__time">提交时间:2026-09-03 12:00</div>
<div class="success-card__note">感谢您的参与,您的意向将作为2027年度承检医院安排参考<br>预选结果提交后不可修改</div>
</div>
<div class="section-title">我选择的意向医院</div>
<div class="section-sub"><b style="color:#0f9b9b;">2</b> 家,以下为只读回显,不可再次编辑</div>
<div class="hospital-card">
<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 class="hospital-card__tags">
<span class="htag htag--gastro">胃肠镜体检</span>
</div>
</div>
</div>
<div class="checked-mark">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg>
</div>
</div>
<div class="hospital-card">
<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 class="hospital-card__tags">
<span class="htag htag--gastro">胃肠镜体检</span>
</div>
</div>
</div>
<div class="checked-mark">
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg>
</div>
</div>
</div>
</div>
<div class="bottom-actions">
<!-- [交互] 点击返回首页: index.html,首页通知条同步变为「预选已完成」态 -->
<button class="bottom-actions__btn" onclick="location.href='index.html'">返回首页</button>
</div>
</div>
</body>
</html>
@@ -0,0 +1,294 @@
<!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; }
/* 征集说明卡:目的、周期、不可逆提示 */
.intro-card {
background: #fff; border-radius: 18px; padding: 16px; margin-bottom: 18px;
box-shadow: var(--shadow); border: 1px solid var(--border);
}
.intro-card__title { font-size: 16px; font-weight: 700; margin-bottom: 4px; display: flex; align-items: center; gap: 6px; }
/* 计划信息行:组织单位 / 开始日期 / 截止日期,左标签右值 */
.intro-card__field {
display: flex; justify-content: space-between; align-items: center;
padding: 9px 0; border-bottom: 1px solid #f0f0f0; font-size: 13px;
}
.intro-card__field span { color: var(--text-muted); }
.intro-card__field b { color: var(--text-primary); font-weight: 600; white-space: nowrap; }
.intro-card__field:last-of-type { border-bottom: none; padding-bottom: 2px; }
.intro-card__warn {
margin-top: 10px; padding: 8px 10px; border-radius: 10px;
background: #fff2f0; border: 1px solid #ffccc7;
font-size: 12px; color: #f5222d; line-height: 1.6;
}
.section-title { font-size: 16px; font-weight: 700; margin-bottom: 6px; }
.section-sub { font-size: 12px; color: var(--text-muted); margin-bottom: 12px; }
.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); }
.hospital-card__tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.htag { font-size: 10px; line-height: 16px; padding: 0 8px; border-radius: 8px; }
.htag--gastro { background: #f6ffed; color: #52c41a; }
.htag--routine { background: #e6f7ff; color: #1890ff; }
/* 多选复选框:区别于正式预约的单选圆点 */
.check-box {
width: 22px; height: 22px; border-radius: 6px; border: 2px solid #d9d9d9;
position: relative; flex-shrink: 0; transition: all 0.25s ease; background: #fff;
}
.check-box::after {
content: ''; position: absolute; left: 6px; top: 2px; width: 5px; height: 10px;
border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg);
opacity: 0; transition: opacity 0.2s ease;
}
.hospital-card.active .check-box { border-color: var(--primary); background: var(--primary); }
.hospital-card.active .check-box::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); transition: all 0.2s ease;
}
.bottom-actions__btn:disabled {
background: #d9d9d9; color: #fff; box-shadow: none; cursor: not-allowed;
}
/* 提交二次确认弹窗:因预选仅可填写一次,提交前强制确认 */
.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: 16px; line-height: 1.6; }
.modal-card__sub b { color: #f5222d; }
.modal-hospital-list { background: #f7f9fb; border-radius: 14px; padding: 12px 14px; margin-bottom: 20px; }
.modal-hospital-list__title { font-size: 12px; color: var(--text-muted); margin-bottom: 8px; }
.modal-hospital-list__item {
display: flex; align-items: center; gap: 8px; font-size: 14px; font-weight: 600;
color: var(--text-primary); padding: 5px 0;
}
.modal-hospital-list__item::before { content: '🏥'; font-size: 14px; }
.modal-btns { display: flex; gap: 12px; }
.modal-btn {
flex: 1; height: 44px; border-radius: 22px; font-size: 15px; font-weight: 600;
border: none; cursor: pointer;
}
.modal-btn--cancel { background: #f5f5f5; color: var(--text-secondary); }
.modal-btn--confirm {
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">
<!-- [交互] 返回首页: index.html -->
<a class="nav-back" href="index.html">&#8249;</a>
<span class="nav-title">胃肠镜医院预选</span>
</div>
<div class="scroll-content">
<div class="page-body">
<div class="intro-card">
<div class="intro-card__title">📋 2027 年度胃肠镜体检医院意向征集</div>
<div class="intro-card__field"><span>预选日期: 2026-07-01至2026-10-20</span></div>
<div class="intro-card__warn">⚠️ 本次预选每人仅可填写一次,提交后不可修改,请谨慎选择。</div>
</div>
<div class="section-title">选择意向医院</div>
<div class="section-sub">点击卡片可多选,当前已选 <span id="selectedCount">0</span></div>
<div class="hospital-card" onclick="toggleHospital(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 class="hospital-card__tags">
<span class="htag htag--gastro">胃肠镜体检</span>
<span class="htag htag--routine">常规体检</span>
</div>
</div>
</div>
<div class="check-box"></div>
</div>
<div class="hospital-card" onclick="toggleHospital(this)">
<div class="hospital-card__info">
<div class="hospital-card__icon">🏥</div>
<div>
<div class="hospital-card__name">CQ星龙园医院</div>
<div class="hospital-card__addr">陕西西安市</div>
<div class="hospital-card__tags">
<span class="htag htag--gastro">胃肠镜体检</span>
</div>
</div>
</div>
<div class="check-box"></div>
</div>
<div class="hospital-card" onclick="toggleHospital(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 class="hospital-card__tags">
<span class="htag htag--gastro">胃肠镜体检</span>
</div>
</div>
</div>
<div class="check-box"></div>
</div>
<div class="hospital-card" onclick="toggleHospital(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 class="hospital-card__tags">
<span class="htag htag--gastro">胃肠镜体检</span>
<span class="htag htag--routine">常规体检</span>
</div>
</div>
</div>
<div class="check-box"></div>
</div>
<div class="hospital-card" onclick="toggleHospital(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 class="hospital-card__tags">
<span class="htag htag--gastro">胃肠镜体检</span>
</div>
</div>
</div>
<div class="check-box"></div>
</div>
</div>
</div>
<div class="bottom-actions">
<!-- [交互] 未选择任何医院时按钮置灰禁用;点击提交弹出二次确认弹窗 -->
<button class="bottom-actions__btn" id="submitBtn" disabled onclick="openConfirm()">提交预选</button>
</div>
<!-- [交互] 二次确认弹窗:列出已选医院,确认后跳转 gastro-preselect-done.html -->
<div class="modal-overlay hidden" id="confirmModal">
<div class="modal-card">
<div class="modal-card__title">确认提交预选</div>
<div class="modal-card__sub">本次预选<b>仅可填写一次,提交后不可修改</b><br>请确认以下意向医院无误</div>
<div class="modal-hospital-list">
<div class="modal-hospital-list__title">已选 <span id="modalCount">0</span> 家医院</div>
<div id="modalHospitalList"></div>
</div>
<div class="modal-btns">
<button class="modal-btn modal-btn--cancel" onclick="closeConfirm()">返回修改</button>
<button class="modal-btn modal-btn--confirm" onclick="confirmSubmit()">确认提交</button>
</div>
</div>
</div>
</div>
<script>
// 多选切换:点击卡片勾选/取消勾选
function toggleHospital(el) {
el.classList.toggle('active');
updateSubmitState();
}
// 根据已选数量更新计数文案与提交按钮禁用态
function updateSubmitState() {
var count = document.querySelectorAll('.hospital-card.active').length;
document.getElementById('selectedCount').textContent = count;
var btn = document.getElementById('submitBtn');
btn.disabled = count === 0;
btn.textContent = count === 0 ? '提交预选' : '提交预选(已选 ' + count + ' 家)';
}
// 打开二次确认弹窗前,将已选医院名称注入弹窗列表
function openConfirm() {
var actives = document.querySelectorAll('.hospital-card.active');
if (actives.length === 0) return;
var html = '';
actives.forEach(function (card) {
html += '<div class="modal-hospital-list__item">' + card.querySelector('.hospital-card__name').textContent + '</div>';
});
document.getElementById('modalHospitalList').innerHTML = html;
document.getElementById('modalCount').textContent = actives.length;
document.getElementById('confirmModal').classList.remove('hidden');
}
function closeConfirm() { document.getElementById('confirmModal').classList.add('hidden'); }
// [交互] 确认提交后进入已提交只读页: gastro-preselect-done.html
function confirmSubmit() { location.href = 'gastro-preselect-done.html'; }
</script>
</body>
</html>
@@ -103,6 +103,50 @@
background: linear-gradient(135deg, #13c2c2 0%, #36cfc9 100%);
color: #fff; box-shadow: 0 10px 20px rgba(19, 194, 194, 0.22);
}
/* 就诊卡题:必填卡号输入与办理提示 */
.q-card__required { color: #ff4d4f; font-style: normal; margin-left: 2px; }
.q-card__hint {
margin-top: 12px; font-size: 13px; color: var(--primary-dark); font-weight: 600;
cursor: pointer; display: inline-flex; align-items: center; gap: 2px; text-decoration: underline;
text-underline-offset: 3px;
}
.q-card__input { margin-top: 14px; }
.q-card__input-el {
width: 100%; height: 44px; border: 2px solid #e8e8e8; border-radius: 22px;
padding: 0 16px; font-size: 14px; font-family: inherit; color: var(--text-primary);
outline: none; background: #fff; transition: border-color 0.2s;
}
.q-card__input-el:focus { border-color: var(--primary); }
.q-card__guide-step {
display: flex; gap: 8px; font-size: 12px; line-height: 1.7;
color: #614700; margin-bottom: 6px;
}
.q-card__guide-step:last-child { margin-bottom: 0; }
.q-card__guide-no {
width: 16px; height: 16px; border-radius: 50%; background: #faad14; color: #fff;
font-size: 10px; font-weight: 700; display: flex; align-items: center;
justify-content: center; flex-shrink: 0; margin-top: 3px;
}
/* 就诊卡办理流程弹窗 */
/* 页面内容较长时手机壳会被撑高,弹窗改为顶部定位并在打开时滚回页首,保证可见 */
.modal-overlay {
position: absolute; inset: 0; background: rgba(0,0,0,0.45); z-index: 100;
display: flex; align-items: flex-start; justify-content: center; padding: 24px;
}
.modal-overlay.hidden { display: none; }
.modal-card {
width: 100%; background: #fff; border-radius: 24px; padding: 22px 20px 18px;
box-shadow: 0 20px 50px rgba(0,0,0,0.16); margin-top: 90px;
}
.modal-card__title { font-size: 17px; font-weight: 700; text-align: center; margin-bottom: 14px; }
.modal-card__sub {
font-size: 12px; color: var(--text-muted); line-height: 1.6; text-align: center; margin-top: 12px;
}
.modal-confirm-btn {
margin-top: 18px; 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>
@@ -133,6 +177,15 @@
<div class="section-title">胃肠镜检查问卷</div>
<div class="section-desc">请如实填写以下信息,以便医生评估检查方案</div>
<!-- [交互] 就诊卡题仅在选择唐都医院时出现(?hospital=tangdu),卡号为必填;点击「没有就诊卡?」弹窗查看办理流程 -->
<div class="q-card" id="qVisitCard" style="display:none">
<div class="q-card__label"><span class="q-card__index">1</span>请填写唐都医院就诊卡号 <em class="q-card__required">*</em></div>
<div class="q-card__input">
<input class="q-card__input-el" type="text" maxlength="20" placeholder="请输入就诊卡号">
</div>
<div class="q-card__hint" onclick="openCardModal()">没有就诊卡?</div>
</div>
<div class="q-card">
<div class="q-card__label"><span class="q-card__index">1</span>是否使用阿司匹林?</div>
<div class="q-options">
@@ -187,6 +240,18 @@
<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 class="modal-overlay hidden" id="cardModal">
<div class="modal-card">
<div class="modal-card__title">就诊卡办理流程</div>
<div class="q-card__guide-step"><span class="q-card__guide-no">1</span><span>携带本人身份证,前往唐都医院门诊大厅建卡窗口或自助机现场办理就诊卡。</span></div>
<div class="q-card__guide-step"><span class="q-card__guide-no">2</span><span>或关注「唐都医院」微信公众号,在线申领电子就诊卡。</span></div>
<div class="q-card__guide-step"><span class="q-card__guide-no">3</span><span>办理完成后返回本页,填写就诊卡号即可继续预约。</span></div>
<div class="modal-card__sub">就诊卡号为预约必填项,未办理将无法完成胃肠镜预约</div>
<button class="modal-confirm-btn" onclick="closeCardModal()">知道了</button>
</div>
</div>
</div>
<script>
@@ -195,6 +260,24 @@
group.querySelectorAll('.q-option').forEach(function(b) { b.classList.remove('active'); });
btn.classList.add('active');
}
// [交互] 「没有就诊卡?」弹窗查看办理流程
function openCardModal() {
window.scrollTo(0, 0);
document.getElementById('cardModal').classList.remove('hidden');
}
function closeCardModal() { document.getElementById('cardModal').classList.add('hidden'); }
// [交互] 根据URL参数决定是否展示就诊卡题,并按可见卡片重新编排序号
(function initFromUrl() {
var hospital = new URLSearchParams(window.location.search).get('hospital');
document.getElementById('qVisitCard').style.display = (hospital === 'tangdu') ? '' : 'none';
var idx = 1;
var cards = document.querySelectorAll('.q-card');
for (var i = 0; i < cards.length; i++) {
if (cards[i].style.display === 'none') continue;
var badge = cards[i].querySelector('.q-card__index');
if (badge) badge.textContent = idx++;
}
})();
</script>
</body>
</html>
+78
View File
@@ -214,6 +214,71 @@
transition: all 0.25s ease;
}
.banner__dot.is-active { width: 18px; background: #13c2c2; }
/* 胃肠镜医院预选事件通知条:限期待办入口,仅征集期展示,橙色区别于下方青绿主色内容区 */
.notice-bar {
margin-top: 14px;
background: linear-gradient(135deg, #fff7e6 0%, #fffdf7 100%);
border: 1px solid #ffe7ba;
border-radius: 16px;
padding: 12px 14px;
display: flex;
align-items: center;
gap: 10px;
cursor: pointer;
box-shadow: 0 4px 14px rgba(250, 140, 22, 0.08);
transition: transform 0.15s ease;
}
.notice-bar:active { transform: scale(0.985); }
.notice-bar__icon {
width: 36px;
height: 36px;
border-radius: 12px;
background: linear-gradient(135deg, #fa8c16 0%, #ffa940 100%);
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
flex-shrink: 0;
}
.notice-bar__content { flex: 1; min-width: 0; }
.notice-bar__title {
font-size: 14px;
font-weight: 700;
color: #d46b08;
display: flex;
align-items: center;
gap: 6px;
}
.notice-bar__live {
width: 6px;
height: 6px;
border-radius: 50%;
background: #f5222d;
animation: noticePulse 1.2s ease-in-out infinite;
}
@keyframes noticePulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }
.notice-bar__desc {
margin-top: 3px;
font-size: 11px;
line-height: 1.5;
color: #ad6800;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.notice-bar__action {
display: inline-flex;
align-items: center;
justify-content: center;
height: 28px;
padding: 0 12px;
border-radius: 14px;
background: #fa8c16;
color: #fff;
font-size: 12px;
font-weight: 600;
flex-shrink: 0;
}
.section-title {
font-size: 16px;
font-weight: 700;
@@ -442,6 +507,19 @@
<span class="banner__dot"></span>
</div>
<!-- [交互] 胃肠镜医院预选通知条:仅管理员开启预选计划期间展示;
未提交时点击进入: gastro-preselect.html(示意当前态);
员工提交后变为完成态(标题改「预选已完成」、徽标变绿勾、按钮改「查看结果 ›」),点击进入: gastro-preselect-done.html
征集期结束后整条隐藏 -->
<div class="notice-bar" onclick="location.href='gastro-preselect.html'">
<span class="notice-bar__icon">📢</span>
<div class="notice-bar__content">
<div class="notice-bar__title">胃肠镜体检医院预选进行中<span class="notice-bar__live"></span></div>
<div class="notice-bar__desc">选出您倾向的体检医院,截止 09-15,每人仅可填写一次</div>
</div>
<span class="notice-bar__action">去选择</span>
</div>
<div class="section-title">体检服务</div>
<div class="feature-list">
<!-- [交互] 点击跳转至: booking-type.html -->
@@ -278,17 +278,6 @@
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;
}
@@ -469,11 +458,6 @@
</div>
</div>
<div class="progress-card">
<div class="progress-card__header">
<div class="progress-card__title">体检进度</div>
<div class="progress-card__ratio" id="rProgRatio">5 / 26 项</div>
</div>
<div class="progress-bar-lg"><div class="progress-bar-lg__fill" id="rProgFill" style="width: 19.2%;"></div></div>
<!-- [交互] 点击切换已检/未检 Tab -->
<div class="project-tabs">
<button class="project-tabs__btn project-tabs__btn--active" type="button" id="rTabDone" onclick="switchProg('r',0)">已检项目 (5)</button>
@@ -497,11 +481,6 @@
</div>
</div>
<div class="progress-card">
<div class="progress-card__header">
<div class="progress-card__title">体检进度</div>
<div class="progress-card__ratio">26 / 26 项</div>
</div>
<div class="progress-bar-lg"><div class="progress-bar-lg__fill" style="width: 100%;"></div></div>
<!-- [交互] 点击切换已检/未检 Tab -->
<div class="project-tabs">
<button class="project-tabs__btn project-tabs__btn--active" type="button" id="rdTabDone" onclick="switchProg('rd',0)">已检项目 (26)</button>
@@ -538,8 +517,8 @@
<div class="project-list" id="rcPickedList"></div>
</div>
</div>
<!-- [交互] 点击跳转至: booking-type.html(重新走常规体检预约流程) -->
<button class="rebook-btn" type="button" onclick="location.href='booking-type.html'">重新预约</button>
<!-- [交互] 点击跳转至: booking-date.html(重新走常规体检预约流程) -->
<button class="rebook-btn" type="button" onclick="location.href='booking-date.html'">重新预约</button>
</div>
<!-- ======================= 常规体检 · 无预约信息 ======================= -->
@@ -557,45 +536,6 @@
<!-- ======================= 胃肠镜体检 · 待体检 ======================= -->
<div class="panel hidden" data-type="gastro" data-status="pending">
<div class="person-card" id="codeGastro">
<div class="person-card__header">
<div class="section-title" style="margin-bottom:0">体检签到码</div>
<!-- [交互] 点击右上角小图标切换条形码/二维码 -->
<button class="code-switch" type="button" title="切换条形码/二维码" onclick="toggleCodeMode('codeGastro')">
<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="M17 1l4 4-4 4"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><path d="M7 23l-4-4 4-4"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/></svg>
</button>
</div>
<div class="qrcode-wrap code-only--bar">
<!-- [交互] 点击条码放大展示 -->
<svg class="code-img code-img--bar" onclick="openCodeOverlay('codeGastro')" viewBox="0 0 200 110" xmlns="http://www.w3.org/2000/svg">
<rect width="200" height="110" fill="#fff"/>
<rect x="10" y="10" width="3" height="72" fill="#1a1a1a"/><rect x="16" y="10" width="1.5" height="72" fill="#1a1a1a"/><rect x="20" y="10" width="2" height="72" fill="#1a1a1a"/><rect x="25" y="10" width="4" height="72" fill="#1a1a1a"/><rect x="32" y="10" width="1.5" height="72" fill="#1a1a1a"/><rect x="36" y="10" width="2.5" height="72" fill="#1a1a1a"/><rect x="41" y="10" width="1.5" height="72" fill="#1a1a1a"/><rect x="45" y="10" width="3" height="72" fill="#1a1a1a"/><rect x="50" y="10" width="2" height="72" fill="#1a1a1a"/><rect x="54" y="10" width="1.5" height="72" fill="#1a1a1a"/><rect x="58" y="10" width="4" height="72" fill="#1a1a1a"/><rect x="65" y="10" width="1.5" height="72" fill="#1a1a1a"/><rect x="69" y="10" width="2.5" height="72" fill="#1a1a1a"/><rect x="74" y="10" width="1.5" height="72" fill="#1a1a1a"/><rect x="78" y="10" width="3" height="72" fill="#1a1a1a"/><rect x="83" y="10" width="2" height="72" fill="#1a1a1a"/><rect x="87" y="10" width="4" height="72" fill="#1a1a1a"/><rect x="94" y="10" width="1.5" height="72" fill="#1a1a1a"/><rect x="98" y="10" width="2" height="72" fill="#1a1a1a"/><rect x="102" y="10" width="3" height="72" fill="#1a1a1a"/><rect x="107" y="10" width="1.5" height="72" fill="#1a1a1a"/><rect x="111" y="10" width="4" height="72" fill="#1a1a1a"/><rect x="118" y="10" width="2" height="72" fill="#1a1a1a"/><rect x="122" y="10" width="1.5" height="72" fill="#1a1a1a"/><rect x="126" y="10" width="3" height="72" fill="#1a1a1a"/><rect x="131" y="10" width="2.5" height="72" fill="#1a1a1a"/><rect x="136" y="10" width="1.5" height="72" fill="#1a1a1a"/><rect x="140" y="10" width="4" height="72" fill="#1a1a1a"/><rect x="147" y="10" width="1.5" height="72" fill="#1a1a1a"/><rect x="151" y="10" width="2" height="72" fill="#1a1a1a"/><rect x="155" y="10" width="3" height="72" fill="#1a1a1a"/><rect x="160" y="10" width="1.5" height="72" fill="#1a1a1a"/><rect x="164" y="10" width="2.5" height="72" fill="#1a1a1a"/><rect x="169" y="10" width="4" height="72" fill="#1a1a1a"/><rect x="176" y="10" width="1.5" height="72" fill="#1a1a1a"/><rect x="180" y="10" width="2" height="72" fill="#1a1a1a"/><rect x="184" y="10" width="3" height="72" fill="#1a1a1a"/><rect x="189" y="10" width="2.5" height="72" fill="#1a1a1a"/>
<text x="100" y="97" text-anchor="middle" font-size="10" font-family="monospace" fill="#666">WC2026032300642</text>
</svg>
<span class="qrcode-wrap__hint">点击条码可放大查看</span>
</div>
<div class="qrcode-wrap code-only--qr">
<!-- [交互] 点击二维码放大展示 -->
<svg class="code-img code-img--qr" onclick="openCodeOverlay('codeGastro')" 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="summary-card">
<div class="section-title">胃肠镜体检</div>
<div class="summary-list">
@@ -617,11 +557,6 @@
<div class="tips-card__item"><span class="tips-card__dot"></span><span>若需取消预约,请至少提前一天操作。</span></div>
</div>
<div class="progress-card">
<div class="progress-card__header">
<div class="progress-card__title">体检进度</div>
<div class="progress-card__ratio">0 / 2 项</div>
</div>
<div class="progress-bar-lg"><div class="progress-bar-lg__fill" style="width: 0%;"></div></div>
<!-- [交互] 点击切换已检/未检 Tab -->
<div class="project-tabs">
<button class="project-tabs__btn" type="button" id="gTabDone" onclick="switchProg('g',0)">已检项目 (0)</button>
@@ -646,11 +581,6 @@
</div>
</div>
<div class="progress-card">
<div class="progress-card__header">
<div class="progress-card__title">体检进度</div>
<div class="progress-card__ratio">2 / 2 项</div>
</div>
<div class="progress-bar-lg"><div class="progress-bar-lg__fill" style="width: 100%;"></div></div>
<!-- [交互] 点击切换已检/未检 Tab -->
<div class="project-tabs">
<button class="project-tabs__btn project-tabs__btn--active" type="button" id="gdTabDone" onclick="switchProg('gd',0)">已检项目 (2)</button>
+28 -21
View File
@@ -79,6 +79,16 @@
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;
@@ -244,10 +254,7 @@
display: inline-flex;
}
/* 报告图片 */
.image-section {
padding: 14px 16px 4px;
}
/* 影像报告 */
.image-section__label {
font-size: 12px;
color: var(--text-muted);
@@ -314,6 +321,11 @@
<!-- [交互] 返回按钮:返回体检报告列表 -->
<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">
@@ -374,15 +386,6 @@
</div>
</div>
<!-- 胃镜报告图片 -->
<div class="image-section">
<div class="image-section__label">胃镜报告图片</div>
<div class="image-view-link">
<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="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
查看
</div>
</div>
<div class="divider"></div>
<!-- ========== 肠镜检查 ========== -->
@@ -416,18 +419,22 @@
</div>
</div>
<!-- 肠镜报告图片 -->
<div class="image-section">
<div class="image-section__label">肠镜报告图片</div>
<div class="divider"></div>
<!-- ========== 影像报告 ========== -->
<div class="report-section">
<div class="report-section__title">影像报告</div>
<div class="image-section__label">胃镜报告</div>
<div class="image-view-link">
<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="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
查看
</div>
</div>
<!-- 货件报告图片 -->
<div class="image-section">
<div class="image-section__label">货件报告图片</div>
<div class="image-section__label">肠镜报告</div>
<div class="image-view-link">
<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="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
查看
</div>
<div class="image-section__label">活检报告</div>
<div class="image-view-link">
<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="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg>
查看
+2
View File
@@ -593,6 +593,8 @@ const SITE_MAP = [
{ file:'booking-project-selected.html', label:'预约-已选项目' },
{ file:'booking-date.html', label:'预约-选择日期' },
{ file:'booking-date-selected.html', label:'预约-已选日期' },
{ file:'gastro-preselect.html', label:'胃肠镜医院预选' },
{ file:'gastro-preselect-done.html', label:'胃肠镜预选-已提交' },
{ file:'my-appointments-all.html', label:'我的预约' },
{ file:'hospital-checkin.html', label:'到院体检' },
{ file:'reports.html', label:'体检报告' },