refactor: 优化导航页UI交互,卡片点击跳转主页+徽章悬浮页面列表

- 去掉顶部冗余统计徽章,Tab导航移入Header居中显示
- 模块卡片改为点击跳转主页,点击页数徽章弹出悬浮页面列表
- 已完成模块卡片添加绿色边框呼吸灯动画
- 健康应急APP角色分组标题与卡片居中对齐
- 同步更新项目背景.md导航页交互说明

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
冯普
2026-04-09 12:39:47 +08:00
co-authored by Claude Opus 4.6
parent 006b5f0d5c
commit fd39307aaf
2 changed files with 201 additions and 189 deletions
+198 -188
View File
@@ -13,6 +13,9 @@
--warning: #FAAD14;
--danger: #FF4D4F;
--purple: #722ED1;
--green: #52C41A;
--green-light: #f6ffed;
--green-border: #b7eb8f;
--text-primary: #1a1a2e;
--text-secondary: #5a607f;
--text-placeholder: #999999;
@@ -22,7 +25,6 @@
--radius-sm: 6px;
--radius-md: 10px;
--radius-lg: 16px;
--radius-xl: 20px;
--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);
@@ -31,27 +33,20 @@
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: 44px 48px 28px; overflow: hidden; }
.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; }
.header__top { display: flex; align-items: flex-start; justify-content: space-between; }
.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; font-weight: 400; }
.header__stats { display: flex; gap: 14px; margin-top: 22px; flex-wrap: wrap; }
.stat-badge { background: rgba(255,255,255,0.15); backdrop-filter: blur(10px); border: 1px solid rgba(255,255,255,0.2); border-radius: 24px; padding: 8px 20px; font-size: 13px; font-weight: 500; display: flex; align-items: center; gap: 8px; transition: background .2s; }
.stat-badge:hover { background: rgba(255,255,255,0.25); }
.stat-badge__dot { width: 10px; height: 10px; border-radius: 50%; box-shadow: 0 0 6px currentColor; }
.stat-badge__dot--web { background: #69b1ff; color: #69b1ff; }
.stat-badge__dot--app { background: #95de64; color: #95de64; }
.stat-badge__dot--emergency { background: #ffc069; color: #ffc069; }
/* ===== Tab 导航 ===== */
.tab-nav { display: flex; align-items: center; gap: 6px; background: var(--card-bg); padding: 12px 48px; position: sticky; top: 0; z-index: 10; box-shadow: 0 2px 12px rgba(0,0,0,0.06); }
.tab-nav__item { padding: 9px 22px; font-size: 14px; font-weight: 500; color: var(--text-secondary); cursor: pointer; border-radius: 24px; transition: all .25s ease; user-select: none; display: flex; align-items: center; gap: 8px; border: 1.5px solid transparent; }
.tab-nav__item:hover { color: var(--primary); background: var(--primary-light); }
.tab-nav__item--active { color: #fff; background: var(--primary); border-color: var(--primary); box-shadow: 0 2px 8px rgba(22,119,255,0.3); }
.tab-nav__item--active .tab-nav__badge { background: rgba(255,255,255,0.25); color: #fff; }
.tab-nav__badge { font-size: 11px; padding: 2px 8px; border-radius: 10px; background: var(--primary-light); color: var(--primary); font-weight: 600; transition: all .25s; }
.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; }
/* ===== 内容区 ===== */
@@ -61,13 +56,14 @@ body { background: var(--background); font-family: -apple-system, BlinkMacSystem
@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(360px, 1fr)); gap: 20px; }
.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; }
.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-group__title:first-child { margin-top: 0; }
.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); }
@@ -77,185 +73,173 @@ body { background: var(--background); font-family: -apple-system, BlinkMacSystem
.role-icon--admin { background: linear-gradient(135deg, #eb2f96, #ff85c0); }
.role-icon--shared { background: linear-gradient(135deg, #13c2c2, #5cdbd3); }
/* ===== 模块卡片 ===== */
.module-card { position: relative; background: var(--card-bg); border-radius: var(--radius-lg); box-shadow: var(--shadow-sm); padding: 22px 22px 22px 26px; transition: all .25s ease; border: 1px solid var(--border); overflow: hidden; }
.module-card::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; border-radius: 4px 0 0 4px; background: var(--primary); transition: width .2s; }
.module-card:hover { box-shadow: var(--shadow-lg); transform: translateY(-3px); border-color: rgba(22,119,255,0.2); }
.module-card:hover::before { width: 5px; }
.module-card--empty { opacity: 0.6; border-style: dashed; border-color: #d0d5dd; }
.module-card--empty::before { background: #d0d5dd; }
.module-card--empty:hover { opacity: 0.75; transform: translateY(-1px); box-shadow: var(--shadow-md); border-color: #d0d5dd; }
.module-card__header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 14px; }
.module-card__name { font-size: 15px; font-weight: 700; color: var(--text-primary); }
.module-card__count { font-size: 12px; color: var(--text-secondary); margin-left: 8px; font-weight: 400; }
.module-card__tag { font-size: 11px; padding: 3px 10px; border-radius: 12px; font-weight: 600; letter-spacing: 0.3px; }
.module-card__tag--ready { background: #f6ffed; color: #389e0d; border: 1px solid #b7eb8f; }
.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); }
.module-card__empty-hint svg { flex-shrink: 0; }
/* ===== 呼吸灯动画 ===== */
@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); }
}
/* ===== 页面链接 ===== */
.page-links { display: flex; flex-wrap: wrap; gap: 8px; }
.page-link { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; font-weight: 500; color: var(--primary-dark); background: linear-gradient(135deg, #e8f4ff, #f0f7ff); padding: 5px 14px; border-radius: 16px; text-decoration: none; transition: all .2s ease; border: 1px solid rgba(22,119,255,0.12); }
.page-link:hover { background: linear-gradient(135deg, #bae0ff, #d6ebff); border-color: rgba(22,119,255,0.25); transform: translateY(-1px); box-shadow: 0 2px 6px rgba(22,119,255,0.12); }
.page-link svg { flex-shrink: 0; }
.page-link--dialog { color: #ad4e00; background: linear-gradient(135deg, #fff7e6, #fff9ed); border-color: rgba(250,173,20,0.2); }
.page-link--dialog:hover { background: linear-gradient(135deg, #ffe7ba, #fff1cc); border-color: rgba(250,173,20,0.35); box-shadow: 0 2px 6px rgba(250,173,20,0.15); }
/* ===== 模块卡片 ===== */
.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; }
</style>
</head>
<body>
<div class="header">
<div class="header__inner">
<div class="header__top">
<div>
<div class="header__title">健康长庆升级 · 高保真交互原型</div>
<div class="header__sub">点击模块卡片中的页面链接,即可跳转预览对应原型</div>
</div>
</div>
<div class="header__stats" id="header-stats"></div>
<div class="header__title">健康长庆升级 · 高保真交互原型</div>
<div class="header__sub">点击模块卡片跳转至对应模块主页,点击页数徽章查看全部页面</div>
</div>
<div class="tab-nav" id="tab-nav"></div>
</div>
<div class="tab-nav" id="tab-nav"></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="12" height="12" 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="12" height="12" 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>',
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>',
role: { expert: '👨‍⚕', assistant: '🤖', operator: '📋', worker: '👷', onsite: '🏥', admin: '⚙', shared: '🔗' }
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', pages: [] },
{ name: '应急就医', dir: 'web-admin/emergency-dispatch', pages: [] },
{ 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', pages: [
{ file: 'index.html', label: '咨询首页' },
{ file: 'expert-list.html', label: '专家列表' },
{ file: 'expert-profile.html', label: '专家主页' },
{ file: 'find-expert.html', label: '找专家' },
{ file: 'text-chat.html', label: '图文咨询' },
{ file: 'video-booking.html', label: '视频预约' },
{ file: 'video-success.html', label: '预约成功' },
{ file: 'expert-reviews.html', label: '专家评价' },
{ file: 'hospital-detail.html', label: '医院详情' },
{ file: 'my-records.html', label: '咨询记录' },
{ file: 'record-detail.html', label: '记录详情' },
{ file: 'rate-doctor.html', label: '评价医生' },
{ file: 'assistant-chat.html', label: '小助手对话' },
{ file: 'consult-notice-dialog.html', label: '咨询须知弹窗', dialog: true },
{ file: 'end-consult-dialog.html', label: '结束咨询弹窗', dialog: true },
{ file: 'select-person-dialog.html', label: '选择就诊人弹窗', dialog: true },
{ file: 'select-report-dialog.html', label: '选择报告弹窗', dialog: true },
{ file: 'rate-dialog.html', label: '评价弹窗', dialog: true }
] },
{ name: '应急就医', dir: 'employee-app/emergency-medical', pages: [] },
{ 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', pages: [
{ file: 'index.html', label: '工作台首页' }, { file: 'text-chat.html', label: '图文咨询' },
{ file: 'text-consult-done.html', label: '咨询完成' }, { file: 'video-appt.html', label: '视频预约' },
{ file: 'video-call.html', label: '视频通话' }, { file: 'video-done.html', label: '视频完成' },
{ file: 'video-ongoing.html', label: '视频进行中' }, { file: 'employee-profile.html', label: '员工档案' }
{ 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', pages:[] },
{ name:'应急就医', dir:'web-admin/emergency-dispatch', pages:[] },
{ 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', pages:[
{ file:'index.html', label:'咨询首页' }, { file:'expert-list.html', label:'专家列表' },
{ file:'expert-profile.html', label:'专家主页' }, { file:'find-expert.html', label:'找专家' },
{ file:'text-chat.html', label:'图文咨询' }, { file:'video-booking.html', label:'视频预约' },
{ file:'video-success.html', label:'预约成功' }, { file:'expert-reviews.html', label:'专家评价' },
{ file:'hospital-detail.html', label:'医院详情' }, { file:'my-records.html', label:'咨询记录' },
{ file:'record-detail.html', label:'记录详情' }, { file:'rate-doctor.html', label:'评价医生' },
{ file:'assistant-chat.html', label:'小助手对话' },
{ file:'consult-notice-dialog.html', label:'咨询须知弹窗', dialog:true },
{ file:'end-consult-dialog.html', label:'结束咨询弹窗', dialog:true },
{ file:'select-person-dialog.html', label:'选择就诊人弹窗', dialog:true },
{ file:'select-report-dialog.html', label:'选择报告弹窗', dialog:true },
{ file:'rate-dialog.html', label:'评价弹窗', dialog:true }
]},
{ name:'应急就医', dir:'employee-app/emergency-medical', pages:[] },
{ 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', pages:[
{file:'index.html',label:'工作台首页'},{file:'text-chat.html',label:'图文咨询'},
{file:'text-consult-done.html',label:'咨询完成'},{file:'video-appt.html',label:'视频预约'},
{file:'video-call.html',label:'视频通话'},{file:'video-done.html',label:'视频完成'},
{file:'video-ongoing.html',label:'视频进行中'},{file:'employee-profile.html',label:'员工档案'}
]},
{ name: '知识库', dir: 'emergency-app/expert/knowledge', pages: [
{ file: 'index.html', label: '知识库首页' }, { file: 'detail.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: 'change-pwd.html', label: '修改密码' }, { file: 'schedule.html', label: '排班设置' },
{ file: 'stats.html', label: '咨询统计' }, { file: 'reviews.html', label: '我的评价' }
{ name:'我的', dir:'emergency-app/expert/profile', pages:[
{file:'index.html',label:'个人中心'},{file:'edit-profile.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', pages: [
{ file: 'index.html', label: '工作台首页' }, { file: 'text-chat.html', label: '图文咨询' },
{ file: 'consult-done.html', label: '咨询完成' }, { file: 'employee-profile.html', label: '员工档案' },
{ file: 'end-consult-dialog.html', label: '结束咨询弹窗', dialog: true },
{ file: 'push-expert.html', label: '推送专家' }
{ role:'咨询小助手', id:'assistant', modules:[
{ name:'工作台', dir:'emergency-app/assistant/workbench', pages:[
{file:'index.html',label:'工作台首页'},{file:'text-chat.html',label:'图文咨询'},
{file:'consult-done.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: [] },
{ name: '我的', dir: 'emergency-app/assistant/profile', pages: [] }
{ name:'知识库', dir:'emergency-app/assistant/knowledge', pages:[] },
{ name:'我的', dir:'emergency-app/assistant/profile', pages:[] }
]},
{ 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:'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:'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:'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: [] }
{ 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: '聊天' }
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;
@@ -264,13 +248,6 @@ function countPages(t) {
return n;
}
/* 头部统计 */
const statsEl = document.getElementById('header-stats');
const dotCls = ['web', 'app', 'emergency'];
SITE_MAP.forEach((t, i) => {
statsEl.innerHTML += `<span class="stat-badge"><span class="stat-badge__dot stat-badge__dot--${dotCls[i]}"></span>${t.label}${countPages(t)} 页</span>`;
});
/* Tab 导航 */
const tabNav = document.getElementById('tab-nav');
const tabContents = document.getElementById('tab-contents');
@@ -278,40 +255,73 @@ 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>`;
});
/* 生成卡片 */
function cardHTML(mod) {
/* 生成卡片 — 点击卡片跳转主页,点击徽章弹出页面列表 */
let openPopover = null;
function cardHTML(mod, uid) {
const has = mod.pages.length > 0;
const tag = has
? `<span class="module-card__tag module-card__tag--ready">${mod.pages.length} 页</span>`
: '<span class="module-card__tag module-card__tag--pending">待开发</span>';
let body = '';
const cls = has ? 'module-card module-card--ready' : 'module-card module-card--empty';
const mainHref = has ? `${mod.dir}/index.html` : '';
const onclick = has ? `onclick="window.open('${mainHref}','_blank')"` : '';
let tagHtml = '';
if (has) {
body = '<div class="page-links">' + mod.pages.map(p =>
`<a class="page-link${p.dialog?' page-link--dialog':''}" href="${mod.dir}/${p.file}" target="_blank">${p.dialog ? ICONS.dialog : ICONS.page}${p.label}</a>`
).join('') + '</div>';
/* 生成悬浮列表 */
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 {
body = `<div class="module-card__empty-hint">${ICONS.empty}暂无原型页面</div>`;
tagHtml = '<span class="module-card__tag module-card__tag--pending">待开发</span>';
}
return `<div class="module-card${has?'':' module-card--empty'}"><div class="module-card__header"><span class="module-card__name">${mod.name}</span>${tag}</div>${body}</div>`;
const body = has ? '' : `<div class="module-card__empty-hint">${ICONS.empty}暂无原型页面</div>`;
return `<div class="${cls}" ${onclick}><div class="module-card__header"><span class="module-card__name">${mod.name}</span>${tagHtml}</div>${body}</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)).join('') + '</div>';
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">`;
html += r.modules.map(m => cardHTML({ ...m, name: m.name })).join('');
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">`;
html += t.shared.map(m => cardHTML(m)).join('');
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;
+3 -1
View File
@@ -29,7 +29,9 @@ prototype-user-app/
根目录 `index.html` 作为项目统一入口,部署到服务器后供研发人员浏览所有原型页面。
- 通过 Tab 切换三大终端(Web 管理端 / 员工端 APP / 健康应急 APP
- 以模块卡片展示各业务模块,卡片内列出该模块所有原型页面的跳转链接
- 以模块卡片展示各业务模块,点击卡片跳转至该模块主页(index.html)
- 点击卡片右上角页数徽章,悬浮展示该模块所有页面和弹窗的跳转链接
- 已有原型的模块卡片带绿色边框呼吸灯动画,待开发模块为虚线灰色卡片
- 数据驱动:所有模块和页面信息维护在 `SITE_MAP` JS 对象中
- **新增原型页面时,必须同步在 `index.html``SITE_MAP` 中添加对应条目**