feat: 体检模块完善 — 员工端新增胃肠镜体检流程,管理端各配置页新增筛选/弹窗等功能

- 员工端:新增胃肠镜体检待体检/已体检详情页,预约卡片「已完成」统一改为「已体检」
- 管理端:医院范围/套餐模板/项目异常/医院费用/单位费用/计划等配置页完善
- 管理端:群体额度新增体检年度筛选栏,个人额度新增「设置额度」弹窗
This commit is contained in:
liuyunqin
2026-08-14 17:56:04 +08:00
parent 6dacd91ca5
commit 44e7f322ff
16 changed files with 3830 additions and 151 deletions
@@ -128,7 +128,7 @@
<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-done.html">体检</a>
<a class="tabs__item" href="my-appointments-cancelled.html">已取消</a>
</div>
@@ -149,11 +149,11 @@
</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 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>
@@ -116,7 +116,7 @@
<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" href="my-appointments-done.html">体检</a>
<a class="tabs__item tabs__item--active" href="my-appointments-cancelled.html">已取消</a>
</div>
@@ -552,7 +552,7 @@
<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 class="status-bar__text" style="color:#52c41a;">体检</div>
</div>
</div>
@@ -654,7 +654,7 @@
return '<div class="project-item">' +
'<div class="project-item__icon project-item__icon--done">&#10003;</div>' +
'<div class="project-item__name">' + name + '</div>' +
'<div class="project-item__status project-item__status--done">已完成</div></div>';
'<div class="project-item__status project-item__status--done">已体检</div></div>';
}
document.getElementById('doneList').innerHTML = allProjects.map(function(n) { return renderItem(n); }).join('');
@@ -0,0 +1,395 @@
<!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;
}
.summary-card,
.info-card {
background: #fff;
border-radius: 20px;
padding: 18px 16px;
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;
}
/* 体检进度 */
.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; }
</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">刘韵琴</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">2026年3月23日</div>
</div>
<div class="summary-item">
<div class="summary-item__label">体检项目</div>
<div class="summary-item__value">胃肠镜体检</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">2 / 2 项</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>
<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 = 2;
var doneCount = 2;
var allProjects = ['胃镜检查', '肠镜检查'];
function renderItem(name) {
return '<div class="project-item">' +
'<div class="project-item__icon project-item__icon--done">&#10003;</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">&#10003;</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,765 @@
<!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;
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" id="cancelBtn">取消预约</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">刘韵琴</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">2026年3月23日</div>
</div>
<div class="summary-item">
<div class="summary-item__label">体检项目</div>
<div class="summary-item__value">胃肠镜体检</div>
</div>
</div>
</div>
<!-- 体检须知 -->
<div class="tips-card">
<div class="tips-card__title">体检须知</div>
<div class="tips-card__item"><span class="tips-card__dot"></span><span>检查前3天请清淡饮食,避免高纤维、高脂肪食物。</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>检查当天需空腹,禁食禁水至少8小时。</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>若选择无痛胃肠镜,检查后24小时内请勿驾车。</span></div>
<div class="tips-card__item"><span class="tips-card__dot"></span><span>若需取消预约,请至少提前一天操作。</span></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">0 / 2 项</div>
</div>
<div class="progress-bar-lg"><div class="progress-bar-lg__fill" id="progressFill" style="width: 0%;"></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="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') || '0', 10);
var totalCount = parseInt(params.get('total') || '2', 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 = ['胃镜检查', '肠镜检查'];
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 ? '&#10003;' : '&#9679;') + '</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>
@@ -713,7 +713,7 @@
(isDone ? '&#10003;' : '&#9679;') + '</div>' +
'<div class="project-item__name">' + name + '</div>' +
'<div class="project-item__status project-item__status--' + (isDone ? 'done' : 'pending') + '">' +
(isDone ? '已完成' : '未检') + '</div></div>';
(isDone ? '已体检' : '未检') + '</div></div>';
}
document.getElementById('doneList').innerHTML = doneProjects.map(function(n) { return renderItem(n, true); }).join('');
@@ -121,7 +121,7 @@
<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 tabs__item--active" href="my-appointments-done.html">体检</a>
<a class="tabs__item" href="my-appointments-cancelled.html">已取消</a>
</div>
@@ -129,7 +129,7 @@
<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 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>
@@ -141,14 +141,14 @@
</div>
</a>
<a class="appointment-card" href="my-appointments-detail-done.html" style="text-decoration:none;color:inherit;">
<a class="appointment-card" href="my-appointments-detail-gastro-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 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 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>2/2</span></div>
@@ -278,7 +278,7 @@
<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-done.html">体检</a>
<a class="tabs__item" href="my-appointments-cancelled.html">已取消</a>
</div>
@@ -333,6 +333,30 @@
<div class="progress-bar"><div class="progress-bar__fill" style="width: 0%;"></div></div>
</div>
</a>
<a class="appointment-card" data-status="pending" href="my-appointments-detail-gastro.html?done=0&total=2&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/2</span>
</div>
<div class="progress-bar"><div class="progress-bar__fill" style="width: 0%;"></div></div>
</div>
</a>
</div>
</div>
</div>
+502 -13
View File
@@ -74,6 +74,68 @@
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;}
.page-btn:hover,.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
/* 抽屉弹窗 */
.drawer-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0);z-index:999;pointer-events:none;transition:background .3s;}
.drawer-overlay.open{background:rgba(0,0,0,0.45);pointer-events:auto;}
.drawer{position:fixed;top:0;right:-480px;bottom:0;width:480px;background:#fff;box-shadow:-2px 0 8px rgba(0,0,0,0.15);z-index:1000;transition:right .3s;display:flex;flex-direction:column;}
.drawer.open{right:0;}
.drawer__header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px;border-bottom:1px solid var(--border);flex-shrink:0;}
.drawer__title{font-size:var(--font-lg);font-weight:600;}
.drawer__close{width:32px;height:32px;border-radius:50%;border:none;background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-secondary);font-size:18px;}
.drawer__close:hover{background:#F5F5F5;}
.drawer__body{flex:1;overflow-y:auto;padding:24px;}
.drawer__footer{display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid var(--border);flex-shrink:0;}
/* 表单 */
.form-item{margin-bottom:20px;}
.form-label{font-size:var(--font-sm);color:var(--text-secondary);margin-bottom:8px;display:flex;align-items:center;gap:4px;font-weight:500;}
.form-label .required{color:var(--danger);}
.form-input{width:100%;height:40px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;}
.form-input:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
.form-input::-webkit-calendar-picker-indicator{cursor:pointer;opacity:.6;}
/* 开关 */
.switch-row{display:flex;align-items:center;gap:12px;}
.switch{width:40px;height:22px;border-radius:11px;background:#E8E8E8;cursor:pointer;position:relative;transition:.2s;flex-shrink:0;}
.switch.on{background:var(--primary);}
.switch::after{content:'';position:absolute;width:18px;height:18px;border-radius:50%;background:#fff;top:2px;left:2px;transition:.2s;box-shadow:0 1px 3px rgba(0,0,0,0.2);}
.switch.on::after{left:20px;}
.switch-label{font-size:var(--font-sm);color:var(--text-primary);}
/* 可搜索下拉 */
.search-select{position:relative;}
.search-select__input{width:100%;height:40px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 32px 0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 12px center;}
.search-select__input:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
.search-select__dropdown{position:absolute;top:44px;left:0;right:0;background:#fff;border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:0 4px 12px rgba(0,0,0,0.1);max-height:220px;overflow-y:auto;z-index:10;display:none;}
.search-select__dropdown.show{display:block;}
.search-select__option{padding:10px 12px;font-size:var(--font-sm);cursor:pointer;transition:background .15s;color:var(--text-primary);}
.search-select__option:hover,.search-select__option.active{background:var(--primary-light);color:var(--primary);}
.search-select__empty{padding:10px 12px;font-size:var(--font-sm);color:var(--text-placeholder);text-align:center;}
/* 筛选栏搜索下拉 */
.filter-bar .search-select{width:200px;}
.filter-bar .search-select__input{height:36px;}
.filter-bar .search-select__dropdown{top:40px;}
/* 分区标题与动态行 */
.form-section{font-size:var(--font-sm);font-weight:600;color:var(--text-primary);margin:24px 0 4px;padding-top:16px;border-top:1px solid var(--border);}
.form-tip{font-size:var(--font-xs);color:var(--text-placeholder);margin-bottom:12px;line-height:1.5;}
.dynamic-list{margin-bottom:4px;}
.dynamic-row{display:flex;align-items:center;gap:8px;margin-bottom:8px;}
.dynamic-row .form-input{flex:1;}
.dynamic-row .row-del{width:32px;height:32px;border-radius:var(--radius-sm);border:1px solid var(--border);background:#fff;color:var(--danger);cursor:pointer;flex-shrink:0;font-size:16px;line-height:1;}
.dynamic-row .row-del:hover{background:#fff1f0;border-color:var(--danger);}
.add-row-btn{display:inline-flex;align-items:center;gap:4px;font-size:var(--font-sm);color:var(--primary);cursor:pointer;border:1px dashed var(--primary);border-radius:var(--radius-sm);padding:5px 12px;background:var(--primary-light);user-select:none;}
.add-row-btn:hover{background:#bae7ff;}
/* 详情展示 */
.detail-item{margin-bottom:16px;}
.detail-label{font-size:var(--font-sm);color:var(--text-secondary);margin-bottom:6px;}
.detail-value{font-size:var(--font-sm);color:var(--text-primary);line-height:1.6;}
.detail-list-row{display:flex;justify-content:space-between;align-items:center;padding:10px 12px;background:#F8FBFF;border-radius:var(--radius-sm);margin-bottom:6px;font-size:var(--font-sm);}
.detail-list-row .detail-count{color:var(--primary);font-weight:600;}
.detail-empty{font-size:var(--font-sm);color:var(--text-placeholder);padding:4px 0;}
/* TAB 切换 */
.scope-tabs{display:flex;gap:0;margin-bottom:20px;border-bottom:2px solid var(--border);background:#fff;border-radius:var(--radius-md) var(--radius-md) 0 0;box-shadow:var(--shadow-sm);}
.scope-tab{padding:14px 32px;font-size:var(--font-base);color:var(--text-secondary);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-2px;transition:all .2s;font-weight:500;}
.scope-tab:hover{color:var(--primary);}
.scope-tab.active{color:var(--primary);border-bottom-color:var(--primary);font-weight:600;}
.tab-pane{display:none;}
.tab-pane.active{display:block;}
</style>
</head>
<body>
@@ -147,25 +209,31 @@
<!-- 主内容 -->
<main class="main">
<!-- TAB 切换 -->
<div class="scope-tabs">
<div class="scope-tab active" onclick="switchTab('normal', this)">常规体检</div>
<div class="scope-tab" onclick="switchTab('gastro', this)">胃肠镜体检</div>
</div>
<!-- 筛选栏 -->
<div class="filter-bar">
<div class="filter-item">
<label>医院名称:</label>
<input class="filter-input" type="text" placeholder="请输入" style="min-width:180px;">
<label>承检医院</label>
<div class="search-select" id="filter-search-select">
<input type="text" class="search-select__input" id="filter-search-input" placeholder="请输入医院名称搜索" autocomplete="off">
<input type="hidden" id="filter-search-value">
<div class="search-select__dropdown" id="filter-search-dropdown"></div>
</div>
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
<button class="btn btn-primary" onclick="queryTable()">查询</button>
<button class="btn btn-default" onclick="resetFilter()">重置</button>
</div>
<!-- 操作按钮 -->
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-primary">+ 新增</button>
</div>
<!-- 数据表格 -->
<!-- 常规体检 -->
<div class="tab-pane active" id="pane-normal">
<div class="table-card">
<div class="table-card__header">
<div class="table-card__title">医院承检范围列表</div>
<div class="table-card__title">常规体检承检范围列表</div>
</div>
<div class="table-card__content">
<table>
@@ -175,8 +243,8 @@
</tr>
</thead>
<tbody>
<tr><td>1</td><td>庆阳医院</td><td>200</td><td>2026-03-01</td><td>2026-10-31</td><td><span class="tag tag-green">有效</span></td><td><span class="link">详情</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">删除</span></td></tr>
<tr><td>2</td><td>兴隆园医院</td><td>150</td><td>2026-03-01</td><td>2026-10-31</td><td><span class="tag tag-green">有效</span></td><td><span class="link">详情</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">删除</span></td></tr>
<tr data-exceptions='[{"date":"2026-05-01","count":"100"},{"date":"2026-05-02","count":"80"}]' data-nodates='["2026-06-19","2026-06-20"]'><td>1</td><td>庆阳医院</td><td>200</td><td>2026-03-01</td><td>2026-10-31</td><td><span class="tag tag-green">有效</span></td><td><span class="link" onclick="openDetail(this)">详情</span> <span class="link" style="margin-left:8px;" onclick="openEdit(this)">编辑</span></td></tr>
<tr data-exceptions='[{"date":"2026-04-30","count":"120"}]' data-nodates='[]'><td>2</td><td>兴隆园医院</td><td>150</td><td>2026-03-01</td><td>2026-10-31</td><td><span class="tag tag-green">有效</span></td><td><span class="link" onclick="openDetail(this)">详情</span> <span class="link" style="margin-left:8px;" onclick="openEdit(this)">编辑</span></td></tr>
</tbody>
</table>
</div>
@@ -187,8 +255,129 @@
<select class="filter-select" style="min-width:70px;height:32px;"><option>10条</option><option>50条</option></select>
</div>
</div>
</div>
<!-- 胃肠镜体检 -->
<div class="tab-pane" id="pane-gastro">
<div class="table-card">
<div class="table-card__header">
<div class="table-card__title">胃肠镜体检承检范围列表</div>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<th>序号</th><th>医院名称</th><th>每日最多承检人数</th><th>承检开始日期</th><th>承检结束日期</th><th>有效标志</th><th>操作</th>
</tr>
</thead>
<tbody>
<tr data-exceptions='[{"date":"2026-05-10","count":"50"}]' data-nodates='["2026-06-20"]'><td>1</td><td>长安胃肠镜医院</td><td>80</td><td>2026-03-01</td><td>2026-10-31</td><td><span class="tag tag-green">有效</span></td><td><span class="link" onclick="openDetail(this)">详情</span> <span class="link" style="margin-left:8px;" onclick="openEdit(this)">编辑</span></td></tr>
<tr data-exceptions='[]' data-nodates='[]'><td>2</td><td>庆阳医院</td><td>60</td><td>2026-03-01</td><td>2026-10-31</td><td><span class="tag tag-green">有效</span></td><td><span class="link" onclick="openDetail(this)">详情</span> <span class="link" style="margin-left:8px;" onclick="openEdit(this)">编辑</span></td></tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>共 87 条</span>
<button class="page-btn active">1</button>
<span>每页</span>
<select class="filter-select" style="min-width:70px;height:32px;"><option>10条</option><option>50条</option></select>
</div>
</div>
</div>
</main>
<!-- 编辑医院承检范围抽屉 -->
<div class="drawer-overlay" id="drawer-overlay" onclick="closeDrawer()"></div>
<div class="drawer" id="scope-drawer">
<div class="drawer__header">
<div class="drawer__title">编辑医院承检范围</div>
<button class="drawer__close" onclick="closeDrawer()"></button>
</div>
<div class="drawer__body">
<div class="form-item">
<div class="form-label"><span class="required">*</span> 医院</div>
<div class="search-select" id="search-select">
<input type="text" class="search-select__input" id="search-input" placeholder="请输入医院名称搜索" autocomplete="off">
<input type="hidden" id="search-value">
<div class="search-select__dropdown" id="search-dropdown"></div>
</div>
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 每日最多承检人数</div>
<input class="form-input" id="form-capacity" type="number" min="1" placeholder="请输入人数">
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 承检开始日期</div>
<input class="form-input" id="form-start" type="date">
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 承检结束日期</div>
<input class="form-input" id="form-end" type="date">
</div>
<div class="form-item">
<div class="form-label">有效标志</div>
<div class="switch-row">
<div class="switch on" id="switch-valid" onclick="toggleValidSwitch(this)"></div>
<span class="switch-label" id="switch-valid-label">有效</span>
</div>
</div>
<!-- 例外人数设定 -->
<div class="form-section">例外人数设定</div>
<div class="form-tip">针对特定日期单独设置承检人数(覆盖"每日最多承检人数"),例如节假日或加号日期。</div>
<div class="dynamic-list" id="exception-list"></div>
<div class="add-row-btn" onclick="addExceptionRow()"> 添加例外</div>
<!-- 不参检日期 -->
<div class="form-section">不参检日期</div>
<div class="form-tip">设置该医院不承接体检的日期,系统将自动跳过这些日期。</div>
<div class="dynamic-list" id="nodate-list"></div>
<div class="add-row-btn" onclick="addNoDateRow()"> 添加日期</div>
</div>
<div class="drawer__footer">
<button class="btn btn-default" onclick="closeDrawer()">取消</button>
<button class="btn btn-primary" onclick="saveEdit()">确认保存</button>
</div>
</div>
<!-- 医院承检范围详情抽屉 -->
<div class="drawer-overlay" id="detail-overlay" onclick="closeDetail()"></div>
<div class="drawer" id="detail-drawer">
<div class="drawer__header">
<div class="drawer__title">医院承检范围详情</div>
<button class="drawer__close" onclick="closeDetail()"></button>
</div>
<div class="drawer__body">
<div class="detail-item">
<div class="detail-label">医院</div>
<div class="detail-value" id="detail-hospital"></div>
</div>
<div class="detail-item">
<div class="detail-label">每日最多承检人数</div>
<div class="detail-value" id="detail-capacity"></div>
</div>
<div class="detail-item">
<div class="detail-label">承检开始日期</div>
<div class="detail-value" id="detail-start"></div>
</div>
<div class="detail-item">
<div class="detail-label">承检结束日期</div>
<div class="detail-value" id="detail-end"></div>
</div>
<div class="detail-item">
<div class="detail-label">有效标志</div>
<div class="detail-value" id="detail-valid"></div>
</div>
<div class="form-section">例外人数设定</div>
<div id="detail-exceptions"></div>
<div class="form-section">不参检日期</div>
<div id="detail-nodates"></div>
</div>
<div class="drawer__footer">
<button class="btn btn-primary" onclick="closeDetail()">关闭</button>
</div>
</div>
<script>
/* 侧边栏展开/折叠交互 */
function toggleSubgroup(header){
@@ -201,6 +390,306 @@ function toggleSubgroup(header){
var sub=active.closest('.sidebar-subgroup');
if(sub)sub.classList.add('open');
})();
/* TAB 切换 */
function switchTab(type, el){
document.querySelectorAll('.scope-tab').forEach(function(t){ t.classList.remove('active'); });
document.querySelectorAll('.tab-pane').forEach(function(p){ p.classList.remove('active'); });
el.classList.add('active');
document.getElementById('pane-' + type).classList.add('active');
}
/* ===== 编辑医院承检范围抽屉 ===== */
var hospitalData = {
'h1': '庆阳医院',
'h2': '兴隆园医院',
'h3': '泾河医院',
'h4': '西安市中心医院',
'h5': '陕西省人民医院',
'h6': '咸阳市中心医院',
'h7': '宝鸡市人民医院',
'h8': '长安胃肠镜医院'
};
var editingTr = null;
function openEdit(btn){
var tr = btn.closest('tr');
editingTr = tr;
var cells = tr.cells;
var name = cells[1].textContent.trim();
var key = '';
for(var k in hospitalData){
if(hospitalData[k] === name){ key = k; break; }
}
document.getElementById('search-value').value = key;
document.getElementById('search-input').value = name;
document.getElementById('form-capacity').value = cells[2].textContent.trim();
document.getElementById('form-start').value = cells[3].textContent.trim();
document.getElementById('form-end').value = cells[4].textContent.trim();
var valid = cells[5].textContent.trim() === '有效';
var sw = document.getElementById('switch-valid');
sw.classList.toggle('on', valid);
document.getElementById('switch-valid-label').textContent = valid ? '有效' : '无效';
var exceptions = [];
try { exceptions = JSON.parse(tr.dataset.exceptions || '[]'); } catch(e){}
document.getElementById('exception-list').innerHTML = '';
if(exceptions.length === 0){ addExceptionRow(); }
else { exceptions.forEach(function(ex){ addExceptionRow(ex.date, ex.count); }); }
var noDates = [];
try { noDates = JSON.parse(tr.dataset.nodates || '[]'); } catch(e){}
document.getElementById('nodate-list').innerHTML = '';
if(noDates.length === 0){ addNoDateRow(); }
else { noDates.forEach(function(d){ addNoDateRow(d); }); }
document.getElementById('scope-drawer').classList.add('open');
document.getElementById('drawer-overlay').classList.add('open');
}
function closeDrawer(){
document.getElementById('scope-drawer').classList.remove('open');
document.getElementById('drawer-overlay').classList.remove('open');
}
/* 有效标志开关 */
function toggleValidSwitch(el){
el.classList.toggle('on');
document.getElementById('switch-valid-label').textContent = el.classList.contains('on') ? '有效' : '无效';
}
/* 可搜索下拉 */
(function(){
var input = document.getElementById('search-input');
var dropdown = document.getElementById('search-dropdown');
var hidden = document.getElementById('search-value');
function renderOptions(keyword){
dropdown.innerHTML = '';
var kw = keyword.trim().toLowerCase();
var has = false;
for(var key in hospitalData){
var name = hospitalData[key];
if(!kw || name.toLowerCase().indexOf(kw) !== -1){
has = true;
var opt = document.createElement('div');
opt.className = 'search-select__option';
if(hidden.value === key) opt.classList.add('active');
opt.textContent = name;
opt.dataset.value = key;
opt.onclick = function(){
hidden.value = key;
input.value = name;
dropdown.classList.remove('show');
};
dropdown.appendChild(opt);
}
}
if(!has){
var empty = document.createElement('div');
empty.className = 'search-select__empty';
empty.textContent = '无匹配医院';
dropdown.appendChild(empty);
}
}
input.addEventListener('focus', function(){
renderOptions(this.value);
dropdown.classList.add('show');
});
input.addEventListener('input', function(){
hidden.value = '';
renderOptions(this.value);
dropdown.classList.add('show');
});
document.addEventListener('click', function(e){
if(!e.target.closest('#search-select')){
dropdown.classList.remove('show');
}
});
})();
/* 筛选栏可搜索下拉 */
(function(){
var input = document.getElementById('filter-search-input');
var dropdown = document.getElementById('filter-search-dropdown');
var hidden = document.getElementById('filter-search-value');
function renderOptions(keyword){
dropdown.innerHTML = '';
var kw = keyword.trim().toLowerCase();
var has = false;
for(var key in hospitalData){
var name = hospitalData[key];
if(!kw || name.toLowerCase().indexOf(kw) !== -1){
has = true;
var opt = document.createElement('div');
opt.className = 'search-select__option';
if(hidden.value === key) opt.classList.add('active');
opt.textContent = name;
opt.dataset.value = key;
opt.onclick = function(){
hidden.value = key;
input.value = name;
dropdown.classList.remove('show');
};
dropdown.appendChild(opt);
}
}
if(!has){
var empty = document.createElement('div');
empty.className = 'search-select__empty';
empty.textContent = '无匹配医院';
dropdown.appendChild(empty);
}
}
input.addEventListener('focus', function(){
renderOptions(this.value);
dropdown.classList.add('show');
});
input.addEventListener('input', function(){
hidden.value = '';
renderOptions(this.value);
dropdown.classList.add('show');
});
document.addEventListener('click', function(e){
if(!e.target.closest('#filter-search-select')){
dropdown.classList.remove('show');
}
});
})();
/* 筛选查询 */
function queryTable(){
var value = document.getElementById('filter-search-value').value;
var activePane = document.querySelector('.tab-pane.active');
if(!activePane) return;
activePane.querySelectorAll('tbody tr').forEach(function(tr){
var name = tr.cells[1] ? tr.cells[1].textContent.trim() : '';
if(!value || (hospitalData[value] && name === hospitalData[value])){
tr.style.display = '';
} else {
tr.style.display = 'none';
}
});
}
/* 筛选重置 */
function resetFilter(){
document.getElementById('filter-search-input').value = '';
document.getElementById('filter-search-value').value = '';
document.getElementById('filter-search-dropdown').innerHTML = '';
var activePane = document.querySelector('.tab-pane.active');
if(activePane) activePane.querySelectorAll('tbody tr').forEach(function(tr){ tr.style.display = ''; });
}
/* 例外人数动态行 */
function addExceptionRow(date, count){
var list = document.getElementById('exception-list');
var row = document.createElement('div');
row.className = 'dynamic-row';
row.innerHTML = '<input type="date" class="form-input row-date" value="' + (date || '') + '">'
+ '<input type="number" class="form-input row-count" min="1" placeholder="例外人数" value="' + (count || '') + '" style="max-width:110px;">'
+ '<button class="row-del" onclick="this.parentElement.remove()">×</button>';
list.appendChild(row);
}
/* 不参检日期动态行 */
function addNoDateRow(date){
var list = document.getElementById('nodate-list');
var row = document.createElement('div');
row.className = 'dynamic-row';
row.innerHTML = '<input type="date" class="form-input row-date" value="' + (date || '') + '" placeholder="选择日期">'
+ '<button class="row-del" onclick="this.parentElement.remove()">×</button>';
list.appendChild(row);
}
/* 保存编辑 */
function saveEdit(){
if(!editingTr){ return; }
var value = document.getElementById('search-value').value;
if(!value || !hospitalData[value]){ alert('请选择医院'); return; }
var capacity = document.getElementById('form-capacity').value.trim();
if(!capacity || Number(capacity) <= 0){ alert('请输入正确的每日最多承检人数'); return; }
var start = document.getElementById('form-start').value;
var end = document.getElementById('form-end').value;
if(!start){ alert('请选择承检开始日期'); return; }
if(!end){ alert('请选择承检结束日期'); return; }
if(start > end){ alert('承检结束日期不能早于开始日期'); return; }
var exceptions = [];
document.querySelectorAll('#exception-list .dynamic-row').forEach(function(row){
var d = row.querySelector('.row-date').value;
var c = row.querySelector('.row-count').value.trim();
if(d && c) exceptions.push({ date: d, count: c });
});
var noDates = [];
document.querySelectorAll('#nodate-list .dynamic-row').forEach(function(row){
var d = row.querySelector('.row-date').value;
if(d) noDates.push(d);
});
var valid = document.getElementById('switch-valid').classList.contains('on');
var name = hospitalData[value];
var cells = editingTr.cells;
cells[1].textContent = name;
cells[2].textContent = capacity;
cells[3].textContent = start;
cells[4].textContent = end;
cells[5].innerHTML = valid ? '<span class="tag tag-green">有效</span>' : '<span class="tag tag-red">无效</span>';
editingTr.dataset.exceptions = JSON.stringify(exceptions);
editingTr.dataset.nodates = JSON.stringify(noDates);
closeDrawer();
}
/* 详情 */
function openDetail(el){
var tr = el.closest('tr');
var cells = tr.cells;
document.getElementById('detail-hospital').textContent = cells[1].textContent.trim();
document.getElementById('detail-capacity').textContent = cells[2].textContent.trim();
document.getElementById('detail-start').textContent = cells[3].textContent.trim();
document.getElementById('detail-end').textContent = cells[4].textContent.trim();
var valid = cells[5].textContent.trim() === '有效';
document.getElementById('detail-valid').innerHTML = valid
? '<span class="tag tag-green">有效</span>'
: '<span class="tag tag-red">无效</span>';
var exceptions = [];
try { exceptions = JSON.parse(tr.dataset.exceptions || '[]'); } catch(e){}
var exWrap = document.getElementById('detail-exceptions');
if(exceptions.length === 0){
exWrap.innerHTML = '<div class="detail-empty">暂无例外人数设定</div>';
} else {
exWrap.innerHTML = exceptions.map(function(ex){
return '<div class="detail-list-row"><span>' + ex.date + '</span><span class="detail-count">' + ex.count + ' 人</span></div>';
}).join('');
}
var noDates = [];
try { noDates = JSON.parse(tr.dataset.nodates || '[]'); } catch(e){}
var ndWrap = document.getElementById('detail-nodates');
if(noDates.length === 0){
ndWrap.innerHTML = '<div class="detail-empty">暂无不参检日期</div>';
} else {
ndWrap.innerHTML = noDates.map(function(d){
return '<div class="detail-list-row"><span>' + d + '</span></div>';
}).join('');
}
document.getElementById('detail-drawer').classList.add('open');
document.getElementById('detail-overlay').classList.add('open');
}
function closeDetail(){
document.getElementById('detail-drawer').classList.remove('open');
document.getElementById('detail-overlay').classList.remove('open');
}
</script>
</body>
</html>
@@ -74,6 +74,68 @@
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;}
.page-btn:hover,.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
/* 抽屉弹窗 */
.drawer-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0);z-index:999;pointer-events:none;transition:background .3s;}
.drawer-overlay.open{background:rgba(0,0,0,0.45);pointer-events:auto;}
.drawer{position:fixed;top:0;right:-820px;bottom:0;width:820px;background:#fff;box-shadow:-2px 0 8px rgba(0,0,0,0.15);z-index:1000;transition:right .3s;display:flex;flex-direction:column;}
.drawer.open{right:0;}
.drawer__header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px;border-bottom:1px solid var(--border);flex-shrink:0;}
.drawer__title{font-size:var(--font-lg);font-weight:600;}
.drawer__close{width:32px;height:32px;border-radius:50%;border:none;background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-secondary);font-size:18px;}
.drawer__close:hover{background:#F5F5F5;}
.drawer__body{flex:1;overflow-y:auto;padding:24px;}
.drawer__footer{display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid var(--border);flex-shrink:0;}
/* 表单 */
.form-row{display:flex;gap:16px;}
.form-row .form-item{flex:1;}
.form-item{margin-bottom:20px;}
.form-label{font-size:var(--font-sm);color:var(--text-secondary);margin-bottom:8px;display:flex;align-items:center;gap:4px;font-weight:500;}
.form-label .required{color:var(--danger);}
.form-input{width:100%;height:40px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;}
.form-input:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
.form-select{width:100%;height:40px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 12px center;appearance:none;cursor:pointer;}
.form-select:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
/* 可搜索下拉 */
.search-select{position:relative;}
.search-select__input{width:100%;height:40px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 48px 0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 12px center;}
.search-select__input:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
.search-select__clear{position:absolute;top:50%;right:28px;transform:translateY(-50%);width:18px;height:18px;border-radius:50%;background:#BFBFBF;color:#fff;display:none;align-items:center;justify-content:center;cursor:pointer;font-size:12px;line-height:1;z-index:2;}
.search-select__clear:hover{background:#999;}
.search-select.has-value:hover .search-select__clear{display:flex;}
.search-select__dropdown{position:absolute;top:44px;left:0;right:0;background:#fff;border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:0 4px 12px rgba(0,0,0,0.1);max-height:220px;overflow-y:auto;z-index:20;display:none;}
.search-select__dropdown.show{display:block;}
.search-select__option{padding:10px 12px;font-size:var(--font-sm);cursor:pointer;transition:background .15s;color:var(--text-primary);}
.search-select__option:hover{background:var(--primary-light);color:var(--primary);}
.search-select__empty{padding:10px 12px;font-size:var(--font-sm);color:var(--text-placeholder);text-align:center;}
.search-select--sm .search-select__input{height:32px;padding:0 36px 0 8px;background-position:right 8px center;}
.search-select--sm .search-select__dropdown{top:36px;}
.search-select--sm .search-select__clear{right:20px;width:16px;height:16px;font-size:10px;}
/* 项目 TAB */
.tab-box{margin-top:4px;border:1px solid var(--border);border-radius:var(--radius-sm);}
.tab-nav{display:flex;flex-wrap:wrap;background:#FAFAFA;border-bottom:1px solid var(--border);border-radius:var(--radius-sm) var(--radius-sm) 0 0;}
.tab-nav__item{padding:10px 16px;font-size:var(--font-sm);color:var(--text-secondary);cursor:pointer;border-bottom:2px solid transparent;transition:all .2s;white-space:nowrap;user-select:none;}
.tab-nav__item:hover{color:var(--primary);}
.tab-nav__item.active{color:var(--primary);border-bottom-color:var(--primary);font-weight:600;background:#fff;}
.tab-panel{display:none;padding:16px;}
.tab-panel.active{display:block;}
.panel-toolbar{display:flex;justify-content:flex-end;margin-bottom:12px;}
.cancer-fee{padding:16px 16px 0;}
/* 表格内行内控件 */
.row-input{width:100%;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 8px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#FAFAFA;}
.row-select{width:100%;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 24px 0 8px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 8px center;appearance:none;cursor:pointer;}
/* 中间弹窗 */
.modal-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.45);z-index:1100;display:none;align-items:center;justify-content:center;}
.modal-overlay.open{display:flex;}
.modal{background:#fff;border-radius:var(--radius-md);box-shadow:0 4px 16px rgba(0,0,0,0.15);width:480px;max-width:92vw;z-index:1101;}
.modal__header{display:flex;align-items:center;justify-content:space-between;padding:18px 24px;border-bottom:1px solid var(--border);}
.modal__title{font-size:var(--font-lg);font-weight:600;}
.modal__close{width:32px;height:32px;border-radius:50%;border:none;background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-secondary);font-size:18px;}
.modal__close:hover{background:#F5F5F5;}
.modal__body{padding:24px;}
.modal__footer{display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid var(--border);}
.form-input:disabled{background:#F5F5F5;color:var(--text-secondary);cursor:not-allowed;}
.form-select:disabled{background:#F5F5F5;color:var(--text-secondary);cursor:not-allowed;}
.copy-tip{margin-top:4px;font-size:var(--font-xs);color:var(--text-placeholder);line-height:1.6;background:#F5F7FA;border-radius:var(--radius-sm);padding:10px 12px;}
</style>
</head>
<body>
@@ -149,6 +211,12 @@
<main class="main">
<!-- 筛选栏 -->
<div class="filter-bar">
<div class="filter-item">
<label>体检年度:</label>
<select class="filter-select">
<option>请选择</option><option selected>2025</option><option>2024</option><option>2026</option>
</select>
</div>
<div class="filter-item">
<label>体检医院:</label>
<select class="filter-select">
@@ -177,7 +245,8 @@
<!-- 操作按钮 -->
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-primary">+ 复制上一年度模板</button>
<button class="btn btn-primary" onclick="openAddDrawer()">+ 新增</button>
<button class="btn btn-default" onclick="openCopyModal()">复制上一年度模板</button>
</div>
<!-- 数据表格 -->
@@ -189,13 +258,13 @@
<table>
<thead>
<tr>
<th>序号</th><th>医院名称</th><th>模板名称</th><th>性别</th><th>年龄区间</th><th>折扣类型</th><th>折扣数值(元)</th><th>折扣百分比(%</th><th>操作</th>
<th>序号</th><th>医院名称</th><th>体检年度</th><th>模板名称</th><th>性别</th><th>年龄区间</th><th>折扣类型</th><th>折扣数值(元)</th><th>折扣百分比(%</th><th>操作</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>泾河医院</td><td>45岁以上男性标准套餐</td><td></td><td>45岁及以上</td><td>固定减免</td><td>200.00</td><td></td><td><span class="link">详情</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>2</td><td>庆阳医院</td><td>35岁以下女性标准套餐</td><td></td><td>35岁以下</td><td>百分比折扣</td><td></td><td>85</td><td><span class="link">详情</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>3</td><td>延安医院</td><td>35-45岁通用套餐</td><td>通用</td><td>35-45岁</td><td>固定减免</td><td>150.00</td><td></td><td><span class="link">详情</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>1</td><td>泾河医院</td><td>2025</td><td>45岁以上男性标准套餐</td><td></td><td>45岁及以上</td><td>固定减免</td><td>200.00</td><td></td><td><span class="link">详情</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>2</td><td>庆阳医院</td><td>2025</td><td>35岁以下女性标准套餐</td><td></td><td>35岁以下</td><td>百分比折扣</td><td></td><td>85</td><td><span class="link">详情</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>3</td><td>延安医院</td><td>2025</td><td>35-45岁通用套餐</td><td>通用</td><td>35-45岁</td><td>固定减免</td><td>150.00</td><td></td><td><span class="link">详情</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
</tbody>
</table>
</div>
@@ -209,6 +278,170 @@
</div>
</main>
<!-- 新增组合模板抽屉 -->
<div class="drawer-overlay" id="add-overlay" onclick="closeAddDrawer()"></div>
<div class="drawer" id="add-drawer">
<div class="drawer__header">
<div class="drawer__title">新增组合模板</div>
<button class="drawer__close" onclick="closeAddDrawer()"></button>
</div>
<div class="drawer__body">
<div class="form-row">
<div class="form-item">
<div class="form-label"><span class="required">*</span> 组合模板名称</div>
<input class="form-input" id="tpl-name" placeholder="请输入组合模板名称">
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 体检医院</div>
<div id="tpl-hospital-select"></div>
</div>
</div>
<div class="form-row">
<div class="form-item">
<div class="form-label"><span class="required">*</span> 性别</div>
<select class="form-select" id="tpl-gender" onchange="onGenderChange()">
<option value="">请选择</option>
<option value="男"></option>
<option value="女"></option>
<option value="通用">通用</option>
</select>
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 年龄范围</div>
<select class="form-select" id="tpl-age">
<option value="">请选择</option>
<option>35岁以下</option>
<option>35-45岁</option>
<option>45岁及以上</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-item">
<div class="form-label"><span class="required">*</span> 折扣类型</div>
<select class="form-select" id="tpl-discount-type">
<option value="">请选择</option>
<option value="数值">数值</option>
<option value="百分比">百分比</option>
</select>
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 折扣金额(元)</div>
<input class="form-input" id="tpl-discount-amount" type="number" min="0" step="0.01" placeholder="请输入折扣金额">
</div>
</div>
<div class="tab-box">
<div class="tab-nav" id="tpl-tab-nav">
<div class="tab-nav__item active" data-tab="required" onclick="switchProjectTab(this)">必检项目</div>
<div class="tab-nav__item" data-tab="optional" onclick="switchProjectTab(this)">自选项目</div>
<div class="tab-nav__item" data-tab="gyn-unmarried" onclick="switchProjectTab(this)">妇科未婚项目</div>
<div class="tab-nav__item" data-tab="gyn-married" onclick="switchProjectTab(this)">妇科已婚项目</div>
<div class="tab-nav__item" data-tab="cancer-septin9" onclick="switchProjectTab(this)">防癌筛查项目(Septin9</div>
<div class="tab-nav__item" data-tab="cancer-ca724" onclick="switchProjectTab(this)">防癌筛查项目(CA724</div>
</div>
<div class="cancer-fee" id="cancer-fee-box" style="display:none;">
<div class="form-item">
<div class="form-label"><span class="required">*</span> 防癌筛查默认费用(元)</div>
<input class="form-input" id="cancer-fee-input" type="number" min="0" step="0.01" placeholder="请输入防癌筛查默认费用">
</div>
</div>
<div class="tab-panel active" id="panel-required">
<div class="panel-toolbar"><button class="btn btn-default" onclick="addProjectRow('required')">+ 添加项目</button></div>
<table>
<thead><tr><th>体检项目</th><th>项目编码</th><th>项目标记</th><th>操作</th></tr></thead>
<tbody id="tbody-required"></tbody>
</table>
</div>
<div class="tab-panel" id="panel-optional">
<div class="panel-toolbar"><button class="btn btn-default" onclick="addProjectRow('optional')">+ 添加项目</button></div>
<table>
<thead><tr><th>体检项目</th><th>项目编码</th><th>项目标记</th><th>操作</th></tr></thead>
<tbody id="tbody-optional"></tbody>
</table>
</div>
<div class="tab-panel" id="panel-gyn-unmarried">
<div class="panel-toolbar"><button class="btn btn-default" onclick="addProjectRow('gyn-unmarried')">+ 添加项目</button></div>
<table>
<thead><tr><th>体检项目</th><th>项目编码</th><th>项目标记</th><th>操作</th></tr></thead>
<tbody id="tbody-gyn-unmarried"></tbody>
</table>
</div>
<div class="tab-panel" id="panel-gyn-married">
<div class="panel-toolbar"><button class="btn btn-default" onclick="addProjectRow('gyn-married')">+ 添加项目</button></div>
<table>
<thead><tr><th>体检项目</th><th>项目编码</th><th>项目标记</th><th>操作</th></tr></thead>
<tbody id="tbody-gyn-married"></tbody>
</table>
</div>
<div class="tab-panel" id="panel-cancer-septin9">
<div class="panel-toolbar"><button class="btn btn-default" onclick="addProjectRow('cancer-septin9')">+ 添加项目</button></div>
<table>
<thead><tr><th>体检项目</th><th>项目编码</th><th>项目标记</th><th>操作</th></tr></thead>
<tbody id="tbody-cancer-septin9"></tbody>
</table>
</div>
<div class="tab-panel" id="panel-cancer-ca724">
<div class="panel-toolbar"><button class="btn btn-default" onclick="addProjectRow('cancer-ca724')">+ 添加项目</button></div>
<table>
<thead><tr><th>体检项目</th><th>项目编码</th><th>项目标记</th><th>操作</th></tr></thead>
<tbody id="tbody-cancer-ca724"></tbody>
</table>
</div>
</div>
</div>
<div class="drawer__footer">
<button class="btn btn-default" onclick="closeAddDrawer()">取消</button>
<button class="btn btn-primary" onclick="saveComboTemplate()">确认保存</button>
</div>
</div>
<!-- 复制上一年度模板弹窗 -->
<div class="modal-overlay" id="copy-modal-overlay" onclick="if(event.target===this)closeCopyModal()">
<div class="modal">
<div class="modal__header">
<div class="modal__title">复制上一年度模板</div>
<button class="modal__close" onclick="closeCopyModal()"></button>
</div>
<div class="modal__body">
<div class="form-row">
<div class="form-item">
<div class="form-label">上一年度(复制来源)</div>
<input class="form-input" id="copy-source-year" value="2024" disabled>
</div>
<div class="form-item">
<div class="form-label">本年度(复制目标)</div>
<input class="form-input" id="copy-target-year" value="2025" disabled>
</div>
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 体检医院</div>
<select class="form-select" id="copy-hospital" onchange="onCopyHospitalChange()">
<option value="">请选择</option>
<option>泾河医院</option>
<option>庆阳医院</option>
<option>延安医院</option>
<option>兴隆园医院</option>
<option>宁夏宝石花医院</option>
</select>
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 模板</div>
<select class="form-select" id="copy-template" disabled>
<option value="">请先选择体检医院</option>
</select>
</div>
<div class="copy-tip">确认后将把所选医院的上一年度(2024)模板复制到本年度(2025),已存在的同名模板将被覆盖。</div>
</div>
<div class="modal__footer">
<button class="btn btn-default" onclick="closeCopyModal()">取消</button>
<button class="btn btn-primary" onclick="saveCopyTemplate()">确认复制</button>
</div>
</div>
</div>
<script>
/* 侧边栏展开/折叠交互 */
function toggleSubgroup(header){
@@ -221,6 +454,249 @@ function toggleSubgroup(header){
var sub=active.closest('.sidebar-subgroup');
if(sub)sub.classList.add('open');
})();
/* ===== 新增组合模板抽屉 ===== */
var hospitalData = ['泾河医院','庆阳医院','延安医院','兴隆园医院','宁夏宝石花医院'];
var projectData = [
{name:'经颅多普勒', code:'TCD-001'},
{name:'腹部彩超', code:'BUS-002'},
{name:'血常规', code:'BLD-003'},
{name:'心电图', code:'ECG-004'},
{name:'胸部X光', code:'XRY-005'},
{name:'肝功能', code:'LFT-006'},
{name:'肾功能', code:'RFT-007'},
{name:'空腹血糖', code:'GLU-008'},
{name:'血脂四项', code:'LIP-009'},
{name:'尿常规', code:'URI-010'},
{name:'胃镜', code:'GAS-011'},
{name:'肠镜', code:'COL-012'}
];
var projectTabKeys = ['required','optional','gyn-unmarried','gyn-married','cancer-septin9','cancer-ca724'];
/* 可搜索下拉通用组件 */
function createSearchSelect(data, opts){
var container = document.createElement('div');
container.className = 'search-select' + (opts.sm ? ' search-select--sm' : '');
var input = document.createElement('input');
input.type = 'text';
input.className = 'search-select__input';
input.placeholder = opts.placeholder || '请输入关键词搜索';
input.setAttribute('autocomplete', 'off');
var hidden = document.createElement('input');
hidden.type = 'hidden';
var clear = document.createElement('span');
clear.className = 'search-select__clear';
clear.textContent = '✕';
clear.title = '清除';
var dropdown = document.createElement('div');
dropdown.className = 'search-select__dropdown';
container.appendChild(input);
container.appendChild(hidden);
container.appendChild(clear);
container.appendChild(dropdown);
function getLabel(item){ return opts.getLabel ? opts.getLabel(item) : String(item); }
function renderOptions(kw){
dropdown.innerHTML = '';
var kwl = kw.trim().toLowerCase();
var has = false;
data.forEach(function(item, idx){
var label = getLabel(item);
if(!kwl || label.toLowerCase().indexOf(kwl) !== -1){
has = true;
(function(item, label){
var opt = document.createElement('div');
opt.className = 'search-select__option';
opt.textContent = label;
opt.onclick = function(){
hidden.value = idx;
input.value = label;
container.classList.add('has-value');
dropdown.classList.remove('show');
if(opts.onSelect) opts.onSelect(item);
};
dropdown.appendChild(opt);
})(item, label);
}
});
if(!has){
var empty = document.createElement('div');
empty.className = 'search-select__empty';
empty.textContent = '无匹配';
dropdown.appendChild(empty);
}
}
input.addEventListener('focus', function(){ renderOptions(this.value); dropdown.classList.add('show'); });
input.addEventListener('input', function(){ hidden.value=''; renderOptions(this.value); dropdown.classList.add('show'); });
clear.addEventListener('click', function(){
input.value=''; hidden.value=''; container.classList.remove('has-value'); dropdown.classList.remove('show');
if(opts.onSelect) opts.onSelect(null);
});
document.addEventListener('click', function(e){
if(!container.contains(e.target)){ dropdown.classList.remove('show'); }
});
return {
container: container,
getValue: function(){ return hidden.value; },
clear: function(){ input.value=''; hidden.value=''; container.classList.remove('has-value'); dropdown.classList.remove('show'); }
};
}
/* 体检医院搜索下拉 */
var hospitalSelect = createSearchSelect(hospitalData, {
placeholder: '请输入医院名称搜索',
getLabel: function(item){ return item; }
});
document.getElementById('tpl-hospital-select').appendChild(hospitalSelect.container);
function openAddDrawer(){
resetAddDrawer();
document.getElementById('add-drawer').classList.add('open');
document.getElementById('add-overlay').classList.add('open');
}
function closeAddDrawer(){
document.getElementById('add-drawer').classList.remove('open');
document.getElementById('add-overlay').classList.remove('open');
}
function resetAddDrawer(){
document.getElementById('tpl-name').value = '';
hospitalSelect.clear();
document.getElementById('tpl-gender').value = '';
document.getElementById('tpl-age').value = '';
document.getElementById('tpl-discount-type').value = '';
document.getElementById('tpl-discount-amount').value = '';
document.getElementById('cancer-fee-input').value = '';
projectTabKeys.forEach(function(k){ document.getElementById('tbody-' + k).innerHTML = ''; });
switchProjectTab(document.querySelector('#tpl-tab-nav .tab-nav__item[data-tab="required"]'));
onGenderChange();
}
/* 性别切换:男隐藏妇科 tab */
function onGenderChange(){
var gender = document.getElementById('tpl-gender').value;
var showGyn = gender !== '男';
document.querySelectorAll('#tpl-tab-nav .tab-nav__item[data-tab="gyn-unmarried"], #tpl-tab-nav .tab-nav__item[data-tab="gyn-married"]').forEach(function(t){
t.style.display = showGyn ? '' : 'none';
});
var active = document.querySelector('#tpl-tab-nav .tab-nav__item.active');
if(active && (active.dataset.tab === 'gyn-unmarried' || active.dataset.tab === 'gyn-married') && !showGyn){
switchProjectTab(document.querySelector('#tpl-tab-nav .tab-nav__item[data-tab="required"]'));
}
}
/* 项目 tab 切换 */
function switchProjectTab(el){
document.querySelectorAll('#tpl-tab-nav .tab-nav__item').forEach(function(t){ t.classList.remove('active'); });
el.classList.add('active');
var key = el.dataset.tab;
document.querySelectorAll('.tab-panel').forEach(function(p){ p.classList.remove('active'); });
document.getElementById('panel-' + key).classList.add('active');
var isCancer = key === 'cancer-septin9' || key === 'cancer-ca724';
document.getElementById('cancer-fee-box').style.display = isCancer ? 'block' : 'none';
}
/* 添加/删除项目行 */
function addProjectRow(tabKey){
var tbody = document.getElementById('tbody-' + tabKey);
var tr = document.createElement('tr');
var tdItem = document.createElement('td');
var tdCode = document.createElement('td');
var tdMark = document.createElement('td');
var tdOp = document.createElement('td');
var codeInput = document.createElement('input');
codeInput.className = 'row-input';
codeInput.readOnly = true;
codeInput.placeholder = '自动填充';
var ss = createSearchSelect(projectData, {
sm: true,
placeholder: '请选择体检项目',
getLabel: function(item){ return item.name + '' + item.code + ''; },
onSelect: function(item){ codeInput.value = item ? item.code : ''; }
});
var markSelect = document.createElement('select');
markSelect.className = 'row-select';
['一般项目','重点项目'].forEach(function(m){
var o = document.createElement('option');
o.textContent = m;
markSelect.appendChild(o);
});
var del = document.createElement('span');
del.className = 'link';
del.style.color = 'var(--danger)';
del.textContent = '删除';
del.onclick = function(){ tr.remove(); };
tdItem.appendChild(ss.container);
tdCode.appendChild(codeInput);
tdMark.appendChild(markSelect);
tdOp.appendChild(del);
tr.appendChild(tdItem);
tr.appendChild(tdCode);
tr.appendChild(tdMark);
tr.appendChild(tdOp);
tbody.appendChild(tr);
}
function saveComboTemplate(){
if(!document.getElementById('tpl-name').value.trim()){ alert('请输入组合模板名称'); return; }
if(hospitalSelect.getValue() === ''){ alert('请选择体检医院'); return; }
if(!document.getElementById('tpl-gender').value){ alert('请选择性别'); return; }
if(!document.getElementById('tpl-age').value){ alert('请选择年龄范围'); return; }
if(!document.getElementById('tpl-discount-type').value){ alert('请选择折扣类型'); return; }
if(!document.getElementById('tpl-discount-amount').value){ alert('请输入折扣金额'); return; }
alert('已保存(原型演示)');
closeAddDrawer();
}
/* ===== 复制上一年度模板弹窗 ===== */
var templateData = {
'泾河医院': ['45岁以上男性标准套餐', '35岁以下女性标准套餐', '35-45岁通用套餐'],
'庆阳医院': ['35岁以下女性标准套餐', '45岁及以上通用套餐', '35-45岁通用套餐'],
'延安医院': ['35-45岁通用套餐', '45岁以上男性标准套餐'],
'兴隆园医院': ['35岁以下女性标准套餐', '35-45岁通用套餐'],
'宁夏宝石花医院': ['35-45岁通用套餐', '45岁以上男性标准套餐', '35岁以下女性标准套餐']
};
function openCopyModal(){
document.getElementById('copy-hospital').value = '';
onCopyHospitalChange();
document.getElementById('copy-modal-overlay').classList.add('open');
}
function closeCopyModal(){
document.getElementById('copy-modal-overlay').classList.remove('open');
}
function onCopyHospitalChange(){
var hospital = document.getElementById('copy-hospital').value;
var tplSelect = document.getElementById('copy-template');
tplSelect.innerHTML = '';
var ph = document.createElement('option');
ph.value = '';
ph.textContent = hospital ? '请选择模板' : '请先选择体检医院';
tplSelect.appendChild(ph);
(templateData[hospital] || []).forEach(function(name){
var o = document.createElement('option');
o.textContent = name;
tplSelect.appendChild(o);
});
tplSelect.disabled = !hospital;
}
function saveCopyTemplate(){
var hospital = document.getElementById('copy-hospital').value;
var template = document.getElementById('copy-template').value;
if(!hospital){ alert('请选择体检医院'); return; }
if(!template){ alert('请选择模板'); return; }
alert('已复制「' + hospital + ' - ' + template + '」到本年度(原型演示)');
closeCopyModal();
}
</script>
</body>
</html>
@@ -74,6 +74,59 @@
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;}
.page-btn:hover,.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
/* 抽屉弹窗 */
.drawer-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0);z-index:999;pointer-events:none;transition:background .3s;}
.drawer-overlay.open{background:rgba(0,0,0,0.45);pointer-events:auto;}
.drawer{position:fixed;top:0;right:-820px;bottom:0;width:820px;background:#fff;box-shadow:-2px 0 8px rgba(0,0,0,0.15);z-index:1000;transition:right .3s;display:flex;flex-direction:column;}
.drawer.open{right:0;}
.drawer__header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px;border-bottom:1px solid var(--border);flex-shrink:0;}
.drawer__title{font-size:var(--font-lg);font-weight:600;}
.drawer__close{width:32px;height:32px;border-radius:50%;border:none;background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-secondary);font-size:18px;}
.drawer__close:hover{background:#F5F5F5;}
.drawer__body{flex:1;overflow-y:auto;padding:24px;}
.drawer__footer{display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid var(--border);flex-shrink:0;}
/* 表单 */
.form-row{display:flex;gap:16px;}
.form-row .form-item{flex:1;}
.form-item{margin-bottom:20px;}
.form-label{font-size:var(--font-sm);color:var(--text-secondary);margin-bottom:8px;display:flex;align-items:center;gap:4px;font-weight:500;}
.form-label .required{color:var(--danger);}
.form-input{width:100%;height:40px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;}
.form-input:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
.form-select{width:100%;height:40px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 12px center;appearance:none;cursor:pointer;}
.form-select:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
.form-input:disabled{background:#F5F5F5;color:var(--text-secondary);cursor:not-allowed;}
.form-select:disabled{background:#F5F5F5;color:var(--text-secondary);cursor:not-allowed;}
/* 可搜索下拉 */
.search-select{position:relative;}
.search-select__input{width:100%;height:40px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 48px 0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 12px center;}
.search-select__input:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
.search-select__clear{position:absolute;top:50%;right:28px;transform:translateY(-50%);width:18px;height:18px;border-radius:50%;background:#BFBFBF;color:#fff;display:none;align-items:center;justify-content:center;cursor:pointer;font-size:12px;line-height:1;z-index:2;}
.search-select__clear:hover{background:#999;}
.search-select.has-value:hover .search-select__clear{display:flex;}
.search-select__dropdown{position:absolute;top:44px;left:0;right:0;background:#fff;border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:0 4px 12px rgba(0,0,0,0.1);max-height:220px;overflow-y:auto;z-index:20;display:none;}
.search-select__dropdown.show{display:block;}
.search-select__option{padding:10px 12px;font-size:var(--font-sm);cursor:pointer;transition:background .15s;color:var(--text-primary);}
.search-select__option:hover{background:var(--primary-light);color:var(--primary);}
.search-select__empty{padding:10px 12px;font-size:var(--font-sm);color:var(--text-placeholder);text-align:center;}
.search-select--sm .search-select__input{height:32px;padding:0 36px 0 8px;background-position:right 8px center;}
.search-select--sm .search-select__dropdown{top:36px;}
.search-select--sm .search-select__clear{right:20px;width:16px;height:16px;font-size:10px;}
.search-select.is-disabled .search-select__input{background:#F5F5F5;color:var(--text-secondary);cursor:not-allowed;}
.search-select.is-disabled .search-select__clear{display:none !important;}
.row-select:disabled{background:#F5F5F5;color:var(--text-secondary);cursor:not-allowed;}
/* 项目 TAB */
.tab-box{margin-top:4px;border:1px solid var(--border);border-radius:var(--radius-sm);}
.tab-nav{display:flex;flex-wrap:wrap;background:#FAFAFA;border-bottom:1px solid var(--border);border-radius:var(--radius-sm) var(--radius-sm) 0 0;}
.tab-nav__item{padding:10px 16px;font-size:var(--font-sm);color:var(--text-secondary);cursor:pointer;border-bottom:2px solid transparent;transition:all .2s;white-space:nowrap;user-select:none;}
.tab-nav__item:hover{color:var(--primary);}
.tab-nav__item.active{color:var(--primary);border-bottom-color:var(--primary);font-weight:600;background:#fff;}
.tab-panel{display:none;padding:16px;}
.tab-panel.active{display:block;}
.panel-toolbar{display:flex;justify-content:flex-end;margin-bottom:12px;}
/* 表格内行内控件 */
.row-input{width:100%;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 8px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#FAFAFA;}
.row-select{width:100%;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 24px 0 8px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 8px center;appearance:none;cursor:pointer;}
</style>
</head>
<body>
@@ -155,12 +208,30 @@
<option>请选择</option><option>45岁以上男性标准套餐</option><option>35岁以下女性标准套餐</option><option>35-45岁通用套餐</option>
</select>
</div>
<div class="filter-item">
<label>体检年度:</label>
<select class="filter-select">
<option>请选择</option><option selected>2025</option><option>2024</option><option>2026</option>
</select>
</div>
<div class="filter-item">
<label>体检医院:</label>
<select class="filter-select">
<option>请选择</option><option>泾河医院</option><option>庆阳医院</option><option>延安医院</option><option>兴隆园医院</option><option>宁夏宝石花医院</option>
</select>
</div>
<div class="filter-item">
<label>性别:</label>
<select class="filter-select" style="min-width:90px;">
<option>请选择</option><option></option><option></option><option>通用</option>
</select>
</div>
<div class="filter-item">
<label>年龄区间:</label>
<select class="filter-select">
<option>请选择</option><option>35岁以下</option><option>35-45岁</option><option>45岁及以上</option>
</select>
</div>
<div class="filter-item">
<label>单位:</label>
<select class="filter-select">
@@ -179,7 +250,7 @@
<!-- 操作按钮 -->
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-primary">+ 新增</button>
<button class="btn btn-primary" onclick="openAddDrawer()">+ 新增</button>
<button class="btn btn-default">批量删除</button>
</div>
@@ -192,13 +263,13 @@
<table>
<thead>
<tr>
<th>序号</th><th>项目组合模板</th><th>单位</th><th>医院名称</th><th>性别</th><th>年龄区间</th><th>是否有效</th><th>创建日期</th><th>更新日期</th><th>操作</th>
<th>序号</th><th>项目组合模板</th><th>单位</th><th>医院名称</th><th>体检年度</th><th>性别</th><th>年龄区间</th><th>是否有效</th><th>创建日期</th><th>更新日期</th><th>操作</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>45岁以上男性标准套餐</td><td>第一采油厂</td><td>泾河医院</td><td></td><td>45岁及以上</td><td><span class="tag tag-green">有效</span></td><td>2025-03-01</td><td>2025-04-15</td><td><span class="link">详情</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>2</td><td>35岁以下女性标准套餐</td><td>第二采油厂</td><td>庆阳医院</td><td></td><td>35岁以下</td><td><span class="tag tag-green">有效</span></td><td>2025-03-05</td><td>2025-04-20</td><td><span class="link">详情</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>3</td><td>35-45岁通用套餐</td><td>第三采油厂</td><td>延安医院</td><td>通用</td><td>35-45岁</td><td><span class="tag tag-red">无效</span></td><td>2025-02-18</td><td>2025-03-10</td><td><span class="link">详情</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>1</td><td>45岁以上男性标准套餐</td><td>第一采油厂</td><td>泾河医院</td><td>2025</td><td></td><td>45岁及以上</td><td><span class="tag tag-green">有效</span></td><td>2025-03-01</td><td>2025-04-15</td><td><span class="link">详情</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>2</td><td>35岁以下女性标准套餐</td><td>第二采油厂</td><td>庆阳医院</td><td>2025</td><td></td><td>35岁以下</td><td><span class="tag tag-green">有效</span></td><td>2025-03-05</td><td>2025-04-20</td><td><span class="link">详情</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>3</td><td>35-45岁通用套餐</td><td>第三采油厂</td><td>延安医院</td><td>2025</td><td>通用</td><td>35-45岁</td><td><span class="tag tag-red">无效</span></td><td>2025-02-18</td><td>2025-03-10</td><td><span class="link">详情</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
</tbody>
</table>
</div>
@@ -214,6 +285,117 @@
</div>
</main>
<!-- 新增例外配置抽屉 -->
<div class="drawer-overlay" id="add-overlay" onclick="closeAddDrawer()"></div>
<div class="drawer" id="add-drawer">
<div class="drawer__header">
<div class="drawer__title">新增例外配置</div>
<button class="drawer__close" onclick="closeAddDrawer()"></button>
</div>
<div class="drawer__body">
<div class="form-row">
<div class="form-item">
<div class="form-label"><span class="required">*</span> 体检年度</div>
<select class="form-select" id="ex-year"></select>
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 单位</div>
<select class="form-select" id="ex-unit">
<option value="">请选择</option>
<option>第一采油厂</option>
<option>第二采油厂</option>
<option>第三采油厂</option>
</select>
</div>
</div>
<div class="form-row">
<div class="form-item">
<div class="form-label"><span class="required">*</span> 体检医院</div>
<div id="ex-hospital-select"></div>
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 项目组合模板</div>
<div id="ex-tpl-select"></div>
</div>
</div>
<div class="form-row">
<div class="form-item">
<div class="form-label"><span class="required">*</span> 性别</div>
<input class="form-input" id="ex-gender" disabled placeholder="根据项目组合模板自动回填">
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 年龄范围</div>
<input class="form-input" id="ex-age" disabled placeholder="根据项目组合模板自动回填">
</div>
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 是否有效</div>
<select class="form-select" id="ex-valid">
<option>有效</option>
<option>无效</option>
</select>
</div>
<div class="tab-box">
<div class="tab-nav" id="ex-tab-nav">
<div class="tab-nav__item active" data-tab="required" onclick="switchProjectTab(this)">必检项目</div>
<div class="tab-nav__item" data-tab="optional" onclick="switchProjectTab(this)">自选项目</div>
<div class="tab-nav__item" data-tab="gyn-unmarried" onclick="switchProjectTab(this)">妇科未婚项目</div>
<div class="tab-nav__item" data-tab="gyn-married" onclick="switchProjectTab(this)">妇科已婚项目</div>
<div class="tab-nav__item" data-tab="cancer-septin9" onclick="switchProjectTab(this)">防癌筛查项目(Septin9</div>
<div class="tab-nav__item" data-tab="cancer-ca724" onclick="switchProjectTab(this)">防癌筛查项目(CA724</div>
</div>
<div class="tab-panel active" id="panel-required">
<div class="panel-toolbar"><button class="btn btn-default" onclick="addProjectRow('required')">+ 添加项目</button></div>
<table>
<thead><tr><th>体检项目</th><th>项目编码</th><th>项目标记</th><th>操作</th></tr></thead>
<tbody id="tbody-required"></tbody>
</table>
</div>
<div class="tab-panel" id="panel-optional">
<div class="panel-toolbar"><button class="btn btn-default" onclick="addProjectRow('optional')">+ 添加项目</button></div>
<table>
<thead><tr><th>体检项目</th><th>项目编码</th><th>项目标记</th><th>操作</th></tr></thead>
<tbody id="tbody-optional"></tbody>
</table>
</div>
<div class="tab-panel" id="panel-gyn-unmarried">
<div class="panel-toolbar"><button class="btn btn-default" onclick="addProjectRow('gyn-unmarried')">+ 添加项目</button></div>
<table>
<thead><tr><th>体检项目</th><th>项目编码</th><th>项目标记</th><th>操作</th></tr></thead>
<tbody id="tbody-gyn-unmarried"></tbody>
</table>
</div>
<div class="tab-panel" id="panel-gyn-married">
<div class="panel-toolbar"><button class="btn btn-default" onclick="addProjectRow('gyn-married')">+ 添加项目</button></div>
<table>
<thead><tr><th>体检项目</th><th>项目编码</th><th>项目标记</th><th>操作</th></tr></thead>
<tbody id="tbody-gyn-married"></tbody>
</table>
</div>
<div class="tab-panel" id="panel-cancer-septin9">
<div class="panel-toolbar"><button class="btn btn-default" onclick="addProjectRow('cancer-septin9')">+ 添加项目</button></div>
<table>
<thead><tr><th>体检项目</th><th>项目编码</th><th>项目标记</th><th>操作</th></tr></thead>
<tbody id="tbody-cancer-septin9"></tbody>
</table>
</div>
<div class="tab-panel" id="panel-cancer-ca724">
<div class="panel-toolbar"><button class="btn btn-default" onclick="addProjectRow('cancer-ca724')">+ 添加项目</button></div>
<table>
<thead><tr><th>体检项目</th><th>项目编码</th><th>项目标记</th><th>操作</th></tr></thead>
<tbody id="tbody-cancer-ca724"></tbody>
</table>
</div>
</div>
</div>
<div class="drawer__footer">
<button class="btn btn-default" onclick="closeAddDrawer()">取消</button>
<button class="btn btn-primary" onclick="saveExceptionConfig()">确认保存</button>
</div>
</div>
<script>
/* 侧边栏展开/折叠交互 */
function toggleSubgroup(header){
@@ -226,6 +408,322 @@ function toggleSubgroup(header){
var sub=active.closest('.sidebar-subgroup');
if(sub)sub.classList.add('open');
})();
/* ===== 新增例外配置抽屉 ===== */
var hospitalData = ['泾河医院','庆阳医院','延安医院','兴隆园医院','宁夏宝石花医院'];
var templateInfo = {
'45岁以上男性标准套餐': { gender: '男', age: '45岁及以上' },
'35岁以下女性标准套餐': { gender: '女', age: '35岁以下' },
'35-45岁通用套餐': { gender: '通用', age: '35-45岁' },
'45岁及以上通用套餐': { gender: '通用', age: '45岁及以上' }
};
var templateData = {
'泾河医院': ['45岁以上男性标准套餐', '35岁以下女性标准套餐', '35-45岁通用套餐'],
'庆阳医院': ['35岁以下女性标准套餐', '45岁及以上通用套餐', '35-45岁通用套餐'],
'延安医院': ['35-45岁通用套餐', '45岁以上男性标准套餐'],
'兴隆园医院': ['35岁以下女性标准套餐', '35-45岁通用套餐'],
'宁夏宝石花医院': ['35-45岁通用套餐', '45岁以上男性标准套餐', '35岁以下女性标准套餐']
};
var selectedHospital = '';
var selectedTemplateName = '';
var projectData = [
{name:'经颅多普勒', code:'TCD-001'},
{name:'腹部彩超', code:'BUS-002'},
{name:'血常规', code:'BLD-003'},
{name:'心电图', code:'ECG-004'},
{name:'胸部X光', code:'XRY-005'},
{name:'肝功能', code:'LFT-006'},
{name:'肾功能', code:'RFT-007'},
{name:'空腹血糖', code:'GLU-008'},
{name:'血脂四项', code:'LIP-009'},
{name:'尿常规', code:'URI-010'},
{name:'胃镜', code:'GAS-011'},
{name:'肠镜', code:'COL-012'},
{name:'妇科B超', code:'GYN-013'},
{name:'TCT', code:'GYN-014'},
{name:'HPV', code:'GYN-015'},
{name:'Septin9', code:'SEP-016'},
{name:'CA724', code:'CA7-017'}
];
var projectTabKeys = ['required','optional','gyn-unmarried','gyn-married','cancer-septin9','cancer-ca724'];
var templateProjects = {
'45岁以上男性标准套餐': {
'required': ['经颅多普勒','血常规','心电图','胸部X光','肝功能','肾功能'],
'optional': ['腹部彩超','空腹血糖','血脂四项'],
'cancer-septin9': ['Septin9']
},
'35岁以下女性标准套餐': {
'required': ['血常规','尿常规','肝功能'],
'optional': ['腹部彩超'],
'gyn-unmarried': ['妇科B超'],
'gyn-married': ['TCT','HPV'],
'cancer-ca724': ['CA724']
},
'35-45岁通用套餐': {
'required': ['血常规','心电图','胸部X光','肝功能','肾功能'],
'optional': ['腹部彩超','空腹血糖','血脂四项'],
'cancer-ca724': ['CA724']
},
'45岁及以上通用套餐': {
'required': ['血常规','心电图','胸部X光','肝功能','肾功能'],
'optional': ['腹部彩超','空腹血糖','血脂四项']
}
};
/* 可搜索下拉通用组件 */
function createSearchSelect(data, opts){
var container = document.createElement('div');
container.className = 'search-select' + (opts.sm ? ' search-select--sm' : '');
var input = document.createElement('input');
input.type = 'text';
input.className = 'search-select__input';
input.placeholder = opts.placeholder || '请输入关键词搜索';
input.setAttribute('autocomplete', 'off');
var hidden = document.createElement('input');
hidden.type = 'hidden';
var clear = document.createElement('span');
clear.className = 'search-select__clear';
clear.textContent = '✕';
clear.title = '清除';
var dropdown = document.createElement('div');
dropdown.className = 'search-select__dropdown';
container.appendChild(input);
container.appendChild(hidden);
container.appendChild(clear);
container.appendChild(dropdown);
function getLabel(item){ return opts.getLabel ? opts.getLabel(item) : String(item); }
function renderOptions(kw){
dropdown.innerHTML = '';
var kwl = kw.trim().toLowerCase();
var has = false;
data.forEach(function(item, idx){
var label = getLabel(item);
if(!kwl || label.toLowerCase().indexOf(kwl) !== -1){
has = true;
(function(item, label){
var opt = document.createElement('div');
opt.className = 'search-select__option';
opt.textContent = label;
opt.onclick = function(){
hidden.value = idx;
input.value = label;
container.classList.add('has-value');
dropdown.classList.remove('show');
if(opts.onSelect) opts.onSelect(item);
};
dropdown.appendChild(opt);
})(item, label);
}
});
if(!has){
var empty = document.createElement('div');
empty.className = 'search-select__empty';
empty.textContent = '无匹配';
dropdown.appendChild(empty);
}
}
input.addEventListener('focus', function(){ renderOptions(this.value); dropdown.classList.add('show'); });
input.addEventListener('input', function(){ hidden.value=''; renderOptions(this.value); dropdown.classList.add('show'); });
clear.addEventListener('click', function(){
input.value=''; hidden.value=''; container.classList.remove('has-value'); dropdown.classList.remove('show');
if(opts.onSelect) opts.onSelect(null);
});
document.addEventListener('click', function(e){
if(!container.contains(e.target)){ dropdown.classList.remove('show'); }
});
return {
container: container,
getValue: function(){ return hidden.value; },
setValue: function(item){
if(item == null){ input.value=''; hidden.value=''; container.classList.remove('has-value'); return; }
var idx = data.indexOf(item);
if(idx === -1) return;
hidden.value = idx;
input.value = getLabel(item);
container.classList.add('has-value');
},
setData: function(newData){
data = newData;
input.value=''; hidden.value=''; container.classList.remove('has-value'); dropdown.classList.remove('show');
},
clear: function(){ input.value=''; hidden.value=''; container.classList.remove('has-value'); dropdown.classList.remove('show'); }
};
}
/* 体检医院搜索下拉 */
var hospitalSelect = createSearchSelect(hospitalData, {
placeholder: '请输入医院名称搜索',
getLabel: function(item){ return item; },
onSelect: function(item){
selectedHospital = item || '';
updateTemplateOptions();
}
});
document.getElementById('ex-hospital-select').appendChild(hospitalSelect.container);
/* 项目组合模板搜索下拉(根据所选医院过滤) */
var tplSelect = createSearchSelect([], {
placeholder: '请先选择医院',
getLabel: function(item){ return item; },
onSelect: function(item){
selectedTemplateName = item || '';
fillTemplateInfo();
}
});
document.getElementById('ex-tpl-select').appendChild(tplSelect.container);
/* 医院变化后刷新可选模板,并清空模板/性别/年龄/项目 */
function updateTemplateOptions(){
selectedTemplateName = '';
tplSelect.setData(selectedHospital ? (templateData[selectedHospital] || []) : []);
tplSelect.container.querySelector('.search-select__input').placeholder = selectedHospital ? '请选择项目组合模板' : '请先选择医院';
fillTemplateInfo();
}
/* 项目 tab 切换 */
function switchProjectTab(el){
document.querySelectorAll('#ex-tab-nav .tab-nav__item').forEach(function(t){ t.classList.remove('active'); });
el.classList.add('active');
var key = el.dataset.tab;
document.querySelectorAll('.tab-panel').forEach(function(p){ p.classList.remove('active'); });
document.getElementById('panel-' + key).classList.add('active');
}
/* 性别切换:男隐藏妇科 tab */
function onGenderChange(){
var gender = document.getElementById('ex-gender').value;
var showGyn = gender !== '男';
document.querySelectorAll('#ex-tab-nav .tab-nav__item[data-tab="gyn-unmarried"], #ex-tab-nav .tab-nav__item[data-tab="gyn-married"]').forEach(function(t){
t.style.display = showGyn ? '' : 'none';
});
var active = document.querySelector('#ex-tab-nav .tab-nav__item.active');
if(active && (active.dataset.tab === 'gyn-unmarried' || active.dataset.tab === 'gyn-married') && !showGyn){
switchProjectTab(document.querySelector('#ex-tab-nav .tab-nav__item[data-tab="required"]'));
}
}
/* 添加/删除项目行;presetName 存在时为模板带入项,置灰锁定 */
function addProjectRow(tabKey, presetName){
var tbody = document.getElementById('tbody-' + tabKey);
var locked = !!presetName;
var tr = document.createElement('tr');
var tdItem = document.createElement('td');
var tdCode = document.createElement('td');
var tdMark = document.createElement('td');
var tdOp = document.createElement('td');
var codeInput = document.createElement('input');
codeInput.className = 'row-input';
codeInput.readOnly = true;
codeInput.placeholder = '自动填充';
var ss = createSearchSelect(projectData, {
sm: true,
placeholder: '请选择体检项目',
getLabel: function(item){ return item.name + '' + item.code + ''; },
onSelect: function(item){ codeInput.value = item ? item.code : ''; }
});
var markSelect = document.createElement('select');
markSelect.className = 'row-select';
['一般项目','重点项目'].forEach(function(m){
var o = document.createElement('option');
o.textContent = m;
markSelect.appendChild(o);
});
var del = document.createElement('span');
del.className = 'link';
del.style.color = 'var(--danger)';
del.textContent = '删除';
del.onclick = function(){ tr.remove(); };
if(presetName){
var found = projectData.filter(function(p){ return p.name === presetName; })[0];
if(found){
ss.setValue(found);
codeInput.value = found.code;
}
}
if(locked){
ss.container.classList.add('is-disabled');
ss.container.querySelector('.search-select__input').disabled = true;
markSelect.disabled = true;
del.style.display = 'none';
}
tdItem.appendChild(ss.container);
tdCode.appendChild(codeInput);
tdMark.appendChild(markSelect);
tdOp.appendChild(del);
tr.appendChild(tdItem);
tr.appendChild(tdCode);
tr.appendChild(tdMark);
tr.appendChild(tdOp);
tbody.appendChild(tr);
}
/* 体检年度:默认当前年度 */
function initYearSelect(){
var year = new Date().getFullYear();
var sel = document.getElementById('ex-year');
sel.innerHTML = '';
[year, year - 1, year - 2].forEach(function(y){
var o = document.createElement('option');
o.value = y;
o.textContent = y;
sel.appendChild(o);
});
sel.value = year;
}
initYearSelect();
function openAddDrawer(){
resetAddDrawer();
document.getElementById('add-drawer').classList.add('open');
document.getElementById('add-overlay').classList.add('open');
}
function closeAddDrawer(){
document.getElementById('add-drawer').classList.remove('open');
document.getElementById('add-overlay').classList.remove('open');
}
function resetAddDrawer(){
selectedHospital = '';
selectedTemplateName = '';
hospitalSelect.clear();
document.getElementById('ex-unit').value = '';
document.getElementById('ex-valid').value = '有效';
updateTemplateOptions();
switchProjectTab(document.querySelector('#ex-tab-nav .tab-nav__item[data-tab="required"]'));
initYearSelect();
}
/* 选择项目组合模板后,自动回填性别/年龄范围及项目(不可修改) */
function fillTemplateInfo(){
var info = templateInfo[selectedTemplateName];
document.getElementById('ex-gender').value = info ? info.gender : '';
document.getElementById('ex-age').value = info ? info.age : '';
projectTabKeys.forEach(function(k){ document.getElementById('tbody-' + k).innerHTML = ''; });
var proj = templateProjects[selectedTemplateName] || {};
projectTabKeys.forEach(function(k){
(proj[k] || []).forEach(function(name){ addProjectRow(k, name); });
});
onGenderChange();
}
function saveExceptionConfig(){
if(!document.getElementById('ex-unit').value){ alert('请选择单位'); return; }
if(!selectedHospital){ alert('请选择医院'); return; }
if(!selectedTemplateName){ alert('请选择项目组合模板'); return; }
alert('已保存(原型演示)');
closeAddDrawer();
}
</script>
</body>
</html>
@@ -43,11 +43,13 @@
.sidebar-subgroup__body .sidebar-item{padding-left:36px;font-size:12px;}
/* 主内容 */
.main{margin-left:240px;margin-top:56px;padding:24px;min-height:calc(100vh - 56px);}
/* 医院TAB */
.hospital-tab{display:flex;align-items:center;gap:8px;margin-bottom:16px;background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:12px 24px;border:1px solid var(--border);}
.hospital-tab__item{padding:8px 18px;font-size:var(--font-sm);color:var(--text-secondary);cursor:pointer;transition:all .2s;user-select:none;white-space:nowrap;border-radius:var(--radius-sm);border:1px solid var(--border);}
.hospital-tab__item:hover{color:var(--primary);border-color:var(--primary);}
.hospital-tab__item.active{color:#fff;background:var(--primary);border-color:var(--primary);font-weight:500;}
/* 医院TAB切换 */
.hospital-tabs{display:flex;gap:0;margin-bottom:20px;border-bottom:2px solid var(--border);background:#fff;border-radius:var(--radius-md) var(--radius-md) 0 0;box-shadow:var(--shadow-sm);}
.hospital-tab{padding:14px 32px;font-size:var(--font-base);color:var(--text-secondary);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-2px;transition:all .2s;font-weight:500;white-space:nowrap;}
.hospital-tab:hover{color:var(--primary);}
.hospital-tab.active{color:var(--primary);border-bottom-color:var(--primary);font-weight:600;}
.tab-pane{display:none;}
.tab-pane.active{display:block;}
/* 媒体预览图标 */
.media-icon{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:var(--radius-sm);cursor:pointer;transition:all .2s;}
.media-icon--active{background:var(--primary-light);color:var(--primary);}
@@ -84,6 +86,65 @@
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;}
.page-btn:hover,.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
/* 抽屉弹窗 */
.drawer-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0);z-index:999;pointer-events:none;transition:background .3s;}
.drawer-overlay.open{background:rgba(0,0,0,0.45);pointer-events:auto;}
.drawer{position:fixed;top:0;right:-480px;bottom:0;width:480px;background:#fff;box-shadow:-2px 0 8px rgba(0,0,0,0.15);z-index:1000;transition:right .3s;display:flex;flex-direction:column;}
.drawer.open{right:0;}
.drawer--wide{width:720px;right:-720px;}
.drawer__header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px;border-bottom:1px solid var(--border);flex-shrink:0;}
.drawer__title{font-size:var(--font-lg);font-weight:600;}
.drawer__close{width:32px;height:32px;border-radius:50%;border:none;background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-secondary);font-size:18px;}
.drawer__close:hover{background:#F5F5F5;}
.drawer__body{flex:1;overflow-y:auto;padding:24px;}
.drawer__footer{display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid var(--border);flex-shrink:0;}
/* 表单 */
.form-item{margin-bottom:20px;}
.form-label{font-size:var(--font-sm);color:var(--text-secondary);margin-bottom:8px;display:flex;align-items:center;gap:4px;font-weight:500;}
.form-label .required{color:var(--danger);}
.form-input{width:100%;height:40px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;}
.form-input:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
.form-select{width:100%;height:40px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 12px center;appearance:none;cursor:pointer;}
.form-select:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
/* 可搜索下拉 */
.search-select{position:relative;}
.search-select__input{width:100%;height:40px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 48px 0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 12px center;}
.search-select__input:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
.search-select__clear{position:absolute;top:50%;right:28px;transform:translateY(-50%);width:18px;height:18px;border-radius:50%;background:#BFBFBF;color:#fff;display:none;align-items:center;justify-content:center;cursor:pointer;font-size:12px;line-height:1;z-index:2;}
.search-select__clear:hover{background:#999;}
.search-select.has-value:hover .search-select__clear{display:flex;}
.search-select__dropdown{position:absolute;top:44px;left:0;right:0;background:#fff;border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:0 4px 12px rgba(0,0,0,0.1);max-height:220px;overflow-y:auto;z-index:10;display:none;}
.search-select__dropdown.show{display:block;}
.search-select__option{padding:10px 12px;font-size:var(--font-sm);cursor:pointer;transition:background .15s;color:var(--text-primary);}
.search-select__option:hover,.search-select__option.active{background:var(--primary-light);color:var(--primary);}
.search-select__empty{padding:10px 12px;font-size:var(--font-sm);color:var(--text-placeholder);text-align:center;}
/* 中间弹窗 */
.modal-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.45);z-index:1100;display:none;align-items:center;justify-content:center;}
.modal-overlay.open{display:flex;}
.modal{background:#fff;border-radius:var(--radius-lg);box-shadow:0 4px 16px rgba(0,0,0,0.15);width:480px;max-width:92vw;z-index:1101;}
.modal__header{display:flex;align-items:center;justify-content:space-between;padding:18px 24px;border-bottom:1px solid var(--border);}
.modal__title{font-size:var(--font-lg);font-weight:600;}
.modal__close{width:32px;height:32px;border-radius:50%;border:none;background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-secondary);font-size:18px;}
.modal__close:hover{background:#F5F5F5;}
.modal__body{padding:24px;}
.modal__footer{display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid var(--border);}
.form-input:disabled{background:#F5F5F5;color:var(--text-secondary);cursor:not-allowed;}
/* 上传 */
.upload-box{display:flex;align-items:center;justify-content:center;gap:6px;height:40px;border:1px dashed var(--border);border-radius:var(--radius-sm);cursor:pointer;color:var(--text-secondary);font-size:var(--font-sm);transition:all .2s;background:#FAFAFA;}
.upload-box:hover{border-color:var(--primary);color:var(--primary);}
.upload-box .upload-file{display:none;}
/* 富文本 */
.editor-toolbar{display:flex;gap:4px;padding:8px 12px;border:1px solid var(--border);border-bottom:none;border-radius:var(--radius-sm) var(--radius-sm) 0 0;background:#FAFAFA;flex-wrap:wrap;align-items:center;}
.toolbar-btn{padding:4px 8px;border:none;background:transparent;cursor:pointer;border-radius:var(--radius-sm);font-size:var(--font-sm);color:var(--text-secondary);display:inline-flex;align-items:center;justify-content:center;}
.toolbar-btn:hover{background:#E8E8E8;color:var(--text-primary);}
.toolbar-divider{width:1px;background:var(--border);margin:2px 4px;align-self:stretch;}
.toolbar-select{height:26px;border:1px solid var(--border);border-radius:var(--radius-sm);font-size:var(--font-xs);color:var(--text-secondary);background:#fff;cursor:pointer;outline:none;}
.toolbar-color{width:26px;height:26px;border:1px solid var(--border);border-radius:var(--radius-sm);cursor:pointer;padding:0;background:#fff;}
.editor-body{width:100%;min-height:160px;border:1px solid var(--border);border-radius:0 0 var(--radius-sm) var(--radius-sm);padding:14px;font-size:var(--font-sm);outline:none;line-height:1.8;color:var(--text-primary);}
.editor-body:focus{border-color:var(--primary);}
.editor-body:empty:before{content:attr(data-placeholder);color:var(--text-placeholder);}
.editor-footer{display:flex;align-items:center;justify-content:space-between;margin-top:8px;}
.editor-footer__hint{font-size:var(--font-xs);color:#999;}
</style>
</head>
<body>
@@ -157,82 +218,474 @@
<!-- 主内容 -->
<main class="main">
<!-- 医院切换TAB -->
<div class="hospital-tab">
<div class="hospital-tab__item active" onclick="switchHospital(this)">泾河医院</div>
<div class="hospital-tab__item" onclick="switchHospital(this)">庆阳医院</div>
<div class="hospital-tab__item" onclick="switchHospital(this)">延安医院</div>
<div class="hospital-tab__item" onclick="switchHospital(this)">兴隆园医院</div>
<div class="hospital-tab__item" onclick="switchHospital(this)">宁夏宝石花医院</div>
<!-- 医院TAB切换 -->
<div class="hospital-tabs">
<div class="hospital-tab active" onclick="switchHospital('jinghe', this)">泾河医院</div>
<div class="hospital-tab" onclick="switchHospital('qingyang', this)">庆阳医院</div>
<div class="hospital-tab" onclick="switchHospital('yanan', this)">延安医院</div>
<div class="hospital-tab" onclick="switchHospital('xinglongyuan', this)">兴隆园医院</div>
<div class="hospital-tab" onclick="switchHospital('ningxia', this)">宁夏宝石花医院</div>
</div>
<!-- 筛选栏 -->
<div class="filter-bar">
<div class="filter-item">
<label>项目名称:</label>
<input class="filter-input" type="text" placeholder="请输入" style="min-width:160px;">
<!-- 泾河医院 -->
<div class="tab-pane active" id="pane-jinghe">
<div class="filter-bar">
<div class="filter-item">
<label>项目名称:</label>
<input class="filter-input" type="text" placeholder="请输入" style="min-width:160px;">
</div>
<div class="filter-item">
<label>检查分类:</label>
<select class="filter-select">
<option>请选择</option>
</select>
</div>
<div class="filter-item">
<label>项目类别:</label>
<select class="filter-select">
<option>请选择</option>
</select>
</div>
<div class="filter-item">
<label>项目编号:</label>
<input class="filter-input" type="text" placeholder="请输入" style="min-width:120px;">
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
</div>
<div class="filter-item">
<label>检查分类:</label>
<select class="filter-select">
<option>请选择</option>
</select>
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-primary" onclick="openAddDrawer()">+ 新增</button>
<button class="btn btn-default">批量删除</button>
<button class="btn btn-default" onclick="openMutualDrawer()">互斥项目配置</button>
</div>
<div class="filter-item">
<label>项目类别:</label>
<select class="filter-select">
<option>请选择</option>
</select>
<div class="table-card">
<div class="table-card__header">
<div class="table-card__title">泾河医院体检项目费用</div>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<th>序号</th><th>项目名称</th><th>项目编号</th><th>检查分类</th><th>项目类别</th><th>项目图片</th><th>默认费用(元)</th><th>项目音频</th><th>项目视频</th><th>操作</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>经颅多普勒</td><td>TCD-001</td><td>常规检查</td><td>功能检查项目</td><td><span class="media-icon media-icon--empty" title="暂无图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>260.00</td><td><span class="media-icon media-icon--empty" title="暂无音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--empty" title="暂无视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">更新已生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>2</td><td>腹部彩超</td><td>BUS-002</td><td>常规检查</td><td>影像检查项目</td><td><span class="media-icon media-icon--active" title="查看图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>180.00</td><td><span class="media-icon media-icon--active" title="播放音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--active" title="播放视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">更新已生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>3</td><td>血常规</td><td>BLD-003</td><td>常规检查</td><td>检验项目</td><td><span class="media-icon media-icon--empty" title="暂无图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>35.00</td><td><span class="media-icon media-icon--empty" title="暂无音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--active" title="播放视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">更新已生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>共 243 条</span>
<button class="page-btn active">1</button>
<span>每页</span>
<select class="filter-select" style="min-width:70px;height:32px;"><option>10条</option><option>50条</option></select>
</div>
</div>
<div class="filter-item">
<label>项目编号:</label>
<input class="filter-input" type="text" placeholder="请输入" style="min-width:120px;">
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
</div>
<!-- 操作按钮 -->
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-primary">+ 新增</button>
<button class="btn btn-default">批量删除</button>
<button class="btn btn-default">互斥项目配置</button>
<!-- 庆阳医院 -->
<div class="tab-pane" id="pane-qingyang">
<div class="filter-bar">
<div class="filter-item">
<label>项目名称:</label>
<input class="filter-input" type="text" placeholder="请输入" style="min-width:160px;">
</div>
<div class="filter-item">
<label>检查分类:</label>
<select class="filter-select">
<option>请选择</option>
</select>
</div>
<div class="filter-item">
<label>项目类别:</label>
<select class="filter-select">
<option>请选择</option>
</select>
</div>
<div class="filter-item">
<label>项目编号:</label>
<input class="filter-input" type="text" placeholder="请输入" style="min-width:120px;">
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
</div>
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-primary" onclick="openAddDrawer()">+ 新增</button>
<button class="btn btn-default">批量删除</button>
<button class="btn btn-default" onclick="openMutualDrawer()">互斥项目配置</button>
</div>
<div class="table-card">
<div class="table-card__header">
<div class="table-card__title">庆阳医院体检项目费用</div>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<th>序号</th><th>项目名称</th><th>项目编号</th><th>检查分类</th><th>项目类别</th><th>项目图片</th><th>默认费用(元)</th><th>项目音频</th><th>项目视频</th><th>操作</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>经颅多普勒</td><td>TCD-001</td><td>常规检查</td><td>功能检查项目</td><td><span class="media-icon media-icon--empty" title="暂无图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>260.00</td><td><span class="media-icon media-icon--empty" title="暂无音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--empty" title="暂无视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">更新已生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>2</td><td>腹部彩超</td><td>BUS-002</td><td>常规检查</td><td>影像检查项目</td><td><span class="media-icon media-icon--active" title="查看图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>180.00</td><td><span class="media-icon media-icon--active" title="播放音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--active" title="播放视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">更新已生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>3</td><td>血常规</td><td>BLD-003</td><td>常规检查</td><td>检验项目</td><td><span class="media-icon media-icon--empty" title="暂无图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>35.00</td><td><span class="media-icon media-icon--empty" title="暂无音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--active" title="播放视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">更新已生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>共 186 条</span>
<button class="page-btn active">1</button>
<span>每页</span>
<select class="filter-select" style="min-width:70px;height:32px;"><option>10条</option><option>50条</option></select>
</div>
</div>
</div>
<!-- 数据表格 -->
<div class="table-card">
<div class="table-card__header">
<div class="table-card__title">医院体检项目费用</div>
<!-- 延安医院 -->
<div class="tab-pane" id="pane-yanan">
<div class="filter-bar">
<div class="filter-item">
<label>项目名称:</label>
<input class="filter-input" type="text" placeholder="请输入" style="min-width:160px;">
</div>
<div class="filter-item">
<label>检查分类:</label>
<select class="filter-select">
<option>请选择</option>
</select>
</div>
<div class="filter-item">
<label>项目类别:</label>
<select class="filter-select">
<option>请选择</option>
</select>
</div>
<div class="filter-item">
<label>项目编号:</label>
<input class="filter-input" type="text" placeholder="请输入" style="min-width:120px;">
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<th>序号</th><th>项目名称</th><th>项目编号</th><th>检查分类</th><th>项目类别</th><th>项目图片</th><th>默认费用(元)</th><th>项目音频</th><th>项目视频</th><th>操作</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>经颅多普勒</td><td>TCD-001</td><td>常规检查</td><td>功能检查项目</td><td><span class="media-icon media-icon--empty" title="暂无图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>260.00</td><td><span class="media-icon media-icon--empty" title="暂无音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--empty" title="暂无视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>2</td><td>腹部彩超</td><td>BUS-002</td><td>常规检查</td><td>影像检查项目</td><td><span class="media-icon media-icon--active" title="查看图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>180.00</td><td><span class="media-icon media-icon--active" title="播放音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--active" title="播放视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">更新已生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>3</td><td>血常规</td><td>BLD-003</td><td>常规检查</td><td>检验项目</td><td><span class="media-icon media-icon--empty" title="暂无图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>35.00</td><td><span class="media-icon media-icon--empty" title="暂无音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--active" title="播放视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
</tbody>
</table>
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-primary" onclick="openAddDrawer()">+ 新增</button>
<button class="btn btn-default">批量删除</button>
<button class="btn btn-default" onclick="openMutualDrawer()">互斥项目配置</button>
</div>
<div class="pagination">
<span>共 243 条</span>
<button class="page-btn active">1</button>
<span>每页</span>
<select class="filter-select" style="min-width:70px;height:32px;"><option>10条</option><option>50条</option></select>
<div class="table-card">
<div class="table-card__header">
<div class="table-card__title">延安医院体检项目费用</div>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<th>序号</th><th>项目名称</th><th>项目编号</th><th>检查分类</th><th>项目类别</th><th>项目图片</th><th>默认费用(元)</th><th>项目音频</th><th>项目视频</th><th>操作</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>经颅多普勒</td><td>TCD-001</td><td>常规检查</td><td>功能检查项目</td><td><span class="media-icon media-icon--empty" title="暂无图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>260.00</td><td><span class="media-icon media-icon--empty" title="暂无音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--empty" title="暂无视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">更新已生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>2</td><td>腹部彩超</td><td>BUS-002</td><td>常规检查</td><td>影像检查项目</td><td><span class="media-icon media-icon--active" title="查看图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>180.00</td><td><span class="media-icon media-icon--active" title="播放音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--active" title="播放视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">更新已生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>3</td><td>血常规</td><td>BLD-003</td><td>常规检查</td><td>检验项目</td><td><span class="media-icon media-icon--empty" title="暂无图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>35.00</td><td><span class="media-icon media-icon--empty" title="暂无音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--active" title="播放视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">更新已生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>共 157 条</span>
<button class="page-btn active">1</button>
<span>每页</span>
<select class="filter-select" style="min-width:70px;height:32px;"><option>10条</option><option>50条</option></select>
</div>
</div>
</div>
<!-- 兴隆园医院 -->
<div class="tab-pane" id="pane-xinglongyuan">
<div class="filter-bar">
<div class="filter-item">
<label>项目名称:</label>
<input class="filter-input" type="text" placeholder="请输入" style="min-width:160px;">
</div>
<div class="filter-item">
<label>检查分类:</label>
<select class="filter-select">
<option>请选择</option>
</select>
</div>
<div class="filter-item">
<label>项目类别:</label>
<select class="filter-select">
<option>请选择</option>
</select>
</div>
<div class="filter-item">
<label>项目编号:</label>
<input class="filter-input" type="text" placeholder="请输入" style="min-width:120px;">
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
</div>
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-primary" onclick="openAddDrawer()">+ 新增</button>
<button class="btn btn-default">批量删除</button>
<button class="btn btn-default" onclick="openMutualDrawer()">互斥项目配置</button>
</div>
<div class="table-card">
<div class="table-card__header">
<div class="table-card__title">兴隆园医院体检项目费用</div>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<th>序号</th><th>项目名称</th><th>项目编号</th><th>检查分类</th><th>项目类别</th><th>项目图片</th><th>默认费用(元)</th><th>项目音频</th><th>项目视频</th><th>操作</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>经颅多普勒</td><td>TCD-001</td><td>常规检查</td><td>功能检查项目</td><td><span class="media-icon media-icon--empty" title="暂无图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>260.00</td><td><span class="media-icon media-icon--empty" title="暂无音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--empty" title="暂无视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">更新已生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>2</td><td>腹部彩超</td><td>BUS-002</td><td>常规检查</td><td>影像检查项目</td><td><span class="media-icon media-icon--active" title="查看图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>180.00</td><td><span class="media-icon media-icon--active" title="播放音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--active" title="播放视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">更新已生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>3</td><td>血常规</td><td>BLD-003</td><td>常规检查</td><td>检验项目</td><td><span class="media-icon media-icon--empty" title="暂无图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>35.00</td><td><span class="media-icon media-icon--empty" title="暂无音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--active" title="播放视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">更新已生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>共 212 条</span>
<button class="page-btn active">1</button>
<span>每页</span>
<select class="filter-select" style="min-width:70px;height:32px;"><option>10条</option><option>50条</option></select>
</div>
</div>
</div>
<!-- 宁夏宝石花医院 -->
<div class="tab-pane" id="pane-ningxia">
<div class="filter-bar">
<div class="filter-item">
<label>项目名称:</label>
<input class="filter-input" type="text" placeholder="请输入" style="min-width:160px;">
</div>
<div class="filter-item">
<label>检查分类:</label>
<select class="filter-select">
<option>请选择</option>
</select>
</div>
<div class="filter-item">
<label>项目类别:</label>
<select class="filter-select">
<option>请选择</option>
</select>
</div>
<div class="filter-item">
<label>项目编号:</label>
<input class="filter-input" type="text" placeholder="请输入" style="min-width:120px;">
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
</div>
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-primary" onclick="openAddDrawer()">+ 新增</button>
<button class="btn btn-default">批量删除</button>
<button class="btn btn-default" onclick="openMutualDrawer()">互斥项目配置</button>
</div>
<div class="table-card">
<div class="table-card__header">
<div class="table-card__title">宁夏宝石花医院体检项目费用</div>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<th>序号</th><th>项目名称</th><th>项目编号</th><th>检查分类</th><th>项目类别</th><th>项目图片</th><th>默认费用(元)</th><th>项目音频</th><th>项目视频</th><th>操作</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>经颅多普勒</td><td>TCD-001</td><td>常规检查</td><td>功能检查项目</td><td><span class="media-icon media-icon--empty" title="暂无图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>260.00</td><td><span class="media-icon media-icon--empty" title="暂无音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--empty" title="暂无视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">更新已生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>2</td><td>腹部彩超</td><td>BUS-002</td><td>常规检查</td><td>影像检查项目</td><td><span class="media-icon media-icon--active" title="查看图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>180.00</td><td><span class="media-icon media-icon--active" title="播放音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--active" title="播放视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">更新已生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
<tr><td>3</td><td>血常规</td><td>BLD-003</td><td>常规检查</td><td>检验项目</td><td><span class="media-icon media-icon--empty" title="暂无图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>35.00</td><td><span class="media-icon media-icon--empty" title="暂无音频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 2v9M8 2L5 5H3v4h2l3 3V2z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/><path d="M11 5.5a3 3 0 010 5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg></span></td><td><span class="media-icon media-icon--active" title="播放视频"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="4" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.3"/><path d="M11 7l3-2v6l-3-2V7z" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td><span class="link">更新已生成费用</span> <span class="link" style="margin-left:8px;">编辑</span> <span class="link" style="margin-left:8px;">详情</span> <span class="link" style="margin-left:8px;color:var(--danger);">删除</span></td></tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>共 98 条</span>
<button class="page-btn active">1</button>
<span>每页</span>
<select class="filter-select" style="min-width:70px;height:32px;"><option>10条</option><option>50条</option></select>
</div>
</div>
</div>
</main>
<!-- 新增医院体检项目费用抽屉 -->
<div class="drawer-overlay" id="add-overlay" onclick="closeAddDrawer()"></div>
<div class="drawer" id="add-drawer">
<div class="drawer__header">
<div class="drawer__title" id="add-drawer-title">泾河医院 - 新增体检项目费用</div>
<button class="drawer__close" onclick="closeAddDrawer()"></button>
</div>
<div class="drawer__body">
<div class="form-item">
<div class="form-label"><span class="required">*</span> 选择体检项目</div>
<div class="search-select" id="item-search-select">
<input type="text" class="search-select__input" id="item-search-input" placeholder="请输入项目名称搜索" autocomplete="off">
<input type="hidden" id="item-search-value">
<span class="search-select__clear" id="item-search-clear" title="清除" onclick="clearItemSelection()"></span>
<div class="search-select__dropdown" id="item-search-dropdown"></div>
</div>
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 检查分类</div>
<select class="form-select" id="item-category">
<option>请选择</option>
<option>常规检查</option>
<option>特殊检查</option>
</select>
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 项目类别</div>
<select class="form-select" id="item-type">
<option>请选择</option>
<option>功能检查项目</option>
<option>影像检查项目</option>
<option>检验项目</option>
<option>内镜检查项目</option>
</select>
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 默认费用(元)</div>
<input class="form-input" type="number" min="0" id="item-fee" placeholder="请输入默认费用">
</div>
<div class="form-item">
<div class="form-label">项目图片</div>
<label class="upload-box">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 11V3M5 6l3-3 3 3" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 11v1a1 1 0 001 1h8a1 1 0 001-1v-1" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
上传图片
<input type="file" class="upload-file">
</label>
</div>
<div class="form-item">
<div class="form-label">项目音频</div>
<label class="upload-box">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 11V3M5 6l3-3 3 3" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 11v1a1 1 0 001 1h8a1 1 0 001-1v-1" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
上传音频
<input type="file" class="upload-file">
</label>
</div>
<div class="form-item">
<div class="form-label">项目视频</div>
<label class="upload-box">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M8 11V3M5 6l3-3 3 3" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/><path d="M3 11v1a1 1 0 001 1h8a1 1 0 001-1v-1" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
上传视频
<input type="file" class="upload-file">
</label>
</div>
<div class="form-item">
<div class="form-label">描述</div>
<div class="editor-toolbar">
<button class="toolbar-btn" title="加粗" onmousedown="event.preventDefault()" onclick="execCmd('bold')"><strong>B</strong></button>
<button class="toolbar-btn" title="斜体" onmousedown="event.preventDefault()" onclick="execCmd('italic')"><em>I</em></button>
<button class="toolbar-btn" title="下划线" onmousedown="event.preventDefault()" onclick="execCmd('underline')"><u>U</u></button>
<div class="toolbar-divider"></div>
<button class="toolbar-btn" onmousedown="event.preventDefault()" onclick="execCmd('insertOrderedList')">有序列表</button>
<button class="toolbar-btn" onmousedown="event.preventDefault()" onclick="execCmd('insertUnorderedList')">无序列表</button>
<div class="toolbar-divider"></div>
<select class="toolbar-select" onmousedown="event.preventDefault()" onchange="execCmd('fontSize', this.value)">
<option value="">字号</option>
<option value="1"></option>
<option value="2">较小</option>
<option value="3">正常</option>
<option value="4">较大</option>
<option value="5"></option>
</select>
<input type="color" class="toolbar-color" title="文字颜色" value="#333333" onchange="execCmd('foreColor', this.value)">
</div>
<div class="editor-body" id="desc-editor" contenteditable="true" data-placeholder="请输入项目描述"></div>
<div class="editor-footer">
<span class="editor-footer__hint">支持富文本编辑</span>
</div>
</div>
</div>
<div class="drawer__footer">
<button class="btn btn-default" onclick="closeAddDrawer()">取消</button>
<button class="btn btn-primary" onclick="saveAddItem()">确认保存</button>
</div>
</div>
<!-- 互斥项目配置抽屉 -->
<div class="drawer-overlay" id="mutual-overlay" onclick="closeMutualDrawer()"></div>
<div class="drawer drawer--wide" id="mutual-drawer">
<div class="drawer__header">
<div class="drawer__title" id="mutual-drawer-title">泾河医院 - 互斥项目配置</div>
<button class="drawer__close" onclick="closeMutualDrawer()"></button>
</div>
<div class="drawer__body">
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-primary" onclick="openMutualAddModal()">+ 新增</button>
<button class="btn btn-danger" onclick="batchDeleteMutual()">批量删除</button>
</div>
<div class="table-card">
<div class="table-card__content">
<table>
<thead>
<tr>
<th style="width:40px;"><input type="checkbox" id="mutual-check-all" onclick="toggleMutualCheckAll(this)"></th>
<th>序号</th><th>体检项目</th><th>互斥项目</th><th>操作</th>
</tr>
</thead>
<tbody id="mutual-tbody"></tbody>
</table>
</div>
</div>
</div>
</div>
<!-- 新增互斥项目弹窗 -->
<div class="modal-overlay" id="mutual-modal-overlay" onclick="if(event.target===this)closeMutualAddModal()">
<div class="modal">
<div class="modal__header">
<div class="modal__title">新增互斥项目</div>
<button class="modal__close" onclick="closeMutualAddModal()"></button>
</div>
<div class="modal__body">
<div class="form-item">
<div class="form-label">体检医院</div>
<input class="form-input" id="mutual-hospital" disabled>
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 体检项目</div>
<div class="search-select" id="mutual-item-select">
<input type="text" class="search-select__input" id="mutual-item-input" placeholder="请输入项目名称搜索" autocomplete="off">
<input type="hidden" id="mutual-item-value">
<span class="search-select__clear" id="mutual-item-clear" title="清除"></span>
<div class="search-select__dropdown" id="mutual-item-dropdown"></div>
</div>
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 互斥项目</div>
<div class="search-select" id="mutual-exclude-select">
<input type="text" class="search-select__input" id="mutual-exclude-input" placeholder="请输入项目名称搜索" autocomplete="off">
<input type="hidden" id="mutual-exclude-value">
<span class="search-select__clear" id="mutual-exclude-clear" title="清除"></span>
<div class="search-select__dropdown" id="mutual-exclude-dropdown"></div>
</div>
</div>
</div>
<div class="modal__footer">
<button class="btn btn-default" onclick="closeMutualAddModal()">取消</button>
<button class="btn btn-primary" onclick="saveMutualItem()">确认保存</button>
</div>
</div>
</div>
<script>
/* 医院TAB切换 */
function switchHospital(el){
var items=el.parentElement.querySelectorAll('.hospital-tab__item');
items.forEach(function(item){item.classList.remove('active');});
function switchHospital(type, el){
document.querySelectorAll('.hospital-tab').forEach(function(t){ t.classList.remove('active'); });
document.querySelectorAll('.tab-pane').forEach(function(p){ p.classList.remove('active'); });
el.classList.add('active');
document.getElementById('pane-' + type).classList.add('active');
}
/* 侧边栏展开/折叠交互 */
function toggleSubgroup(header){
@@ -245,6 +698,281 @@ function toggleSubgroup(header){
var sub=active.closest('.sidebar-subgroup');
if(sub)sub.classList.add('open');
})();
/* ===== 新增医院体检项目费用抽屉 ===== */
var itemData = [
{name:'经颅多普勒', code:'TCD-001', category:'常规检查', type:'功能检查项目', fee:'260.00'},
{name:'腹部彩超', code:'BUS-002', category:'常规检查', type:'影像检查项目', fee:'180.00'},
{name:'血常规', code:'BLD-003', category:'常规检查', type:'检验项目', fee:'35.00'},
{name:'心电图', code:'ECG-004', category:'常规检查', type:'功能检查项目', fee:'25.00'},
{name:'胸部X光', code:'XRY-005', category:'常规检查', type:'影像检查项目', fee:'120.00'},
{name:'肝功能', code:'LFT-006', category:'常规检查', type:'检验项目', fee:'80.00'},
{name:'肾功能', code:'RFT-007', category:'常规检查', type:'检验项目', fee:'60.00'},
{name:'空腹血糖', code:'GLU-008', category:'常规检查', type:'检验项目', fee:'10.00'},
{name:'血脂四项', code:'LIP-009', category:'常规检查', type:'检验项目', fee:'90.00'},
{name:'尿常规', code:'URI-010', category:'常规检查', type:'检验项目', fee:'15.00'},
{name:'胃镜', code:'GAS-011', category:'特殊检查', type:'内镜检查项目', fee:'350.00'},
{name:'肠镜', code:'COL-012', category:'特殊检查', type:'内镜检查项目', fee:'380.00'}
];
function openAddDrawer(){
var activeTab = document.querySelector('.hospital-tab.active');
var hospitalName = activeTab ? activeTab.textContent.trim() : '医院';
document.getElementById('add-drawer-title').textContent = hospitalName + ' - 新增体检项目费用';
document.getElementById('add-drawer').classList.add('open');
document.getElementById('add-overlay').classList.add('open');
}
function closeAddDrawer(){
document.getElementById('add-drawer').classList.remove('open');
document.getElementById('add-overlay').classList.remove('open');
}
function saveAddItem(){
alert('已保存(原型演示)');
closeAddDrawer();
}
/* 体检项目可搜索下拉 */
(function(){
var input = document.getElementById('item-search-input');
var dropdown = document.getElementById('item-search-dropdown');
var hidden = document.getElementById('item-search-value');
function renderOptions(keyword){
dropdown.innerHTML = '';
var kw = keyword.trim().toLowerCase();
var has = false;
itemData.forEach(function(item, idx){
var label = item.name + '' + item.code + '';
if(!kw || label.toLowerCase().indexOf(kw) !== -1){
has = true;
var opt = document.createElement('div');
opt.className = 'search-select__option';
if(hidden.value === String(idx)) opt.classList.add('active');
opt.textContent = label;
opt.dataset.index = idx;
opt.onclick = function(){
hidden.value = idx;
input.value = label;
document.getElementById('item-search-select').classList.add('has-value');
dropdown.classList.remove('show');
};
dropdown.appendChild(opt);
}
});
if(!has){
var empty = document.createElement('div');
empty.className = 'search-select__empty';
empty.textContent = '无匹配项目';
dropdown.appendChild(empty);
}
}
input.addEventListener('focus', function(){
renderOptions(this.value);
dropdown.classList.add('show');
});
input.addEventListener('input', function(){
hidden.value = '';
renderOptions(this.value);
dropdown.classList.add('show');
});
document.addEventListener('click', function(e){
if(!e.target.closest('#item-search-select')){
dropdown.classList.remove('show');
}
});
})();
/* 清除已选体检项目 */
function clearItemSelection(){
document.getElementById('item-search-input').value = '';
document.getElementById('item-search-value').value = '';
document.getElementById('item-search-select').classList.remove('has-value');
document.getElementById('item-search-dropdown').classList.remove('show');
}
/* 富文本编辑 */
function execCmd(cmd, value){
var editor = document.getElementById('desc-editor');
editor.focus();
document.execCommand(cmd, false, value || null);
}
/* ===== 互斥项目配置 ===== */
var mutualData = [
{item:'经颅多普勒(TCD-001', exclude:'腹部彩超(BUS-002'},
{item:'胃镜(GAS-011', exclude:'肠镜(COL-012'}
];
/* 可搜索下拉通用组件 */
function initSearchSelect(cfg){
var container = document.getElementById(cfg.containerId);
var input = document.getElementById(cfg.inputId);
var hidden = document.getElementById(cfg.hiddenId);
var dropdown = document.getElementById(cfg.dropdownId);
var clearBtn = document.getElementById(cfg.clearId);
function renderOptions(keyword){
dropdown.innerHTML = '';
var kw = keyword.trim().toLowerCase();
var has = false;
cfg.data.forEach(function(item, idx){
var label = cfg.getLabel(item);
if(!kw || label.toLowerCase().indexOf(kw) !== -1){
has = true;
var opt = document.createElement('div');
opt.className = 'search-select__option';
if(hidden.value === String(idx)) opt.classList.add('active');
opt.textContent = label;
opt.dataset.index = idx;
opt.onclick = function(){
hidden.value = idx;
input.value = label;
container.classList.add('has-value');
dropdown.classList.remove('show');
};
dropdown.appendChild(opt);
}
});
if(!has){
var empty = document.createElement('div');
empty.className = 'search-select__empty';
empty.textContent = '无匹配项目';
dropdown.appendChild(empty);
}
}
input.addEventListener('focus', function(){
renderOptions(this.value);
dropdown.classList.add('show');
});
input.addEventListener('input', function(){
hidden.value = '';
renderOptions(this.value);
dropdown.classList.add('show');
});
document.addEventListener('click', function(e){
if(!e.target.closest('#' + cfg.containerId)){
dropdown.classList.remove('show');
}
});
function clear(){
input.value = '';
hidden.value = '';
container.classList.remove('has-value');
dropdown.classList.remove('show');
}
if(clearBtn){
clearBtn.addEventListener('click', clear);
}
return {
clear: clear,
getValue: function(){ return hidden.value; }
};
}
var mutualItemSelect = initSearchSelect({
containerId:'mutual-item-select',
inputId:'mutual-item-input',
hiddenId:'mutual-item-value',
clearId:'mutual-item-clear',
dropdownId:'mutual-item-dropdown',
data:itemData,
getLabel:function(item){ return item.name + '' + item.code + ''; }
});
var mutualExcludeSelect = initSearchSelect({
containerId:'mutual-exclude-select',
inputId:'mutual-exclude-input',
hiddenId:'mutual-exclude-value',
clearId:'mutual-exclude-clear',
dropdownId:'mutual-exclude-dropdown',
data:itemData,
getLabel:function(item){ return item.name + '' + item.code + ''; }
});
/* 渲染互斥项目列表 */
function renderMutualTable(){
var tbody = document.getElementById('mutual-tbody');
tbody.innerHTML = '';
mutualData.forEach(function(row, i){
var tr = document.createElement('tr');
tr.innerHTML =
'<td><input type="checkbox" class="mutual-row-check" data-index="' + i + '" onchange="updateMutualCheckAll()"></td>' +
'<td>' + (i + 1) + '</td>' +
'<td>' + row.item + '</td>' +
'<td>' + row.exclude + '</td>' +
'<td><span class="link" style="color:var(--danger);" onclick="deleteMutualRow(' + i + ')">删除</span></td>';
tbody.appendChild(tr);
});
document.getElementById('mutual-check-all').checked = false;
}
/* 打开互斥项目配置抽屉 */
function openMutualDrawer(){
var activeTab = document.querySelector('.hospital-tab.active');
var hospitalName = activeTab ? activeTab.textContent.trim() : '医院';
document.getElementById('mutual-drawer-title').textContent = hospitalName + ' - 互斥项目配置';
renderMutualTable();
document.getElementById('mutual-drawer').classList.add('open');
document.getElementById('mutual-overlay').classList.add('open');
}
function closeMutualDrawer(){
document.getElementById('mutual-drawer').classList.remove('open');
document.getElementById('mutual-overlay').classList.remove('open');
}
/* 新增互斥项目弹窗 */
function openMutualAddModal(){
var activeTab = document.querySelector('.hospital-tab.active');
document.getElementById('mutual-hospital').value = activeTab ? activeTab.textContent.trim() : '';
mutualItemSelect.clear();
mutualExcludeSelect.clear();
document.getElementById('mutual-modal-overlay').classList.add('open');
}
function closeMutualAddModal(){
document.getElementById('mutual-modal-overlay').classList.remove('open');
}
function saveMutualItem(){
var itemIdx = mutualItemSelect.getValue();
var excludeIdx = mutualExcludeSelect.getValue();
if(itemIdx === '' || excludeIdx === ''){ alert('请选择体检项目和互斥项目'); return; }
if(itemIdx === excludeIdx){ alert('体检项目与互斥项目不能相同'); return; }
var item = itemData[Number(itemIdx)];
var exclude = itemData[Number(excludeIdx)];
var itemLabel = item.name + '' + item.code + '';
var excludeLabel = exclude.name + '' + exclude.code + '';
var dup = mutualData.some(function(r){ return r.item === itemLabel && r.exclude === excludeLabel; });
if(dup){ alert('该互斥关系已存在'); return; }
mutualData.push({item:itemLabel, exclude:excludeLabel});
renderMutualTable();
closeMutualAddModal();
}
/* 删除互斥项目 */
function deleteMutualRow(i){
if(!confirm('确认删除该互斥关系?')) return;
mutualData.splice(i, 1);
renderMutualTable();
}
function toggleMutualCheckAll(el){
document.querySelectorAll('.mutual-row-check').forEach(function(c){ c.checked = el.checked; });
}
function updateMutualCheckAll(){
var all = document.querySelectorAll('.mutual-row-check');
var checked = document.querySelectorAll('.mutual-row-check:checked');
document.getElementById('mutual-check-all').checked = all.length > 0 && checked.length === all.length;
}
function batchDeleteMutual(){
var checked = document.querySelectorAll('.mutual-row-check:checked');
if(checked.length === 0){ alert('请先选择要删除的记录'); return; }
if(!confirm('确认删除选中的 ' + checked.length + ' 条互斥关系?')) return;
var indexes = [];
checked.forEach(function(c){ indexes.push(Number(c.dataset.index)); });
indexes.sort(function(a, b){ return b - a; });
indexes.forEach(function(i){ mutualData.splice(i, 1); });
renderMutualTable();
}
</script>
</body>
</html>
@@ -79,6 +79,26 @@
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;}
.page-btn:hover,.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
/* 弹窗 */
.modal-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.45);z-index:999;display:none;align-items:center;justify-content:center;}
.modal-overlay.open{display:flex;}
.modal{background:#fff;border-radius:var(--radius-md);box-shadow:0 4px 16px rgba(0,0,0,0.15);width:460px;max-width:92vw;}
.modal__header{display:flex;align-items:center;justify-content:space-between;padding:18px 24px;border-bottom:1px solid var(--border);}
.modal__title{font-size:var(--font-lg);font-weight:600;}
.modal__close{width:32px;height:32px;border-radius:50%;border:none;background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-secondary);font-size:18px;}
.modal__close:hover{background:#F5F5F5;}
.modal__body{padding:24px;}
.modal__footer{display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid var(--border);}
/* 表单 */
.form-item{margin-bottom:20px;}
.form-label{font-size:var(--font-sm);color:var(--text-secondary);margin-bottom:8px;display:flex;align-items:center;gap:4px;font-weight:500;}
.form-label .required{color:var(--danger);}
.form-input{width:100%;height:40px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;}
.form-input:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
/* 信息展示 */
.fee-info{background:#FAFAFA;border-radius:var(--radius-sm);padding:14px 16px;margin-bottom:20px;display:flex;flex-direction:column;gap:10px;}
.fee-info__item{display:flex;font-size:var(--font-sm);color:var(--text-primary);}
.fee-info__item label{color:var(--text-secondary);width:88px;flex-shrink:0;}
</style>
</head>
<body>
@@ -164,6 +184,12 @@
<option>请选择</option><option>第一采油厂</option><option>第二采油厂</option><option>第三采油厂</option>
</select>
</div>
<div class="filter-item">
<label>体检年度:</label>
<select class="filter-select">
<option>请选择</option><option selected>2025</option><option>2024</option><option>2026</option>
</select>
</div>
<div class="filter-item">
<label>体检医院:</label>
<select class="filter-select">
@@ -192,9 +218,9 @@
</tr>
</thead>
<tbody>
<tr><td>1</td><td>第一采油厂</td><td>2025</td><td>泾河医院</td><td>经颅多普勒</td><td><span class="media-icon media-icon--active" title="查看图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>280.00</td><td><span class="link">更改费用</span></td></tr>
<tr><td>2</td><td>第二采油厂</td><td>2025</td><td>庆阳医院</td><td>腹部彩超</td><td><span class="media-icon media-icon--active" title="查看图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>200.00</td><td><span class="link">更改费用</span></td></tr>
<tr><td>3</td><td>第三采油厂</td><td>2025</td><td>延安医院</td><td>血常规</td><td><span class="media-icon media-icon--empty" title="暂无图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>40.00</td><td><span class="link">更改费用</span></td></tr>
<tr><td>1</td><td>第一采油厂</td><td>2025</td><td>泾河医院</td><td>经颅多普勒</td><td><span class="media-icon media-icon--active" title="查看图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>280.00</td><td><span class="link" onclick="openFeeModal(this)">更改费用</span></td></tr>
<tr><td>2</td><td>第二采油厂</td><td>2025</td><td>庆阳医院</td><td>腹部彩超</td><td><span class="media-icon media-icon--active" title="查看图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>200.00</td><td><span class="link" onclick="openFeeModal(this)">更改费用</span></td></tr>
<tr><td>3</td><td>第三采油厂</td><td>2025</td><td>延安医院</td><td>血常规</td><td><span class="media-icon media-icon--empty" title="暂无图片"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><rect x="2" y="3" width="12" height="10" rx="1.5" stroke="currentColor" stroke-width="1.3"/><circle cx="5.5" cy="6.5" r="1.2" stroke="currentColor" stroke-width="1"/><path d="M2 11l3.5-3 2.5 2 3-2.5L14 11" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg></span></td><td>40.00</td><td><span class="link" onclick="openFeeModal(this)">更改费用</span></td></tr>
</tbody>
</table>
</div>
@@ -207,6 +233,32 @@
</div>
</main>
<!-- 更改费用弹窗 -->
<div class="modal-overlay" id="fee-modal-overlay" onclick="if(event.target===this)closeFeeModal()">
<div class="modal">
<div class="modal__header">
<div class="modal__title">更改费用</div>
<button class="modal__close" onclick="closeFeeModal()"></button>
</div>
<div class="modal__body">
<div class="fee-info">
<div class="fee-info__item"><label>单位:</label><span id="fee-unit"></span></div>
<div class="fee-info__item"><label>体检年度:</label><span id="fee-year"></span></div>
<div class="fee-info__item"><label>医院名称:</label><span id="fee-hospital"></span></div>
<div class="fee-info__item"><label>体检项目:</label><span id="fee-item"></span></div>
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 项目费用(元)</div>
<input class="form-input" id="fee-amount" type="number" min="0" step="0.01" placeholder="请输入项目费用">
</div>
</div>
<div class="modal__footer">
<button class="btn btn-default" onclick="closeFeeModal()">取消</button>
<button class="btn btn-primary" onclick="saveFee()">确认保存</button>
</div>
</div>
</div>
<script>
/* 侧边栏展开/折叠交互 */
function toggleSubgroup(header){
@@ -219,6 +271,30 @@ function toggleSubgroup(header){
var sub=active.closest('.sidebar-subgroup');
if(sub)sub.classList.add('open');
})();
/* ===== 更改费用弹窗 ===== */
var feeTr = null;
function openFeeModal(btn){
feeTr = btn.closest('tr');
var cells = feeTr.cells;
document.getElementById('fee-unit').textContent = cells[1].textContent.trim();
document.getElementById('fee-year').textContent = cells[2].textContent.trim();
document.getElementById('fee-hospital').textContent = cells[3].textContent.trim();
document.getElementById('fee-item').textContent = cells[4].textContent.trim();
document.getElementById('fee-amount').value = cells[6].textContent.trim();
document.getElementById('fee-modal-overlay').classList.add('open');
}
function closeFeeModal(){
document.getElementById('fee-modal-overlay').classList.remove('open');
}
function saveFee(){
if(!feeTr) return;
var amount = document.getElementById('fee-amount').value.trim();
if(!amount || Number(amount) < 0){ alert('请输入正确的项目费用'); return; }
feeTr.cells[6].textContent = Number(amount).toFixed(2);
closeFeeModal();
}
</script>
</body>
</html>
+149 -45
View File
@@ -74,6 +74,13 @@
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;}
.page-btn:hover,.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
/* TAB 切换 */
.plan-tabs{display:flex;gap:0;margin-bottom:20px;border-bottom:2px solid var(--border);background:#fff;border-radius:var(--radius-md) var(--radius-md) 0 0;box-shadow:var(--shadow-sm);}
.plan-tab{padding:14px 32px;font-size:var(--font-base);color:var(--text-secondary);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-2px;transition:all .2s;font-weight:500;}
.plan-tab:hover{color:var(--primary);}
.plan-tab.active{color:var(--primary);border-bottom-color:var(--primary);font-weight:600;}
.tab-pane{display:none;}
.tab-pane.active{display:block;}
</style>
</head>
<body>
@@ -147,57 +154,131 @@
<!-- 主内容 -->
<main class="main">
<!-- 筛选栏 -->
<div class="filter-bar">
<div class="filter-item">
<label>计划名称:</label>
<input class="filter-input" type="text" placeholder="请输入" style="min-width:180px;">
</div>
<div class="filter-item">
<label>有效标志:</label>
<select class="filter-select">
<option>请选择</option><option>有效</option><option>无效</option>
</select>
</div>
<div class="filter-item">
<label>开展单位:</label>
<select class="filter-select">
<option>请选择</option>
</select>
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
<!-- TAB 切换 -->
<div class="plan-tabs">
<div class="plan-tab active" onclick="switchTab('normal', this)">常规体检</div>
<div class="plan-tab" onclick="switchTab('gastro', this)">胃肠镜体检</div>
</div>
<!-- 操作按钮 -->
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-primary">+ 新增</button>
<!-- 常规体检 -->
<div class="tab-pane active" id="pane-normal">
<!-- 筛选栏 -->
<div class="filter-bar">
<div class="filter-item">
<label>体检年度:</label>
<select class="filter-select plan-year"></select>
</div>
<div class="filter-item">
<label>计划名称:</label>
<input class="filter-input" type="text" placeholder="请输入" style="min-width:180px;">
</div>
<div class="filter-item">
<label>有效标志:</label>
<select class="filter-select">
<option>请选择</option><option>有效</option><option>无效</option>
</select>
</div>
<div class="filter-item">
<label>开展单位:</label>
<select class="filter-select">
<option>请选择</option>
</select>
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
</div>
<!-- 操作按钮 -->
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-primary">+ 新增</button>
</div>
<!-- 数据表格 -->
<div class="table-card">
<div class="table-card__header">
<div class="table-card__title">常规体检计划列表</div>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<th>序号</th><th>单位</th><th>体检年度</th><th>体检计划名称</th><th>承检医院</th><th>签约医院</th><th>有效标志</th><th>体检计划日期范围</th><th>允许预约日期范围</th><th>创建人</th><th>创建时间</th><th>操作</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>新闻中心</td><td>2026</td><td>新闻中心2026年员工非职业健康体检</td><td>兴隆园医院</td><td>宝石花</td><td><span class="tag tag-green">有效</span></td><td>2025-06-23至2025-08-31</td><td>2025-06-23至2025-08-31</td><td>系统管理员</td><td>2025-06-18 09:20</td><td><span class="link">编辑</span> <span class="link" style="margin-left:8px;">删除</span></td></tr>
<tr><td>2</td><td>公司机关</td><td>2026</td><td>公司机关2026年员工非职业健康体检</td><td>宝石花</td><td>宝石花</td><td><span class="tag tag-green">有效</span></td><td>2025-06-23至2025-08-31</td><td>2025-06-23至2025-08-31</td><td>系统管理员</td><td>2025-06-18 09:45</td><td><span class="link">编辑</span> <span class="link" style="margin-left:8px;">删除</span></td></tr>
<tr><td>3</td><td>采油二厂</td><td>2026</td><td>采油二厂2026年员工职业健康体检</td><td>兴隆园医院</td><td>兴隆园医院</td><td><span class="tag tag-green">有效</span></td><td>2025-06-23至2025-08-31</td><td>2025-06-23至2025-08-31</td><td>系统管理员</td><td>2025-06-19 14:10</td><td><span class="link">编辑</span> <span class="link" style="margin-left:8px;">删除</span></td></tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>共 243 条</span>
<button class="page-btn active">1</button>
<span>每页</span>
<select class="filter-select" style="min-width:70px;height:32px;"><option>10条</option><option>20条</option><option>50条</option></select>
</div>
</div>
</div>
<!-- 数据表格 -->
<div class="table-card">
<div class="table-card__header">
<div class="table-card__title">体检计划列表</div>
<!-- 胃肠镜体检 -->
<div class="tab-pane" id="pane-gastro">
<!-- 筛选栏 -->
<div class="filter-bar">
<div class="filter-item">
<label>体检年度:</label>
<select class="filter-select plan-year"></select>
</div>
<div class="filter-item">
<label>计划名称:</label>
<input class="filter-input" type="text" placeholder="请输入" style="min-width:180px;">
</div>
<div class="filter-item">
<label>有效标志:</label>
<select class="filter-select">
<option>请选择</option><option>有效</option><option>无效</option>
</select>
</div>
<div class="filter-item">
<label>开展单位:</label>
<select class="filter-select">
<option>请选择</option>
</select>
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<th>序号</th><th>单位</th><th>体检年度</th><th>体检计划名称</th><th>承检医院</th><th>签约医院</th><th>有效标志</th><th>体检计划日期范围</th><th>允许预约日期范围</th><th>操作</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>新闻中心</td><td>2026</td><td>新闻中心2026年员工非职业健康体检</td><td>兴隆园医院</td><td>宝石花</td><td><span class="tag tag-green">有效</span></td><td>2025-06-23至2025-08-31</td><td>2025-06-23至2025-08-31</td><td><span class="link">编辑</span> <span class="link" style="margin-left:8px;">删除</span></td></tr>
<tr><td>2</td><td>公司机关</td><td>2026</td><td>公司机关2026年员工非职业健康体检</td><td>宝石花</td><td>宝石花</td><td><span class="tag tag-green">有效</span></td><td>2025-06-23至2025-08-31</td><td>2025-06-23至2025-08-31</td><td><span class="link">编辑</span> <span class="link" style="margin-left:8px;">删除</span></td></tr>
<tr><td>3</td><td>采油二厂</td><td>2026</td><td>采油二厂2026年员工职业健康体检</td><td>兴隆园医院</td><td>兴隆园医院</td><td><span class="tag tag-green">有效</span></td><td>2025-06-23至2025-08-31</td><td>2025-06-23至2025-08-31</td><td><span class="link">编辑</span> <span class="link" style="margin-left:8px;">删除</span></td></tr>
</tbody>
</table>
<!-- 操作按钮 -->
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-primary">+ 新增</button>
</div>
<div class="pagination">
<span>共 243 条</span>
<button class="page-btn active">1</button>
<span>每页</span>
<select class="filter-select" style="min-width:70px;height:32px;"><option>10条</option><option>20条</option><option>50条</option></select>
<!-- 数据表格 -->
<div class="table-card">
<div class="table-card__header">
<div class="table-card__title">胃肠镜体检计划列表</div>
</div>
<div class="table-card__content">
<table>
<thead>
<tr>
<th>序号</th><th>单位</th><th>体检年度</th><th>体检计划名称</th><th>承检医院</th><th>签约医院</th><th>有效标志</th><th>体检计划日期范围</th><th>允许预约日期范围</th><th>创建人</th><th>创建时间</th><th>操作</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>新闻中心</td><td>2026</td><td>新闻中心2026年员工胃肠镜体检</td><td>宝石花</td><td>宝石花</td><td><span class="tag tag-green">有效</span></td><td>2025-06-23至2025-08-31</td><td>2025-06-23至2025-08-31</td><td>系统管理员</td><td>2025-06-20 10:05</td><td><span class="link">编辑</span> <span class="link" style="margin-left:8px;">删除</span></td></tr>
<tr><td>2</td><td>公司机关</td><td>2026</td><td>公司机关2026年员工胃肠镜体检</td><td>庆阳医院</td><td>庆阳医院</td><td><span class="tag tag-green">有效</span></td><td>2025-06-23至2025-08-31</td><td>2025-06-23至2025-08-31</td><td>系统管理员</td><td>2025-06-20 10:32</td><td><span class="link">编辑</span> <span class="link" style="margin-left:8px;">删除</span></td></tr>
<tr><td>3</td><td>采油二厂</td><td>2026</td><td>采油二厂2026年员工胃肠镜体检</td><td>兴隆园医院</td><td>兴隆园医院</td><td><span class="tag tag-green">有效</span></td><td>2025-06-23至2025-08-31</td><td>2025-06-23至2025-08-31</td><td>系统管理员</td><td>2025-06-21 15:40</td><td><span class="link">编辑</span> <span class="link" style="margin-left:8px;">删除</span></td></tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>共 87 条</span>
<button class="page-btn active">1</button>
<span>每页</span>
<select class="filter-select" style="min-width:70px;height:32px;"><option>10条</option><option>20条</option><option>50条</option></select>
</div>
</div>
</div>
</main>
@@ -214,6 +295,29 @@ function toggleSubgroup(header){
var sub=active.closest('.sidebar-subgroup');
if(sub)sub.classList.add('open');
})();
/* TAB 切换 */
function switchTab(type, el){
document.querySelectorAll('.plan-tab').forEach(function(t){ t.classList.remove('active'); });
document.querySelectorAll('.tab-pane').forEach(function(p){ p.classList.remove('active'); });
el.classList.add('active');
document.getElementById('pane-' + type).classList.add('active');
}
/* 体检年度默认当年 */
(function(){
var year = new Date().getFullYear();
document.querySelectorAll('.plan-year').forEach(function(sel){
sel.innerHTML = '';
for(var y = year - 3; y <= year + 1; y++){
var opt = document.createElement('option');
opt.value = y;
opt.textContent = y + '年';
if(y === year) opt.selected = true;
sel.appendChild(opt);
}
});
})();
</script>
</body>
</html>
@@ -147,6 +147,16 @@
<!-- 主内容 -->
<main class="main">
<!-- 筛选栏 -->
<div class="filter-bar">
<div class="filter-item">
<label>体检年度:</label>
<select class="filter-select quota-year"></select>
</div>
<button class="btn btn-primary">查询</button>
<button class="btn btn-default">重置</button>
</div>
<!-- 数据表格 - 群体额度 -->
<div class="table-card">
<div class="table-card__header">
@@ -190,6 +200,21 @@ function toggleSubgroup(header){
var sub=active.closest('.sidebar-subgroup');
if(sub)sub.classList.add('open');
})();
/* 体检年度默认当年 */
(function(){
var year = new Date().getFullYear();
document.querySelectorAll('.quota-year').forEach(function(sel){
sel.innerHTML = '';
for(var y = year - 3; y <= year + 1; y++){
var opt = document.createElement('option');
opt.value = y;
opt.textContent = y + '年';
if(y === year) opt.selected = true;
sel.appendChild(opt);
}
});
})();
</script>
</body>
</html>
@@ -74,6 +74,35 @@
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;}
.page-btn:hover,.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
/* 弹窗 */
.modal-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.45);z-index:999;display:none;align-items:center;justify-content:center;}
.modal-overlay.open{display:flex;}
.modal{background:#fff;border-radius:var(--radius-md);box-shadow:0 4px 16px rgba(0,0,0,0.15);width:460px;max-width:92vw;}
.modal__header{display:flex;align-items:center;justify-content:space-between;padding:18px 24px;border-bottom:1px solid var(--border);}
.modal__title{font-size:var(--font-lg);font-weight:600;}
.modal__close{width:32px;height:32px;border-radius:50%;border:none;background:transparent;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-secondary);font-size:18px;}
.modal__close:hover{background:#F5F5F5;}
.modal__body{padding:24px;}
.modal__footer{display:flex;justify-content:flex-end;gap:12px;padding:16px 24px;border-top:1px solid var(--border);}
/* 表单 */
.form-item{margin-bottom:20px;}
.form-item:last-child{margin-bottom:0;}
.form-label{font-size:var(--font-sm);color:var(--text-secondary);margin-bottom:8px;font-weight:500;}
.form-label .required{color:var(--danger);}
.form-input{width:100%;height:40px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff;}
.form-input:focus{border-color:var(--primary);box-shadow:0 0 0 2px rgba(24,144,255,0.2);}
/* 人员信息 */
.person-info{background:#F5F7FA;border-radius:var(--radius-sm);padding:12px 14px;margin-bottom:20px;display:flex;flex-wrap:wrap;gap:8px 28px;}
.person-info__item{font-size:var(--font-sm);}
.person-info__item label{color:var(--text-secondary);}
.person-info__item span{color:var(--text-primary);font-weight:500;}
/* 开关 */
.switch-row{display:flex;align-items:center;gap:12px;}
.switch{width:40px;height:22px;border-radius:11px;background:#E8E8E8;cursor:pointer;position:relative;transition:.2s;flex-shrink:0;}
.switch.on{background:var(--primary);}
.switch::after{content:'';position:absolute;width:18px;height:18px;border-radius:50%;background:#fff;top:2px;left:2px;transition:.2s;box-shadow:0 1px 3px rgba(0,0,0,0.2);}
.switch.on::after{left:20px;}
.switch-label{font-size:var(--font-sm);color:var(--text-primary);}
</style>
</head>
<body>
@@ -150,7 +179,7 @@
<!-- 筛选栏 -->
<div class="filter-bar">
<div class="filter-item">
<label>单位:</label>
<label>单位部门</label>
<select class="filter-select">
<option>全部</option>
<option>采油一厂</option>
@@ -198,9 +227,9 @@
</tr>
</thead>
<tbody>
<tr><td>1</td><td>张明</td><td>100234</td><td></td><td>38</td><td>610113199602632255</td><td>公司机关</td><td>人事部</td><td>2500.00</td><td></td><td><span class="link">设置额度</span></td></tr>
<tr><td>2</td><td>李芳</td><td>100567</td><td></td><td>42</td><td>610113199602632255</td><td>公司机关</td><td>财务部</td><td>2500.00</td><td></td><td><span class="link">设置额度</span></td></tr>
<tr><td>3</td><td>王强</td><td>200891</td><td></td><td>50</td><td>610113199602632255</td><td>采油一厂</td><td>生产办</td><td>2500.00</td><td></td><td><span class="link">设置额度</span></td></tr>
<tr><td>1</td><td>张明</td><td>100234</td><td></td><td>38</td><td>610113199602632255</td><td>公司机关</td><td>人事部</td><td>2500.00</td><td></td><td><span class="link" onclick="openQuotaModal(this)">设置额度</span></td></tr>
<tr><td>2</td><td>李芳</td><td>100567</td><td></td><td>42</td><td>610113199602632255</td><td>公司机关</td><td>财务部</td><td>2500.00</td><td></td><td><span class="link" onclick="openQuotaModal(this)">设置额度</span></td></tr>
<tr><td>3</td><td>王强</td><td>200891</td><td></td><td>50</td><td>610113199602632255</td><td>采油一厂</td><td>生产办</td><td>2500.00</td><td></td><td><span class="link" onclick="openQuotaModal(this)">设置额度</span></td></tr>
</tbody>
</table>
</div>
@@ -217,6 +246,38 @@
</div>
</main>
<!-- 设置个人额度弹窗 -->
<div class="modal-overlay" id="quota-modal-overlay" onclick="if(event.target===this)closeQuotaModal()">
<div class="modal">
<div class="modal__header">
<div class="modal__title">设置个人额度</div>
<button class="modal__close" onclick="closeQuotaModal()"></button>
</div>
<div class="modal__body">
<div class="person-info">
<div class="person-info__item"><label>姓名:</label><span id="quota-name"></span></div>
<div class="person-info__item"><label>员工编号:</label><span id="quota-code"></span></div>
<div class="person-info__item"><label>单位部门:</label><span id="quota-unit"></span></div>
</div>
<div class="form-item">
<div class="form-label"><span class="required">*</span> 体检额度(元)</div>
<input class="form-input" id="quota-amount" type="number" min="0" step="0.01" placeholder="请输入体检额度">
</div>
<div class="form-item">
<div class="form-label">是否手动输入</div>
<div class="switch-row">
<div class="switch" id="quota-manual" onclick="toggleQuotaSwitch(this)"></div>
<span class="switch-label" id="quota-manual-label"></span>
</div>
</div>
</div>
<div class="modal__footer">
<button class="btn btn-default" onclick="closeQuotaModal()">取消</button>
<button class="btn btn-primary" onclick="saveQuota()">确认保存</button>
</div>
</div>
</div>
<script>
/* 侧边栏展开/折叠交互 */
function toggleSubgroup(header){
@@ -229,6 +290,44 @@ function toggleSubgroup(header){
var sub=active.closest('.sidebar-subgroup');
if(sub)sub.classList.add('open');
})();
/* ===== 设置个人额度弹窗 ===== */
var quotaTr = null;
function openQuotaModal(btn){
quotaTr = btn.closest('tr');
var cells = quotaTr.cells;
document.getElementById('quota-name').textContent = cells[1].textContent.trim();
document.getElementById('quota-code').textContent = cells[2].textContent.trim();
document.getElementById('quota-unit').textContent = cells[6].textContent.trim() + ' / ' + cells[7].textContent.trim();
document.getElementById('quota-amount').value = cells[8].textContent.trim();
var manual = cells[9].textContent.trim() === '是';
var sw = document.getElementById('quota-manual');
sw.classList.toggle('on', manual);
document.getElementById('quota-manual-label').textContent = manual ? '是' : '否';
document.getElementById('quota-modal-overlay').classList.add('open');
}
function closeQuotaModal(){
document.getElementById('quota-modal-overlay').classList.remove('open');
}
function toggleQuotaSwitch(el){
el.classList.toggle('on');
document.getElementById('quota-manual-label').textContent = el.classList.contains('on') ? '是' : '否';
}
function saveQuota(){
if(!quotaTr) return;
var amount = document.getElementById('quota-amount').value.trim();
if(!amount || Number(amount) < 0){ alert('请输入正确的体检额度'); return; }
var formatted = Number(amount).toFixed(2);
var manual = document.getElementById('quota-manual').classList.contains('on');
var cells = quotaTr.cells;
cells[8].textContent = formatted;
cells[9].textContent = manual ? '是' : '否';
closeQuotaModal();
}
</script>
</body>
</html>