- 大屏数据配置:增加应急中心下拉切换(西安/银川),各中心独立配置面板,模块开关控制输入框置灰 - 排班配置:改为星期行×操作人员/专业人员列结构,编辑模式带边框输入和人员多选搜索 - 模拟急救联动:列表改为员工维度,点击弹出模拟急救弹窗(疾病Tab/地图选点/急救提示书/资源列表) - 删除 center-employee.html 和 center-seat.html,清理所有侧边栏引用 - 新增多个详情/新增子页面,优化资源管理和异常事件页面 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
612 lines
39 KiB
HTML
612 lines
39 KiB
HTML
<!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>
|
|
:root {
|
|
--primary: #1677FF;
|
|
--primary-light: #E6F7FF;
|
|
--primary-dark: #0958D9;
|
|
--success: #52C41A;
|
|
--warning: #FAAD14;
|
|
--danger: #FF4D4F;
|
|
--purple: #722ED1;
|
|
--green: #52C41A;
|
|
--green-light: #f6ffed;
|
|
--green-border: #b7eb8f;
|
|
--text-primary: #1a1a2e;
|
|
--text-secondary: #5a607f;
|
|
--text-placeholder: #999999;
|
|
--border: #e8ecf1;
|
|
--background: #f0f2f8;
|
|
--card-bg: #ffffff;
|
|
--radius-sm: 6px;
|
|
--radius-md: 10px;
|
|
--radius-lg: 16px;
|
|
--shadow-sm: 0 1px 3px rgba(0,0,0,0.04), 0 1px 2px rgba(0,0,0,0.06);
|
|
--shadow-md: 0 4px 16px rgba(22,119,255,0.10), 0 2px 6px rgba(0,0,0,0.06);
|
|
--shadow-lg: 0 10px 30px rgba(22,119,255,0.15), 0 4px 10px rgba(0,0,0,0.06);
|
|
}
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body { background: var(--background); font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', 'Segoe UI', sans-serif; color: var(--text-primary); min-height: 100vh; }
|
|
|
|
/* ===== Header ===== */
|
|
.header { position: relative; background: linear-gradient(135deg, #0b3d91 0%, var(--primary) 40%, #4facfe 100%); color: #fff; padding: 40px 48px 20px; overflow: hidden; }
|
|
.header::before { content: ''; position: absolute; top: -60px; right: -40px; width: 260px; height: 260px; background: radial-gradient(circle, rgba(255,255,255,0.12) 0%, transparent 70%); border-radius: 50%; }
|
|
.header::after { content: ''; position: absolute; bottom: -80px; left: 20%; width: 360px; height: 360px; background: radial-gradient(circle, rgba(255,255,255,0.06) 0%, transparent 70%); border-radius: 50%; }
|
|
.header__inner { position: relative; z-index: 1; max-width: 1400px; margin: 0 auto; text-align: center; }
|
|
.header__title { font-size: 28px; font-weight: 800; letter-spacing: 1px; text-shadow: 0 2px 8px rgba(0,0,0,0.15); }
|
|
.header__sub { font-size: 14px; color: rgba(255,255,255,0.7); margin-top: 8px; }
|
|
|
|
/* ===== Tab 导航(嵌入 Header 底部) ===== */
|
|
.tab-nav { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 20px 48px 0; position: relative; z-index: 1; }
|
|
.tab-nav__item { padding: 10px 28px; font-size: 15px; font-weight: 600; color: rgba(255,255,255,0.7); cursor: pointer; border-radius: 28px; transition: all .25s ease; user-select: none; display: flex; align-items: center; gap: 8px; border: 1.5px solid rgba(255,255,255,0.25); background: rgba(255,255,255,0.08); backdrop-filter: blur(6px); }
|
|
.tab-nav__item:hover { color: #fff; background: rgba(255,255,255,0.18); border-color: rgba(255,255,255,0.4); }
|
|
.tab-nav__item--active { color: var(--primary-dark); background: #fff; border-color: #fff; box-shadow: 0 4px 16px rgba(0,0,0,0.15); }
|
|
.tab-nav__item--active .tab-nav__badge { background: var(--primary); color: #fff; }
|
|
.tab-nav__badge { font-size: 11px; padding: 2px 9px; border-radius: 10px; background: rgba(255,255,255,0.2); color: rgba(255,255,255,0.9); font-weight: 700; transition: all .25s; }
|
|
.tab-nav__icon { width: 18px; height: 18px; flex-shrink: 0; }
|
|
|
|
/* ===== 内容区 ===== */
|
|
.main-content { max-width: 1400px; margin: 0 auto; padding: 28px 48px 48px; }
|
|
.tab-content { display: none; animation: fadeUp .35s ease; }
|
|
.tab-content--active { display: block; }
|
|
@keyframes fadeUp { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
|
|
|
|
/* ===== 模块网格 ===== */
|
|
.module-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 20px; }
|
|
.module-grid--center { justify-content: center; display: flex; flex-wrap: wrap; gap: 20px; }
|
|
.module-grid--center .module-card { width: 320px; flex-shrink: 0; }
|
|
|
|
/* ===== 角色分组 ===== */
|
|
.role-group { margin-bottom: 28px; text-align: center; }
|
|
.role-group:last-child { margin-bottom: 0; }
|
|
.role-group__title { display: inline-flex; align-items: center; gap: 8px; font-size: 15px; font-weight: 600; color: var(--text-primary); margin-bottom: 16px; padding: 6px 16px 6px 12px; background: var(--card-bg); border-radius: var(--radius-md); box-shadow: var(--shadow-sm); }
|
|
.role-icon { width: 22px; height: 22px; border-radius: 6px; display: flex; align-items: center; justify-content: center; font-size: 13px; color: #fff; flex-shrink: 0; }
|
|
.role-icon--expert { background: linear-gradient(135deg, #1677FF, #4facfe); }
|
|
.role-icon--assistant { background: linear-gradient(135deg, #722ED1, #b37feb); }
|
|
.role-icon--operator { background: linear-gradient(135deg, #fa541c, #ff7a45); }
|
|
.role-icon--worker { background: linear-gradient(135deg, #52c41a, #95de64); }
|
|
.role-icon--onsite { background: linear-gradient(135deg, #faad14, #ffc53d); }
|
|
.role-icon--admin { background: linear-gradient(135deg, #eb2f96, #ff85c0); }
|
|
.role-icon--shared { background: linear-gradient(135deg, #13c2c2, #5cdbd3); }
|
|
|
|
/* ===== 呼吸灯动画 ===== */
|
|
@keyframes breathe {
|
|
0%, 100% { border-color: rgba(82,196,26,0.35); box-shadow: 0 0 0 0 rgba(82,196,26,0); }
|
|
50% { border-color: rgba(82,196,26,0.7); box-shadow: 0 0 12px 2px rgba(82,196,26,0.18); }
|
|
}
|
|
|
|
/* ===== 模块卡片 ===== */
|
|
.module-card { position: relative; background: var(--card-bg); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); padding: 20px; transition: all .25s ease; border: 1.5px solid var(--border); cursor: pointer; z-index: 1; }
|
|
.module-card--pop-open { z-index: 200; }
|
|
.module-card:hover { box-shadow: var(--shadow-lg); transform: translateY(-3px); }
|
|
.module-card--ready { border-color: var(--green-border); animation: breathe 3s ease-in-out infinite; }
|
|
.module-card--ready:hover { border-color: var(--green); animation: none; box-shadow: 0 8px 24px rgba(82,196,26,0.2); }
|
|
.module-card--empty { opacity: 0.55; border-style: dashed; border-color: #d0d5dd; cursor: default; }
|
|
.module-card--empty:hover { transform: none; box-shadow: var(--shadow-sm); }
|
|
.module-card__header { display: flex; align-items: center; justify-content: space-between; }
|
|
.module-card__name { font-size: 15px; font-weight: 700; color: var(--text-primary); }
|
|
.module-card__tag { position: relative; font-size: 11px; padding: 3px 10px; border-radius: 12px; font-weight: 600; letter-spacing: 0.3px; }
|
|
.module-card__tag--ready { background: var(--green-light); color: #389e0d; border: 1px solid var(--green-border); cursor: pointer; transition: all .15s; }
|
|
.module-card__tag--ready:hover { background: #d9f7be; transform: scale(1.05); }
|
|
.module-card__tag--pending { background: #fffbe6; color: #d48806; border: 1px solid #ffe58f; }
|
|
.module-card__empty-hint { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-placeholder); margin-top: 10px; }
|
|
|
|
/* ===== 悬浮页面列表 ===== */
|
|
.page-popover { display: none; position: absolute; top: 100%; right: 0; margin-top: 6px; background: var(--card-bg); border: 1px solid var(--border); border-radius: var(--radius-md); box-shadow: 0 8px 30px rgba(0,0,0,0.15); padding: 8px 0; z-index: 100; min-width: 200px; max-height: 320px; overflow-y: auto; animation: popIn .2s ease; }
|
|
.page-popover--visible { display: block; }
|
|
@keyframes popIn { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: translateY(0); } }
|
|
.page-popover__title { font-size: 12px; color: var(--text-placeholder); padding: 4px 14px 8px; border-bottom: 1px solid var(--border); margin-bottom: 4px; }
|
|
.page-popover__item { display: flex; align-items: center; gap: 8px; padding: 7px 14px; font-size: 13px; color: var(--text-primary); text-decoration: none; transition: background .15s; }
|
|
.page-popover__item:hover { background: var(--primary-light); color: var(--primary-dark); }
|
|
.page-popover__item svg { flex-shrink: 0; }
|
|
.page-popover__item--dialog { color: #ad4e00; }
|
|
.page-popover__item--dialog:hover { background: #fff7e6; color: #ad4e00; }
|
|
|
|
/* ===== 卡片底部 PRD 链接 ===== */
|
|
.module-card__footer { display: flex; justify-content: flex-start; margin-top: 10px; }
|
|
.module-card__prd { font-size: 12px; color: var(--primary); cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px; border-radius: var(--radius-sm); transition: all .15s; }
|
|
.module-card__prd:hover { background: var(--primary-light); color: var(--primary-dark); }
|
|
.module-card__prd svg { flex-shrink: 0; }
|
|
|
|
/* ===== PRD Tab 页 ===== */
|
|
.prd-page__global { margin-bottom: 28px; }
|
|
.prd-global-card { background: linear-gradient(135deg, #f6ffed 0%, #e6f7ff 100%); border: 1.5px solid var(--green-border); border-radius: var(--radius-lg); padding: 20px 24px; cursor: pointer; transition: all .25s; display: flex; align-items: center; gap: 16px; }
|
|
.prd-global-card:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); }
|
|
.prd-global-card__icon { width: 44px; height: 44px; border-radius: 12px; background: linear-gradient(135deg, var(--primary), #4facfe); display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
|
|
.prd-global-card__info { flex: 1; }
|
|
.prd-global-card__title { font-size: 16px; font-weight: 700; color: var(--text-primary); }
|
|
.prd-global-card__desc { font-size: 13px; color: var(--text-secondary); margin-top: 4px; }
|
|
.prd-section { margin-bottom: 28px; }
|
|
.prd-section__title { font-size: 15px; font-weight: 600; color: var(--text-primary); margin-bottom: 14px; padding: 6px 16px; background: var(--card-bg); border-radius: var(--radius-md); box-shadow: var(--shadow-sm); display: inline-flex; align-items: center; gap: 8px; }
|
|
.prd-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }
|
|
.prd-item { background: var(--card-bg); border: 1.5px solid var(--border); border-radius: var(--radius-md); padding: 16px 18px; cursor: pointer; transition: all .2s; display: flex; align-items: center; gap: 12px; }
|
|
.prd-item:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); border-color: var(--primary); }
|
|
.prd-item--disabled { opacity: 0.45; cursor: default; border-style: dashed; }
|
|
.prd-item--disabled:hover { box-shadow: none; transform: none; border-color: var(--border); }
|
|
.prd-item__icon { width: 36px; height: 36px; border-radius: 8px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; font-size: 18px; }
|
|
.prd-item__icon--ready { background: var(--green-light); color: #389e0d; }
|
|
.prd-item__icon--empty { background: #f5f5f5; color: #bbb; }
|
|
.prd-item__info { flex: 1; min-width: 0; }
|
|
.prd-item__name { font-size: 14px; font-weight: 600; color: var(--text-primary); }
|
|
.prd-item__path { font-size: 11px; color: var(--text-placeholder); margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
.prd-item__status { font-size: 11px; padding: 2px 8px; border-radius: 10px; font-weight: 600; flex-shrink: 0; }
|
|
.prd-item__status--ready { background: var(--green-light); color: #389e0d; border: 1px solid var(--green-border); }
|
|
.prd-item__status--empty { background: #fffbe6; color: #d48806; border: 1px solid #ffe58f; }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="header">
|
|
<div class="header__inner">
|
|
<div class="header__title">健康长庆升级项目 · 高保真交互原型</div>
|
|
<div class="header__sub">点击模块卡片跳转至对应模块主页,点击页数徽章查看全部页面,点击PRD文档在线预览详细功能说明</div>
|
|
</div>
|
|
<div class="tab-nav" id="tab-nav"></div>
|
|
</div>
|
|
<div class="main-content">
|
|
<div id="tab-contents"></div>
|
|
</div>
|
|
<script>
|
|
/* ===== SVG 图标 ===== */
|
|
const ICONS = {
|
|
web: '<svg class="tab-nav__icon" viewBox="0 0 18 18" fill="none"><rect x="1" y="2" width="16" height="12" rx="2" stroke="currentColor" stroke-width="1.5"/><line x1="5" y1="16" x2="13" y2="16" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/><line x1="9" y1="14" x2="9" y2="16" stroke="currentColor" stroke-width="1.5"/></svg>',
|
|
app: '<svg class="tab-nav__icon" viewBox="0 0 18 18" fill="none"><rect x="4" y="1" width="10" height="16" rx="2" stroke="currentColor" stroke-width="1.5"/><line x1="7.5" y1="14" x2="10.5" y2="14" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>',
|
|
emergency: '<svg class="tab-nav__icon" viewBox="0 0 18 18" fill="none"><path d="M9 1L2 6.5V16h5v-4h4v4h5V6.5L9 1z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M9 7v3M9 11.5v.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>',
|
|
page: '<svg width="14" height="14" viewBox="0 0 12 12" fill="none"><path d="M3 1h4l3 3v7H3V1z" stroke="currentColor" stroke-width="1.1"/><path d="M7 1v3h3" stroke="currentColor" stroke-width="1.1"/></svg>',
|
|
dialog: '<svg width="14" height="14" viewBox="0 0 12 12" fill="none"><rect x="1.5" y="2" width="9" height="8" rx="1.5" stroke="currentColor" stroke-width="1.1"/><line x1="4" y1="5" x2="8" y2="5" stroke="currentColor" stroke-width="1.1" stroke-linecap="round"/><line x1="4" y1="7.5" x2="6.5" y2="7.5" stroke="currentColor" stroke-width="1.1" stroke-linecap="round"/></svg>',
|
|
empty: '<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="6.5" stroke="currentColor" stroke-width="1.2" stroke-dasharray="3 2"/><path d="M8 5.5v3M8 10v.5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>',
|
|
prd: '<svg class="tab-nav__icon" viewBox="0 0 18 18" fill="none"><path d="M4 1h7l4 4v12H4V1z" stroke="currentColor" stroke-width="1.5"/><path d="M11 1v4h4" stroke="currentColor" stroke-width="1.5"/><line x1="7" y1="9" x2="13" y2="9" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/><line x1="7" y1="12" x2="11" y2="12" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>',
|
|
prdSmall: '<svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M2.5 1h5l2.5 2.5v7.5h-7.5V1z" stroke="currentColor" stroke-width="1"/><path d="M7.5 1v2.5h2.5" stroke="currentColor" stroke-width="1"/></svg>',
|
|
role: { expert:'👨⚕', assistant:'🤖', operator:'📋', worker:'👷', onsite:'🏥', admin:'⚙', shared:'🔗' }
|
|
};
|
|
|
|
const SITE_MAP = [
|
|
{ id:'web-admin', label:'Web 管理端', icon:'web', color:'#69b1ff', modules:[
|
|
{ name:'系统管理', dir:'web-admin/system-management', pages:[] },
|
|
{ name:'健康体检', dir:'web-admin/health-checkup', pages:[] },
|
|
{ name:'体重管理', dir:'web-admin/weight-management', pages:[] },
|
|
{ name:'营养管理', dir:'web-admin/nutrition', pages:[] },
|
|
{ name:'运动管理', dir:'web-admin/exercise', pages:[] },
|
|
{ name:'健康监测', dir:'web-admin/health-monitor', pages:[] },
|
|
{ name:'健康评估', dir:'web-admin/health-assessment', pages:[] },
|
|
{ name:'知识普及', dir:'web-admin/knowledge', pages:[] },
|
|
{ name:'健康数据', dir:'web-admin/health-data', pages:[] },
|
|
{ name:'健康档案', dir:'web-admin/health-record', pages:[] },
|
|
{ name:'心脑血管病预防', dir:'web-admin/cardiovascular', pages:[] },
|
|
{ name:'糖尿病预防', dir:'web-admin/diabetes', pages:[] },
|
|
{ name:'癌症预防', dir:'web-admin/cancer', pages:[] },
|
|
{ name:'专家咨询(管理员)', dir:'web-admin/health-consult', entry:'history-expert.html', prd:'web-admin/health-consult/doc/PRD.md', pages:[
|
|
{ file:'history-expert.html', label:'专家咨询记录' },
|
|
{ file:'video-detail-pending-confirm.html', label:'视频详情-待确认' },
|
|
{ file:'video-detail-pending-start.html', label:'视频详情-待开始' },
|
|
{ file:'video-detail-completed.html', label:'视频详情-已完成' },
|
|
{ file:'video-detail-rejected.html', label:'视频详情-已拒绝' },
|
|
{ file:'video-detail-cancelled.html', label:'视频详情-已取消' },
|
|
{ file:'video-detail-in-progress.html', label:'视频详情-进行中' },
|
|
{ file:'history-assistant.html', label:'小助手咨询记录' },
|
|
{ file:'history-evaluation.html', label:'用户评价' },
|
|
{ file:'consult-record.html', label:'咨询档案' },
|
|
{ file:'consult-record-detail.html', label:'咨询档案详情' },
|
|
{ file:'archive-personal.html', label:'个人咨询数据' },
|
|
{ file:'archive-personal-detail.html', label:'员工咨询明细' },
|
|
{ file:'archive-unit.html', label:'单位报表数据' },
|
|
{ file:'archive-unit-detail.html', label:'单位报表明细' },
|
|
{ file:'expert-statistics.html', label:'专家咨询统计' },
|
|
{ file:'unit-statistics.html', label:'单位咨询统计' },
|
|
{ file:'settlement.html', label:'咨询结算' },
|
|
{ file:'settlement-add.html', label:'新增结算' },
|
|
{ file:'settlement-report.html', label:'结算报表' },
|
|
{ file:'exception-dirty.html', label:'系统脏数据' },
|
|
{ file:'config-hospital.html', label:'医院配置' },
|
|
{ file:'config-department.html', label:'科室配置' },
|
|
{ file:'config-disease.html', label:'疾病配置' },
|
|
{ file:'config-notice.html', label:'咨询须知' },
|
|
{ file:'config-phrase.html', label:'常用语管理' },
|
|
{ file:'config-hospital-dialog.html', label:'医院配置弹窗', dialog:true },
|
|
{ file:'config-department-dialog.html', label:'科室配置弹窗', dialog:true },
|
|
{ file:'config-disease-dialog.html', label:'疾病配置弹窗', dialog:true },
|
|
{ file:'config-phrase-dialog.html', label:'常用语弹窗', dialog:true }
|
|
]},
|
|
{ name:'专家咨询(小助手)', dir:'web-admin/health-consult/assistant', entry:'current-consult.html', prd:'web-admin/health-consult/assistant/doc/PRD.md', pages:[
|
|
{ file:'current-consult.html', label:'当前咨询' },
|
|
{ file:'chat-message.html', label:'对话消息' },
|
|
{ file:'history-consult.html', label:'历史咨询' },
|
|
{ file:'expert-manage.html', label:'专家管理' },
|
|
{ file:'checkup-standard.html', label:'体检标准化' },
|
|
{ file:'sms-send.html', label:'短信发送' },
|
|
{ file:'config-phrase.html', label:'常用语' },
|
|
{ file:'consult-settle.html', label:'咨询结算' },
|
|
{ file:'consult-settle-add.html', label:'新增/编辑结算配置' },
|
|
{ file:'consult-settle-report.html', label:'结算报表' },
|
|
{ file:'employee-profile-dialog.html', label:'咨询人档案弹窗', dialog:true },
|
|
{ file:'select-expert-dialog.html', label:'选择专家弹窗', dialog:true },
|
|
{ file:'contacts-dialog.html', label:'通讯录弹窗', dialog:true },
|
|
{ file:'chat-detail-dialog.html', label:'对话详情弹窗', dialog:true },
|
|
{ file:'expert-detail-dialog.html', label:'专家详情弹窗', dialog:true },
|
|
{ file:'expert-import-dialog.html', label:'批量导入弹窗', dialog:true },
|
|
{ file:'export-task-dialog.html', label:'导出任务弹窗', dialog:true },
|
|
{ file:'import-task-dialog.html', label:'导入任务弹窗', dialog:true },
|
|
{ file:'item-detail-dialog.html', label:'项目明细弹窗', dialog:true },
|
|
{ file:'send-dialog.html', label:'新建短信弹窗', dialog:true },
|
|
{ file:'sms-detail-dialog.html', label:'发送详情弹窗', dialog:true },
|
|
{ file:'report-detail-dialog.html', label:'报表详情弹窗', dialog:true },
|
|
{ file:'expert-schedule-dialog.html', label:'专家排班弹窗', dialog:true }
|
|
]},
|
|
{ name:'应急就医(管理员)', dir:'web-admin/emergency-dispatch/admin', entry:'archive-personal.html', pages:[
|
|
{ file:'archive-personal.html', label:'个人应急数据' },
|
|
{ file:'archive-personal-detail.html', label:'个人应急数据详情' },
|
|
{ file:'archive-personal-detail-illness.html', label:'个人大病就医详情' },
|
|
{ file:'archive-unit.html', label:'单位报表数据' },
|
|
{ file:'archive-center.html', label:'应急中心报表数据' },
|
|
{ file:'resource-hospital.html', label:'医院信息' },
|
|
{ file:'resource-medical-point.html', label:'医疗点信息' },
|
|
{ file:'resource-aed.html', label:'AED设备信息-设备管理' },
|
|
{ file:'resource-aed-add.html', label:'AED设备信息-新增AED设备' },
|
|
{ file:'resource-aed-deploy.html', label:'AED设备信息-布点管理' },
|
|
{ file:'resource-aed-deploy-add.html', label:'AED设备信息-新增布点' },
|
|
{ file:'resource-aed-map.html', label:'AED设备信息-AED地图' },
|
|
{ file:'resource-aed-certifier.html', label:'AED设备信息-取证人员' },
|
|
{ file:'resource-aed-certifier-add.html', label:'AED设备信息-新增取证人员' },
|
|
{ file:'resource-aed-maintenance.html', label:'AED设备信息-维护记录' },
|
|
{ file:'resource-aed-maintenance-add.html', label:'AED设备信息-新增维护记录' },
|
|
{ file:'resource-aed-training.html', label:'AED设备信息-培演记录' },
|
|
{ file:'resource-aed-usage.html', label:'AED设备信息-应用记录' },
|
|
{ file:'resource-ambulance.html', label:'救护车信息' },
|
|
{ file:'resource-first-aid-kit.html', label:'急救包信息' },
|
|
{ file:'resource-doctor.html', label:'急救医生信息' },
|
|
{ file:'resource-emergency-contact.html', label:'紧急联系人信息' },
|
|
{ file:'center-basic-info.html', label:'应急中心基本信息' },
|
|
{ file:'center-work-order.html', label:'应急工单' },
|
|
{ file:'center-seat.html', label:'坐席管理' },
|
|
{ file:'center-group.html', label:'分组管理' },
|
|
{ file:'center-call-record.html', label:'通话记录' },
|
|
{ file:'center-serious-illness.html', label:'大病就医' },
|
|
{ file:'center-data-screen.html', label:'大屏数据配置' },
|
|
{ file:'center-schedule.html', label:'排班配置' },
|
|
{ file:'center-simulation.html', label:'模拟急救联动' },
|
|
{ file:'exception-result.html', label:'结果异常' }
|
|
]},
|
|
{ name:'应急就医(操作人员)', dir:'web-admin/emergency-dispatch/operator', entry:'emergency-active.html', pages:[
|
|
{ file:'emergency-active.html', label:'正在应急' },
|
|
{ file:'work-order.html', label:'应急工单' },
|
|
{ file:'call-record.html', label:'通话记录' },
|
|
{ file:'serious-illness.html', label:'大病就医' },
|
|
{ file:'duty-group.html', label:'值班小组' }
|
|
]},
|
|
{ name:'应急就医(专业人员)', dir:'web-admin/emergency-dispatch/professional', entry:'professional.html', pages:[
|
|
{ file:'professional.html', label:'正在应急' }
|
|
]},
|
|
{ name:'一线医疗', dir:'web-admin/frontline-medical', pages:[] }
|
|
]},
|
|
{ id:'employee-app', label:'员工端 APP', icon:'app', color:'#95de64', modules:[
|
|
{ name:'AI', dir:'employee-app/ai', pages:[] },
|
|
{ name:'应用主页', dir:'employee-app/home', pages:[] },
|
|
{ name:'健康体检', dir:'employee-app/health-checkup', pages:[] },
|
|
{ name:'体重管理', dir:'employee-app/weight-management', pages:[] },
|
|
{ name:'营养管理', dir:'employee-app/nutrition', pages:[] },
|
|
{ name:'运动管理', dir:'employee-app/exercise', pages:[] },
|
|
{ name:'健康监测', dir:'employee-app/health-monitor', pages:[] },
|
|
{ name:'健康评估', dir:'employee-app/health-assessment', pages:[] },
|
|
{ name:'心脑血管病预防', dir:'employee-app/cardiovascular', pages:[] },
|
|
{ name:'糖尿病预防', dir:'employee-app/diabetes', pages:[] },
|
|
{ name:'癌症预防', dir:'employee-app/cancer', pages:[] },
|
|
{ name:'健康咨询', dir:'employee-app/health-consult', prd:'employee-app/health-consult/doc/PRD.md', pages:[
|
|
{ file:'index.html', label:'咨询首页' }, { file:'search.html', label:'综合搜索' },
|
|
{ file:'find-expert.html', label:'找专家' }, { file:'expert-list.html', label:'专家列表' },
|
|
{ file:'expert-profile.html', label:'专家主页' }, { file:'expert-reviews.html', label:'专家评价' },
|
|
{ file:'hospital-detail.html', label:'医院详情' },
|
|
{ file:'select-person.html', label:'选择咨询人' }, { file:'select-record.html', label:'发送档案' }, { file:'consult-person-detail.html', label:'咨询人档案' },
|
|
{ file:'add-health-record.html', label:'新增健康档案' },
|
|
{ file:'text-chat.html', label:'图文咨询' }, { file:'text-chat-history.html', label:'图文历史对话' },
|
|
{ file:'assistant-chat.html', label:'小助手对话' }, { file:'assistant-chat-history.html', label:'小助手历史对话' },
|
|
{ file:'video-booking.html', label:'视频预约' }, { file:'video-success.html', label:'预约成功' },
|
|
{ file:'video-detail-confirming.html', label:'视频待确认' }, { file:'video-detail-pending.html', label:'视频待开始' },
|
|
{ file:'video-detail-done.html', label:'视频已完成' }, { file:'video-detail-cancelled.html', label:'视频已取消' },
|
|
{ file:'video-detail-rejected.html', label:'视频已拒绝' },
|
|
{ file:'video-detail-ongoing.html', label:'视频进行中' },
|
|
{ file:'my-records.html', label:'咨询记录' },
|
|
{ file:'record-detail-rated.html', label:'已评价详情' }, { file:'record-detail-unrated.html', label:'未评价详情' }, { file:'record-detail-timeout.html', label:'已超时详情' },
|
|
{ file:'rate-doctor.html', label:'评价医生' },
|
|
{ file:'end-consult-dialog.html', label:'结束咨询弹窗', dialog:true },
|
|
{ file:'select-report-dialog.html', label:'选择报告弹窗', dialog:true },
|
|
{ file:'consult-flowchart.html', label:'咨询流程图' }
|
|
]},
|
|
{ name:'应急就医', dir:'employee-app/emergency-medical', entry:'index.html', prd:'employee-app/emergency-medical/doc/PRD.md', pages:[
|
|
{ file:'index.html', label:'应急就医主页' },
|
|
{ file:'emergency-chat.html', label:'应急对话' },
|
|
{ file:'resource-map.html', label:'应急资源地图' },
|
|
{ file:'resource-map-clinic.html', label:'地图-医疗点' },
|
|
{ file:'resource-map-aed.html', label:'地图-AED' },
|
|
{ file:'resource-map-ambulance.html', label:'地图-救护车' },
|
|
{ file:'resource-map-kit.html', label:'地图-急救包' },
|
|
{ file:'hospital-detail.html', label:'油田医院详情' },
|
|
{ file:'clinic-detail.html', label:'医疗点详情' },
|
|
{ file:'aed-detail.html', label:'AED详情' },
|
|
{ file:'ambulance-detail.html', label:'救护车详情' },
|
|
{ file:'first-aid-kit-detail.html', label:'急救包详情' },
|
|
{ file:'emergency-tips.html', label:'急救提示书' },
|
|
{ file:'help-records.html', label:'应急求助记录' },
|
|
{ file:'appointment-list.html', label:'大病就医预约' },
|
|
{ file:'appointment-list-done.html', label:'预约-已完成' },
|
|
{ file:'appointment-list-cancelled.html', label:'预约-已取消' },
|
|
{ file:'appointment-detail-pending.html', label:'就医详情-待确认' },
|
|
{ file:'appointment-detail-confirmed.html', label:'就医详情-已确认' },
|
|
{ file:'appointment-detail-done.html', label:'就医详情-已完成' },
|
|
{ file:'appointment-detail-cancelled.html', label:'就医详情-已取消' },
|
|
{ file:'appointment-form.html', label:'发起新预约' },
|
|
{ file:'first-aid-videos.html', label:'急救教学视频' }
|
|
]},
|
|
{ name:'一线医疗', dir:'employee-app/frontline-medical', pages:[] },
|
|
{ name:'健康档案', dir:'employee-app/health-record', pages:[] },
|
|
{ name:'知识普及', dir:'employee-app/knowledge', pages:[] },
|
|
{ name:'个人中心', dir:'employee-app/profile', pages:[] }
|
|
]},
|
|
{ id:'emergency-app', label:'健康应急 APP', icon:'emergency', color:'#ffc069',
|
|
roles:[
|
|
{ role:'咨询专家', id:'expert', modules:[
|
|
{ name:'工作台', dir:'emergency-app/expert/workbench', prd:'emergency-app/expert/doc/PRD.md', pages:[
|
|
{file:'index.html',label:'工作台首页'},{file:'text-chat.html',label:'图文咨询'},
|
|
{file:'text-chat-done.html',label:'图文咨询完成'},
|
|
{file:'text-consult-done.html',label:'咨询完成'},{file:'text-consult-timeout.html',label:'咨询超时'},
|
|
{file:'video-appt.html',label:'视频预约'},
|
|
{file:'video-ongoing.html',label:'视频待开始'},
|
|
{file:'video-in-progress.html',label:'视频进行中'},
|
|
{file:'video-done.html',label:'视频完成'},
|
|
{file:'video-cancelled.html',label:'视频已取消'},{file:'video-rejected.html',label:'视频已拒绝'}
|
|
]},
|
|
{ name:'知识库', dir:'emergency-app/expert/knowledge', pages:[
|
|
{file:'index.html',label:'知识库首页'},{file:'detail.html',label:'知识详情'}
|
|
]},
|
|
{ name:'我的', dir:'emergency-app/expert/profile', pages:[
|
|
{file:'index.html',label:'个人中心'},{file:'edit-profile.html',label:'编辑资料'},
|
|
{file:'edit-diseases.html',label:'擅长疾病'},
|
|
{file:'change-pwd.html',label:'修改密码'},{file:'schedule.html',label:'排班设置'},
|
|
{file:'stats.html',label:'咨询统计'},{file:'reviews.html',label:'我的评价'}
|
|
]}
|
|
]},
|
|
{ role:'咨询小助手', id:'assistant', modules:[
|
|
{ name:'工作台', dir:'emergency-app/assistant/workbench', prd:'emergency-app/assistant/doc/PRD.md', pages:[
|
|
{file:'index.html',label:'工作台首页'},{file:'text-chat.html',label:'图文咨询'},
|
|
{file:'text-chat-done.html',label:'图文咨询完成'},
|
|
{file:'text-consult-done.html',label:'咨询完成'},{file:'text-consult-timeout.html',label:'咨询超时'},
|
|
{file:'employee-profile.html',label:'员工档案'},
|
|
{file:'end-consult-dialog.html',label:'结束咨询弹窗',dialog:true},
|
|
{file:'push-expert.html',label:'推送专家'}
|
|
]},
|
|
{ name:'知识库', dir:'emergency-app/assistant/knowledge', pages:[
|
|
{file:'index.html',label:'知识库首页'},{file:'detail.html',label:'知识详情'}
|
|
]},
|
|
{ name:'我的', dir:'emergency-app/assistant/profile', pages:[
|
|
{file:'index.html',label:'个人中心'},{file:'edit-profile.html',label:'编辑资料'},
|
|
{file:'change-pwd.html',label:'修改密码'}
|
|
] }
|
|
]},
|
|
{ role:'应急操作人员', id:'operator', modules:[
|
|
{name:'工作台',dir:'emergency-app/operator/workbench',pages:[]},
|
|
{name:'知识库',dir:'emergency-app/operator/knowledge',pages:[]},
|
|
{name:'我的',dir:'emergency-app/operator/profile',pages:[]}
|
|
]},
|
|
{ role:'应急工作人员', id:'worker', modules:[
|
|
{name:'工作台',dir:'emergency-app/worker/workbench',pages:[]},
|
|
{name:'知识库',dir:'emergency-app/worker/knowledge',pages:[]},
|
|
{name:'我的',dir:'emergency-app/worker/profile',pages:[]}
|
|
]},
|
|
{ role:'应急驻场人员', id:'onsite', modules:[
|
|
{name:'工作台',dir:'emergency-app/onsite/workbench',pages:[]},
|
|
{name:'知识库',dir:'emergency-app/onsite/knowledge',pages:[]},
|
|
{name:'我的',dir:'emergency-app/onsite/profile',pages:[]}
|
|
]},
|
|
{ role:'管理员', id:'admin', modules:[
|
|
{name:'工作台',dir:'emergency-app/admin/workbench',pages:[]},
|
|
{name:'知识库',dir:'emergency-app/admin/knowledge',pages:[]},
|
|
{name:'我的',dir:'emergency-app/admin/profile',pages:[]}
|
|
]}
|
|
],
|
|
shared:[
|
|
{ name:'AI助手', dir:'emergency-app/ai-assistant', pages:[{file:'index.html',label:'AI助手'}] },
|
|
{ name:'消息', dir:'emergency-app/message', pages:[
|
|
{file:'index.html',label:'消息列表'},{file:'contacts.html',label:'通讯录'},{file:'im-chat.html',label:'聊天'}
|
|
]}
|
|
]
|
|
}
|
|
];
|
|
|
|
/* ===== 渲染逻辑 ===== */
|
|
function countPages(t) {
|
|
if (t.modules) return t.modules.reduce((s, m) => s + m.pages.length, 0);
|
|
let n = 0;
|
|
if (t.roles) t.roles.forEach(r => r.modules.forEach(m => n += m.pages.length));
|
|
if (t.shared) t.shared.forEach(m => n += m.pages.length);
|
|
return n;
|
|
}
|
|
|
|
/* Tab 导航 */
|
|
const tabNav = document.getElementById('tab-nav');
|
|
const tabContents = document.getElementById('tab-contents');
|
|
const totalTabs = SITE_MAP.length + 1; /* +1 for PRD tab */
|
|
SITE_MAP.forEach((t, i) => {
|
|
tabNav.innerHTML += `<div class="tab-nav__item${i===0?' tab-nav__item--active':''}" data-idx="${i}">${ICONS[t.icon]}${t.label}<span class="tab-nav__badge">${countPages(t)}</span></div>`;
|
|
});
|
|
/* PRD Tab */
|
|
const prdTabIdx = SITE_MAP.length;
|
|
tabNav.innerHTML += `<div class="tab-nav__item" data-idx="${prdTabIdx}">${ICONS.prd}产品需求文档</div>`;
|
|
|
|
/* 生成卡片 — 点击卡片跳转主页,点击徽章弹出页面列表 */
|
|
let openPopover = null;
|
|
function cardHTML(mod, uid) {
|
|
const has = mod.pages.length > 0;
|
|
const cls = has ? 'module-card module-card--ready' : 'module-card module-card--empty';
|
|
const mainHref = has ? `${mod.dir}/${mod.entry || 'index.html'}` : '';
|
|
const onclick = has ? `onclick="window.open('${mainHref}','_blank')"` : '';
|
|
|
|
let tagHtml = '';
|
|
if (has) {
|
|
/* 生成悬浮列表 */
|
|
let popItems = mod.pages.map(p => {
|
|
const dcls = p.dialog ? ' page-popover__item--dialog' : '';
|
|
const icon = p.dialog ? ICONS.dialog : ICONS.page;
|
|
return `<a class="page-popover__item${dcls}" href="${mod.dir}/${p.file}" target="_blank">${icon}${p.label}</a>`;
|
|
}).join('');
|
|
tagHtml = `<span class="module-card__tag module-card__tag--ready" data-pop="${uid}" onclick="event.stopPropagation();togglePop('${uid}')">${mod.pages.length} 页</span><div class="page-popover" id="pop-${uid}" onclick="event.stopPropagation()"><div class="page-popover__title">页面列表</div>${popItems}</div>`;
|
|
} else {
|
|
tagHtml = '<span class="module-card__tag module-card__tag--pending">待开发</span>';
|
|
}
|
|
|
|
const body = has ? '' : `<div class="module-card__empty-hint">${ICONS.empty}暂无原型页面</div>`;
|
|
/* PRD 文档链接(右下角) */
|
|
let prdHtml = '';
|
|
if (mod.prd) {
|
|
prdHtml = `<div class="module-card__footer"><a class="module-card__prd" onclick="event.stopPropagation();openMdPreview('${mod.prd}','${mod.name} PRD')">${ICONS.prdSmall}PRD文档</a></div>`;
|
|
}
|
|
return `<div class="${cls}" ${onclick}><div class="module-card__header"><span class="module-card__name">${mod.name}</span>${tagHtml}</div>${body}${prdHtml}</div>`;
|
|
}
|
|
|
|
function togglePop(uid) {
|
|
const el = document.getElementById('pop-' + uid);
|
|
if (openPopover && openPopover !== el) {
|
|
openPopover.classList.remove('page-popover--visible');
|
|
openPopover.closest('.module-card').classList.remove('module-card--pop-open');
|
|
}
|
|
el.classList.toggle('page-popover--visible');
|
|
const card = el.closest('.module-card');
|
|
if (el.classList.contains('page-popover--visible')) {
|
|
card.classList.add('module-card--pop-open');
|
|
openPopover = el;
|
|
} else {
|
|
card.classList.remove('module-card--pop-open');
|
|
openPopover = null;
|
|
}
|
|
}
|
|
document.addEventListener('click', () => {
|
|
if (openPopover) {
|
|
openPopover.closest('.module-card').classList.remove('module-card--pop-open');
|
|
openPopover.classList.remove('page-popover--visible');
|
|
openPopover = null;
|
|
}
|
|
});
|
|
|
|
/* 生成 Tab 内容 */
|
|
let uidCounter = 0;
|
|
SITE_MAP.forEach((t, i) => {
|
|
const div = document.createElement('div');
|
|
div.className = 'tab-content' + (i === 0 ? ' tab-content--active' : '');
|
|
div.dataset.idx = i;
|
|
let html = '';
|
|
if (t.modules) {
|
|
html = '<div class="module-grid">' + t.modules.map(m => cardHTML(m, 'u' + uidCounter++)).join('') + '</div>';
|
|
} else {
|
|
t.roles.forEach(r => {
|
|
const icon = ICONS.role[r.id] || '';
|
|
html += `<div class="role-group"><div class="role-group__title"><span class="role-icon role-icon--${r.id}">${icon}</span>${r.role}</div><div class="module-grid module-grid--center">`;
|
|
html += r.modules.map(m => cardHTML(m, 'u' + uidCounter++)).join('');
|
|
html += '</div></div>';
|
|
});
|
|
html += `<div class="role-group"><div class="role-group__title"><span class="role-icon role-icon--shared">${ICONS.role.shared}</span>全角色共享</div><div class="module-grid module-grid--center">`;
|
|
html += t.shared.map(m => cardHTML(m, 'u' + uidCounter++)).join('');
|
|
html += '</div></div>';
|
|
}
|
|
div.innerHTML = html;
|
|
tabContents.appendChild(div);
|
|
});
|
|
|
|
/* Tab 切换 */
|
|
tabNav.addEventListener('click', e => {
|
|
const item = e.target.closest('.tab-nav__item');
|
|
if (!item) return;
|
|
const idx = item.dataset.idx;
|
|
tabNav.querySelectorAll('.tab-nav__item').forEach(el => el.classList.remove('tab-nav__item--active'));
|
|
tabContents.querySelectorAll('.tab-content').forEach(el => el.classList.remove('tab-content--active'));
|
|
item.classList.add('tab-nav__item--active');
|
|
tabContents.querySelector(`[data-idx="${idx}"]`).classList.add('tab-content--active');
|
|
});
|
|
|
|
/* ===== PRD Tab 内容生成 ===== */
|
|
(function buildPrdTab() {
|
|
const div = document.createElement('div');
|
|
div.className = 'tab-content';
|
|
div.dataset.idx = prdTabIdx;
|
|
let html = '';
|
|
|
|
/* 顶部:共性需求说明 */
|
|
html += `<div class="prd-page__global">
|
|
<div class="prd-global-card" onclick="openMdPreview('共性需求说明.md','共性需求说明')">
|
|
<div class="prd-global-card__icon">
|
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M6 2h9l5 5v15H6V2z" stroke="#fff" stroke-width="1.8"/><path d="M15 2v5h5" stroke="#fff" stroke-width="1.8"/><line x1="9" y1="11" x2="17" y2="11" stroke="#fff" stroke-width="1.4" stroke-linecap="round"/><line x1="9" y1="14.5" x2="15" y2="14.5" stroke="#fff" stroke-width="1.4" stroke-linecap="round"/><line x1="9" y1="18" x2="13" y2="18" stroke="#fff" stroke-width="1.4" stroke-linecap="round"/></svg>
|
|
</div>
|
|
<div class="prd-global-card__info">
|
|
<div class="prd-global-card__title">共性需求说明</div>
|
|
<div class="prd-global-card__desc">全平台通用的业务规则、交互规范和共性功能说明</div>
|
|
</div>
|
|
<span class="prd-item__status prd-item__status--ready">查看</span>
|
|
</div>
|
|
</div>`;
|
|
|
|
/* 收集所有模块的 PRD 信息 */
|
|
function collectModules(siteEntry) {
|
|
const result = [];
|
|
if (siteEntry.modules) {
|
|
siteEntry.modules.forEach(m => {
|
|
result.push({ name: m.name, dir: m.dir, prd: m.prd || null });
|
|
});
|
|
}
|
|
if (siteEntry.roles) {
|
|
siteEntry.roles.forEach(r => {
|
|
r.modules.forEach(m => {
|
|
result.push({ name: r.role + ' - ' + m.name, dir: m.dir, prd: m.prd || null });
|
|
});
|
|
});
|
|
}
|
|
if (siteEntry.shared) {
|
|
siteEntry.shared.forEach(m => {
|
|
result.push({ name: '共享 - ' + m.name, dir: m.dir, prd: m.prd || null });
|
|
});
|
|
}
|
|
return result;
|
|
}
|
|
|
|
SITE_MAP.forEach(t => {
|
|
const mods = collectModules(t);
|
|
const readyCount = mods.filter(m => m.prd).length;
|
|
html += `<div class="prd-section">
|
|
<div class="prd-section__title">${ICONS[t.icon] || ''}${t.label}<span class="tab-nav__badge" style="margin-left:6px">${readyCount}/${mods.length}</span></div>
|
|
<div class="prd-grid">`;
|
|
|
|
mods.forEach(m => {
|
|
if (m.prd) {
|
|
html += `<div class="prd-item" onclick="openMdPreview('${m.prd}','${m.name} PRD')">
|
|
<div class="prd-item__icon prd-item__icon--ready">📄</div>
|
|
<div class="prd-item__info">
|
|
<div class="prd-item__name">${m.name} PRD</div>
|
|
<div class="prd-item__path">${m.prd}</div>
|
|
</div>
|
|
<span class="prd-item__status prd-item__status--ready">查看</span>
|
|
</div>`;
|
|
} else {
|
|
html += `<div class="prd-item prd-item--disabled">
|
|
<div class="prd-item__icon prd-item__icon--empty">📄</div>
|
|
<div class="prd-item__info">
|
|
<div class="prd-item__name">${m.name} PRD</div>
|
|
<div class="prd-item__path">${m.dir}/doc/PRD.md</div>
|
|
</div>
|
|
<span class="prd-item__status prd-item__status--empty">待编写</span>
|
|
</div>`;
|
|
}
|
|
});
|
|
|
|
html += '</div></div>';
|
|
});
|
|
|
|
div.innerHTML = html;
|
|
tabContents.appendChild(div);
|
|
})();
|
|
|
|
/* ===== Markdown 预览(新标签页打开) ===== */
|
|
function openMdPreview(filePath, title) {
|
|
window.open('md-viewer.html?file=' + encodeURIComponent(filePath) + '&title=' + encodeURIComponent(title || ''), '_blank');
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |