feat: 新增对话消息模块及通讯录功能,更新小助手导航栏

- 新增对话消息主页面(chat-message.html),IM风格左右分栏,支持与内部人员即时通讯
- 新增通讯录弹窗(contacts-dialog.html),按角色分类显示差异化附加信息
- 所有小助手页面顶部导航栏增加"对话消息"链接
- 同步更新CHANGELOG.md和PRD.md文档
- 导航首页增加小助手模块卡片配置

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-10 17:56:02 +08:00
co-authored by Claude Opus 4.6
parent acf8d99d6a
commit 828ce436e1
17 changed files with 2846 additions and 1 deletions
+15 -1
View File
@@ -178,7 +178,7 @@ const SITE_MAP = [
{ 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:[
{ 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:'history-expert-detail.html', label:'专家对话详情' },
{ file:'history-assistant.html', label:'小助手咨询记录' },
@@ -202,6 +202,20 @@ const SITE_MAP = [
{ 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:'employee-profile-dialog.html', label:'咨询人档案弹窗', dialog:true },
{ file:'select-expert-dialog.html', label:'选择专家弹窗', dialog:true },
{ file:'history-consult.html', label:'历史咨询' },
{ file:'chat-detail-dialog.html', label:'对话详情弹窗', dialog:true },
{ file:'checkup-standard.html', label:'体检标准化' },
{ file:'item-detail-dialog.html', label:'项目明细弹窗', dialog:true },
{ file:'sms-send.html', label:'短信发送' },
{ file:'send-dialog.html', label:'新建短信弹窗', dialog:true },
{ file:'sms-detail-dialog.html', label:'发送详情弹窗', dialog:true },
{ file:'consult-settle.html', label:'咨询结算' },
{ file:'report-detail-dialog.html', label:'报表详情弹窗', dialog:true }
]},
{ name:'应急就医', dir:'web-admin/emergency-dispatch', pages:[] },
{ name:'一线医疗', dir:'web-admin/frontline-medical', pages:[] }
]},
@@ -0,0 +1,94 @@
<!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>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;}
:root{--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;--text-primary:#333;--text-secondary:#666;--border:#E8E8E8;--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--radius-sm:4px;--radius-md:8px;--shadow-sm:0 1px 4px rgba(0,0,0,0.08);}
.dialog{max-width:680px;margin:0 auto;background:#fff;min-height:100vh;}
.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px;border-bottom:1px solid var(--border);position:sticky;top:0;background:#fff;z-index:10;}
.dialog-title{font-size:var(--font-lg);font-weight:600;}
.dialog-close{background:none;border:none;font-size:20px;cursor:pointer;color:var(--text-secondary);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-sm);}
.dialog-close:hover{background:#F5F5F5;color:var(--text-primary);}
/* 咨询信息摘要 */
.consult-summary{padding:16px 24px;background:#FAFAFA;border-bottom:1px solid var(--border);display:grid;grid-template-columns:repeat(3,1fr);gap:12px;}
.summary-item{display:flex;flex-direction:column;gap:4px;}
.summary-item__label{font-size:var(--font-xs);color:var(--text-secondary);}
.summary-item__value{font-size:var(--font-sm);color:var(--text-primary);font-weight:500;}
.tag{display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:var(--font-xs);}
.tag-gray{background:#F5F5F5;color:var(--text-secondary);}
.tag-blue{background:var(--primary-light);color:var(--primary);}
/* 对话内容 */
.chat-body{padding:24px;display:flex;flex-direction:column;gap:16px;}
.system-msg{text-align:center;font-size:var(--font-xs);color:#bbb;padding:4px 0;}
.msg{display:flex;gap:12px;align-items:flex-start;}
.msg.right{flex-direction:row-reverse;}
.msg__avatar{width:36px;height:36px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:var(--font-sm);font-weight:600;}
.msg__avatar.user{background:var(--primary-light);color:var(--primary);}
.msg__avatar.bot{background:#F6FFED;color:var(--success);}
.msg__content{max-width:70%;}
.msg__name{font-size:var(--font-xs);color:var(--text-secondary);margin-bottom:4px;}
.msg.right .msg__name{text-align:right;}
.msg__bubble{background:#F5F7FA;border-radius:var(--radius-md);padding:12px 16px;font-size:var(--font-sm);line-height:1.7;word-break:break-word;}
.msg.right .msg__bubble{background:var(--primary-light);}
.msg__time{font-size:var(--font-xs);color:#bbb;margin-top:4px;}
.msg.right .msg__time{text-align:right;}
.transfer-notice{background:#FFF7E6;border:1px solid #FFD591;border-radius:var(--radius-sm);padding:10px 16px;font-size:var(--font-sm);color:var(--warning);text-align:center;}
</style>
</head>
<body>
<div class="dialog">
<div class="dialog-header">
<div class="dialog-title">对话详情</div>
</div>
<div class="consult-summary">
<div class="summary-item"><span class="summary-item__label">咨询单号</span><span class="summary-item__value">AS20260409002</span></div>
<div class="summary-item"><span class="summary-item__label">员工姓名</span><span class="summary-item__value">李明(CQ002571</span></div>
<div class="summary-item"><span class="summary-item__label">所属单位</span><span class="summary-item__value">采油二厂</span></div>
<div class="summary-item"><span class="summary-item__label">发起时间</span><span class="summary-item__value">2026-04-09 09:45</span></div>
<div class="summary-item"><span class="summary-item__label">咨询时长</span><span class="summary-item__value">15分钟</span></div>
<div class="summary-item"><span class="summary-item__label">咨询状态</span><span class="summary-item__value"><span class="tag tag-blue">进行中</span></span></div>
</div>
<div class="chat-body">
<div class="system-msg">会话开始 · 2026-04-09 09:45</div>
<div class="msg">
<div class="msg__avatar bot"></div>
<div class="msg__content">
<div class="msg__name">健康小助手</div>
<div class="msg__bubble">您好!我是健康咨询小助手,很高兴为您服务。请问您有什么健康问题需要咨询?</div>
<div class="msg__time">09:45</div>
</div>
</div>
<div class="msg right">
<div class="msg__avatar user"></div>
<div class="msg__content">
<div class="msg__name">李明(员工)</div>
<div class="msg__bubble">我体检报告显示空腹血糖6.8,这是糖尿病吗?</div>
<div class="msg__time">09:46</div>
</div>
</div>
<div class="msg">
<div class="msg__avatar bot"></div>
<div class="msg__content">
<div class="msg__name">健康小助手</div>
<div class="msg__bubble">您好!空腹血糖6.8 mmol/L属于糖尿病前期(正常值3.9-6.1,6.1-7.0为糖前期,≥7.0为糖尿病)。<br><br>建议您:<br>1. 不要过于担心,糖尿病前期可以逆转<br>2. 控制饮食,减少精制碳水摄入<br>3. 每天至少30分钟中等强度运动<br>4. 建议咨询内分泌科专家进一步评估</div>
<div class="msg__time">09:47</div>
</div>
</div>
<div class="msg right">
<div class="msg__avatar user"></div>
<div class="msg__content">
<div class="msg__name">李明(员工)</div>
<div class="msg__bubble">能帮我推荐一个内分泌科的专家吗?</div>
<div class="msg__time">09:58</div>
</div>
</div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,327 @@
<!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>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;min-width:1280px;}
:root{--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;--text-primary:#333;--text-secondary:#666;--border:#E8E8E8;--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--font-xl:20px;--radius-sm:4px;--radius-md:8px;--shadow-sm:0 1px 4px rgba(0,0,0,0.08);}
/* ===== 顶部栏 ===== */
.top-bar{display:flex;align-items:center;height:56px;background:#001529;padding:0 24px;position:fixed;top:0;left:0;right:0;z-index:100;}
.top-bar__logo{display:flex;align-items:center;gap:8px;color:#fff;font-size:var(--font-lg);font-weight:600;width:240px;flex-shrink:0;white-space:nowrap;}
.top-bar__logo svg{width:28px;height:28px;}
.top-bar__nav{display:flex;align-items:center;gap:4px;flex:1;}
.top-bar__nav a{color:rgba(255,255,255,0.65);text-decoration:none;padding:6px 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);transition:all .2s;}
.top-bar__nav a:hover{color:#fff;background:rgba(255,255,255,0.08);}
.top-bar__nav a.active{color:#fff;background:var(--primary);}
.top-bar__right{display:flex;align-items:center;gap:16px;font-size:var(--font-sm);margin-left:auto;}
.btn-back{color:rgba(255,255,255,0.65);cursor:pointer;display:flex;align-items:center;gap:4px;text-decoration:none;}
.btn-back:hover{color:#fff;}
.avatar{width:32px;height:32px;border-radius:50%;background:var(--success);display:flex;align-items:center;justify-content:center;color:#fff;font-size:var(--font-sm);}
/* ===== 主内容区 ===== */
.main{margin-top:56px;height:calc(100vh - 56px);display:flex;overflow:hidden;}
/* ===== 左侧消息列表 ===== */
.msg-list{width:320px;background:#fff;border-right:1px solid var(--border);display:flex;flex-direction:column;flex-shrink:0;}
.msg-list__header{padding:16px;border-bottom:1px solid var(--border);display:flex;gap:8px;align-items:center;}
.msg-list__search{flex:1;height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px 0 36px;font-size:var(--font-sm);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='none'%3E%3Ccircle cx='6' cy='6' r='4' stroke='%23999' stroke-width='1.4'/%3E%3Cpath d='M10 10l2.5 2.5' stroke='%23999' stroke-width='1.4' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat 12px center;}
.msg-list__search:focus{border-color:var(--primary);}
.btn-contacts{height:36px;padding:0 14px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:1px solid var(--primary);background:#fff;color:var(--primary);display:inline-flex;align-items:center;gap:6px;white-space:nowrap;transition:all .2s;}
.btn-contacts:hover{background:var(--primary);color:#fff;}
.btn-contacts svg{width:16px;height:16px;}
.msg-list__body{flex:1;overflow-y:auto;}
.msg-item{display:flex;gap:12px;padding:14px 16px;cursor:pointer;border-bottom:1px solid #F5F5F5;transition:background .15s;}
.msg-item:hover{background:#FAFAFA;}
.msg-item.active{background:var(--primary-light);}
.msg-avatar{width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:var(--font-sm);font-weight:600;flex-shrink:0;}
.msg-avatar--expert{background:#F6FFED;color:var(--success);}
.msg-avatar--operator{background:var(--primary-light);color:var(--primary);}
.msg-avatar--professional{background:#FFF7E6;color:var(--warning);}
.msg-avatar--onsite{background:#F9F0FF;color:#722ED1;}
.msg-avatar--admin{background:#FFF1F0;color:var(--danger);}
.msg-info{flex:1;min-width:0;}
.msg-info__top{display:flex;justify-content:space-between;align-items:center;}
.msg-info__name{font-size:var(--font-sm);font-weight:500;color:var(--text-primary);}
.msg-info__time{font-size:var(--font-xs);color:#bbb;}
.msg-info__mid{display:flex;align-items:center;gap:6px;margin-top:3px;}
.role-tag{font-size:10px;padding:1px 6px;border-radius:3px;white-space:nowrap;}
.role-tag--expert{background:#F6FFED;color:var(--success);}
.role-tag--operator{background:var(--primary-light);color:var(--primary);}
.role-tag--professional{background:#FFF7E6;color:var(--warning);}
.role-tag--onsite{background:#F9F0FF;color:#722ED1;}
.role-tag--admin{background:#FFF1F0;color:var(--danger);}
.msg-info__preview{font-size:var(--font-xs);color:var(--text-secondary);margin-top:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.msg-badge{width:18px;height:18px;border-radius:50%;background:var(--danger);color:#fff;font-size:10px;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:2px;}
/* ===== 右侧聊天区 ===== */
.chat-area{flex:1;display:flex;flex-direction:column;background:#F5F7FA;}
.chat-header{height:56px;background:#fff;border-bottom:1px solid var(--border);display:flex;align-items:center;padding:0 20px;flex-shrink:0;gap:8px;}
.chat-header__name{font-size:var(--font-base);font-weight:600;}
.chat-header__role{font-size:var(--font-xs);padding:2px 8px;border-radius:10px;}
.chat-header__detail{font-size:var(--font-xs);color:var(--text-secondary);margin-left:4px;}
.chat-body{flex:1;overflow-y:auto;padding:20px;display:flex;flex-direction:column;gap:16px;}
.system-msg{text-align:center;font-size:var(--font-xs);color:#bbb;padding:4px 0;}
.bubble{display:flex;gap:12px;align-items:flex-start;}
.bubble.right{flex-direction:row-reverse;}
.bubble__avatar{width:36px;height:36px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:var(--font-sm);font-weight:600;background:var(--primary-light);color:var(--primary);}
.bubble__avatar.me{background:#F6FFED;color:var(--success);}
.bubble__content{max-width:60%;}
.bubble__name{font-size:var(--font-xs);color:var(--text-secondary);margin-bottom:4px;}
.bubble.right .bubble__name{text-align:right;}
.bubble__text{background:#fff;border-radius:var(--radius-md);padding:12px 16px;font-size:var(--font-sm);line-height:1.7;box-shadow:var(--shadow-sm);word-break:break-word;}
.bubble.right .bubble__text{background:var(--success);color:#fff;}
.bubble__time{font-size:var(--font-xs);color:#bbb;margin-top:4px;}
.bubble.right .bubble__time{text-align:right;}
.chat-footer{background:#fff;border-top:1px solid var(--border);padding:12px 20px;flex-shrink:0;}
.chat-input-wrap{display:flex;gap:8px;align-items:flex-end;}
.chat-input{flex:1;min-height:40px;max-height:120px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:8px 12px;font-size:var(--font-sm);outline:none;resize:none;font-family:inherit;line-height:1.6;}
.chat-input:focus{border-color:var(--primary);}
.btn{height:36px;padding:0 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;}
.btn-primary{background:var(--primary);color:#fff;}
.btn-primary:hover{background:#40a9ff;}
/* 空状态 */
.chat-empty{flex:1;display:flex;align-items:center;justify-content:center;flex-direction:column;gap:12px;color:#bbb;}
.chat-empty svg{width:64px;height:64px;opacity:0.3;}
/* 弹窗 */
.overlay-modal{display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.45);z-index:1000;align-items:center;justify-content:center;}
.overlay-modal.open{display:flex;}
.overlay-modal__box{background:#fff;border-radius:var(--radius-md);overflow:hidden;box-shadow:0 4px 16px rgba(0,0,0,0.15);position:relative;max-height:90vh;display:flex;flex-direction:column;}
.overlay-modal__close{position:absolute;top:12px;right:12px;width:32px;height:32px;border-radius:50%;background:rgba(0,0,0,0.04);border:none;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#999;z-index:10;transition:all .15s;}
.overlay-modal__close:hover{background:rgba(0,0,0,0.08);color:#333;}
.overlay-modal iframe{border:none;display:block;}
</style>
</head>
<body>
<!-- ===== 顶部栏 ===== -->
<div class="top-bar">
<div class="top-bar__logo">
<svg viewBox="0 0 28 28" fill="none"><rect width="28" height="28" rx="6" fill="#52C41A"/><path d="M9 14.5l3 3 7-7" stroke="#fff" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
专家咨询–小助手
</div>
<nav class="top-bar__nav">
<a href="current-consult.html">当前咨询</a>
<a href="chat-message.html" class="active">对话消息</a>
<a href="history-consult.html">历史咨询</a>
<a href="checkup-standard.html">体检标准化</a>
<a href="sms-send.html">短信发送</a>
<a href="consult-settle.html">咨询结算</a>
</nav>
<div class="top-bar__right">
<a class="btn-back" href="../../index.html">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
返回首页
</a>
<div class="avatar"></div>
<span style="color:rgba(255,255,255,0.65);">健康小助手 ▾</span>
</div>
</div>
<!-- ===== 主内容区 ===== -->
<main class="main">
<!-- 左侧:消息列表 -->
<div class="msg-list">
<div class="msg-list__header">
<input class="msg-list__search" type="text" placeholder="搜索联系人">
<!-- [交互] 点击打开通讯录弹窗 -->
<button class="btn-contacts" onclick="openOverlay('contacts-dialog.html',640,560)">
<svg viewBox="0 0 16 16" fill="none"><path d="M2 3h12v10H2z" stroke="currentColor" stroke-width="1.2" stroke-linejoin="round"/><circle cx="7" cy="7" r="2" stroke="currentColor" stroke-width="1.2"/><path d="M4 12c0-1.7 1.3-3 3-3s3 1.3 3 3" stroke="currentColor" stroke-width="1.2"/><path d="M13 5h1M13 8h1M13 11h1" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>
通讯录
</button>
</div>
<div class="msg-list__body" id="msgListBody">
<!-- [交互] 点击切换右侧对话内容 -->
<div class="msg-item active" onclick="selectMsg(this,0)">
<div class="msg-avatar msg-avatar--expert"></div>
<div class="msg-info">
<div class="msg-info__top">
<span class="msg-info__name">陈医生</span>
<span class="msg-info__time">10:45</span>
</div>
<div class="msg-info__mid"><span class="role-tag role-tag--expert">咨询专家</span></div>
<div class="msg-info__preview">李明的血糖指标我看了,建议做糖耐量检测</div>
</div>
<div class="msg-badge">1</div>
</div>
<div class="msg-item" onclick="selectMsg(this,1)">
<div class="msg-avatar msg-avatar--operator"></div>
<div class="msg-info">
<div class="msg-info__top">
<span class="msg-info__name">周丽</span>
<span class="msg-info__time">10:20</span>
</div>
<div class="msg-info__mid"><span class="role-tag role-tag--operator">操作人员</span></div>
<div class="msg-info__preview">今天下午的体检安排已经更新了</div>
</div>
</div>
<div class="msg-item" onclick="selectMsg(this,2)">
<div class="msg-avatar msg-avatar--professional"></div>
<div class="msg-info">
<div class="msg-info__top">
<span class="msg-info__name">林护士</span>
<span class="msg-info__time">09:50</span>
</div>
<div class="msg-info__mid"><span class="role-tag role-tag--professional">专业人员</span></div>
<div class="msg-info__preview">张伟的体检报告已经出来了,请查收</div>
</div>
</div>
<div class="msg-item" onclick="selectMsg(this,3)">
<div class="msg-avatar msg-avatar--onsite"></div>
<div class="msg-info">
<div class="msg-info__top">
<span class="msg-info__name">赵刚</span>
<span class="msg-info__time">昨天</span>
</div>
<div class="msg-info__mid"><span class="role-tag role-tag--onsite">驻场人员</span></div>
<div class="msg-info__preview">采油二厂下周有30人需要安排体检</div>
</div>
</div>
<div class="msg-item" onclick="selectMsg(this,4)">
<div class="msg-avatar msg-avatar--admin"></div>
<div class="msg-info">
<div class="msg-info__top">
<span class="msg-info__name">孙主任</span>
<span class="msg-info__time">04-08</span>
</div>
<div class="msg-info__mid"><span class="role-tag role-tag--admin">管理员</span></div>
<div class="msg-info__preview">本月咨询结算数据请尽快整理</div>
</div>
</div>
</div>
</div>
<!-- 右侧:聊天区 -->
<div class="chat-area" id="chatArea">
<div class="chat-header">
<span class="chat-header__name" id="chatName">陈医生</span>
<span class="chat-header__role role-tag role-tag--expert" id="chatRole">咨询专家</span>
<span class="chat-header__detail" id="chatDetail">北京协和医院 · 内分泌科 · 主任医师</span>
</div>
<div class="chat-body" id="chatBody">
<div class="system-msg">对话开始 · 2026-04-10 09:00</div>
<div class="bubble right">
<div class="bubble__avatar me"></div>
<div class="bubble__content">
<div class="bubble__name"></div>
<div class="bubble__text">陈医生您好,有位员工李明空腹血糖6.8,想请您看看需要进一步做什么检查?</div>
<div class="bubble__time">09:15</div>
</div>
</div>
<div class="bubble">
<div class="bubble__avatar" style="background:#F6FFED;color:var(--success);"></div>
<div class="bubble__content">
<div class="bubble__name">陈医生</div>
<div class="bubble__text">你好,6.8属于糖前期范围。建议让他做一个OGTT(口服葡萄糖耐量试验),同时查一下糖化血红蛋白HbA1c,这样能更全面评估血糖控制情况。</div>
<div class="bubble__time">09:30</div>
</div>
</div>
<div class="bubble right">
<div class="bubble__avatar me"></div>
<div class="bubble__content">
<div class="bubble__name"></div>
<div class="bubble__text">好的,我转告他。另外他说家族有糖尿病史,这个需要特别注意吗?</div>
<div class="bubble__time">10:00</div>
</div>
</div>
<div class="bubble">
<div class="bubble__avatar" style="background:#F6FFED;color:var(--success);"></div>
<div class="bubble__content">
<div class="bubble__name">陈医生</div>
<div class="bubble__text">李明的血糖指标我看了,建议做糖耐量检测,有家族史的话更要重视,建议他三个月后复查,日常注意控制饮食和增加运动。</div>
<div class="bubble__time">10:45</div>
</div>
</div>
</div>
<div class="chat-footer">
<div class="chat-input-wrap">
<textarea class="chat-input" rows="1" placeholder="输入消息..."></textarea>
<button class="btn btn-primary">发送</button>
</div>
</div>
</div>
</main>
<!-- 模态弹窗容器 -->
<div class="overlay-modal" id="overlayModal" onclick="if(event.target===this)closeOverlay()">
<div class="overlay-modal__box" id="overlayBox">
<button class="overlay-modal__close" onclick="closeOverlay()"></button>
<iframe id="overlayFrame" src=""></iframe>
</div>
</div>
<script>
/* 弹窗 */
function openOverlay(url, w, h) {
var box = document.getElementById('overlayBox');
box.style.width = w + 'px';
var frame = document.getElementById('overlayFrame');
frame.style.width = w + 'px';
frame.style.height = h + 'px';
frame.src = url;
document.getElementById('overlayModal').classList.add('open');
document.body.style.overflow = 'hidden';
}
function closeOverlay() {
document.getElementById('overlayModal').classList.remove('open');
document.getElementById('overlayFrame').src = '';
document.body.style.overflow = '';
}
/* 消息列表数据 */
var msgData = [
{name:'陈医生',role:'咨询专家',roleClass:'expert',char:'陈',detail:'北京协和医院 · 内分泌科 · 主任医师'},
{name:'周丽',role:'操作人员',roleClass:'operator',char:'周',detail:'长庆油田应急救援中心'},
{name:'林护士',role:'专业人员',roleClass:'professional',char:'林',detail:'主管护师'},
{name:'赵刚',role:'驻场人员',roleClass:'onsite',char:'赵',detail:'长庆油田总医院'},
{name:'孙主任',role:'管理员',roleClass:'admin',char:'孙',detail:'长庆油田 · 健康管理部'}
];
function selectMsg(el, idx) {
document.querySelectorAll('.msg-item').forEach(function(i){i.classList.remove('active');});
el.classList.add('active');
var badge = el.querySelector('.msg-badge');
if (badge) badge.remove();
var d = msgData[idx];
if (d) {
document.getElementById('chatName').textContent = d.name;
var roleEl = document.getElementById('chatRole');
roleEl.textContent = d.role;
roleEl.className = 'chat-header__role role-tag role-tag--' + d.roleClass;
document.getElementById('chatDetail').textContent = d.detail || '';
}
}
/* 接收通讯录弹窗消息,添加联系人到列表 */
window.addEventListener('message', function(e) {
if (e.data === 'close-dialog') { closeOverlay(); return; }
if (e.data && e.data.type === 'add-contact') {
var c = e.data;
var roleClassMap = {'咨询专家':'expert','操作人员':'operator','专业人员':'professional','驻场人员':'onsite','管理员':'admin'};
var rc = roleClassMap[c.role] || 'operator';
var ch = c.name.charAt(0);
/* 检查是否已存在 */
var exists = false;
document.querySelectorAll('.msg-item .msg-info__name').forEach(function(n){
if(n.textContent === c.name) exists = true;
});
if (exists) { closeOverlay(); return; }
var idx = msgData.length;
msgData.push({name:c.name, role:c.role, roleClass:rc, char:ch});
var html = '<div class="msg-item" onclick="selectMsg(this,' + idx + ')">'
+ '<div class="msg-avatar msg-avatar--' + rc + '">' + ch + '</div>'
+ '<div class="msg-info">'
+ '<div class="msg-info__top"><span class="msg-info__name">' + c.name + '</span><span class="msg-info__time">刚刚</span></div>'
+ '<div class="msg-info__mid"><span class="role-tag role-tag--' + rc + '">' + c.role + '</span></div>'
+ '<div class="msg-info__preview">暂无消息</div>'
+ '</div></div>';
document.getElementById('msgListBody').insertAdjacentHTML('afterbegin', html);
closeOverlay();
}
});
</script>
</body>
</html>
@@ -0,0 +1,152 @@
<!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>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;min-width:1280px;}
:root{--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;--text-primary:#333;--text-secondary:#666;--border:#E8E8E8;--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--font-xl:20px;--radius-sm:4px;--radius-md:8px;--shadow-sm:0 1px 4px rgba(0,0,0,0.08);}
.top-bar{display:flex;align-items:center;height:56px;background:#001529;padding:0 24px;position:fixed;top:0;left:0;right:0;z-index:100;}
.top-bar__logo{display:flex;align-items:center;gap:8px;color:#fff;font-size:var(--font-lg);font-weight:600;width:240px;flex-shrink:0;white-space:nowrap;}
.top-bar__logo svg{width:28px;height:28px;}
.top-bar__nav{display:flex;align-items:center;gap:4px;flex:1;}
.top-bar__nav a{color:rgba(255,255,255,0.65);text-decoration:none;padding:6px 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);transition:all .2s;}
.top-bar__nav a:hover{color:#fff;background:rgba(255,255,255,0.08);}
.top-bar__nav a.active{color:#fff;background:var(--primary);}
.top-bar__right{display:flex;align-items:center;gap:16px;font-size:var(--font-sm);margin-left:auto;}
.btn-back{color:rgba(255,255,255,0.65);cursor:pointer;display:flex;align-items:center;gap:4px;text-decoration:none;}.btn-back:hover{color:#fff;}
.avatar{width:32px;height:32px;border-radius:50%;background:var(--success);display:flex;align-items:center;justify-content:center;color:#fff;font-size:var(--font-sm);}
.main{margin-top:56px;padding:24px;display:flex;gap:20px;height:calc(100vh - 56px);}
/* 左侧分类树 */
.category-panel{width:260px;background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);flex-shrink:0;display:flex;flex-direction:column;overflow:hidden;}
.category-panel__header{padding:16px 20px;border-bottom:1px solid var(--border);font-size:var(--font-base);font-weight:600;}
.category-panel__search{margin:12px 16px;height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);outline:none;width:calc(100% - 32px);}
.category-panel__search:focus{border-color:var(--primary);}
.category-list{flex:1;overflow-y:auto;padding:4px 0;}
.cat-item{padding:10px 20px;font-size:var(--font-sm);cursor:pointer;transition:all .15s;display:flex;align-items:center;justify-content:space-between;}
.cat-item:hover{background:#FAFAFA;color:var(--primary);}
.cat-item.active{background:var(--primary-light);color:var(--primary);font-weight:500;}
.cat-item__count{font-size:var(--font-xs);color:var(--text-secondary);background:#F5F5F5;padding:1px 8px;border-radius:10px;}
.cat-item.active .cat-item__count{background:var(--primary);color:#fff;}
/* 右侧项目列表 */
.items-panel{flex:1;background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);display:flex;flex-direction:column;overflow:hidden;}
.items-panel__header{display:flex;align-items:center;justify-content:space-between;padding:16px 24px;border-bottom:1px solid var(--border);}
.items-panel__title{font-size:var(--font-base);font-weight:600;}
.items-panel__body{flex:1;overflow-y:auto;}
table{width:100%;border-collapse:collapse;}
thead th{background:#FAFAFA;padding:12px 16px;text-align:left;font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);white-space:nowrap;}
tbody td{padding:14px 16px;font-size:var(--font-sm);border-bottom:1px solid var(--border);}
tbody tr:last-child td{border-bottom:none;}
tbody tr:hover{background:#F8FBFF;}
.link{color:var(--primary);cursor:pointer;font-size:var(--font-sm);}.link:hover{color:#40a9ff;}
.tag{display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:var(--font-xs);}
.tag-green{background:#F6FFED;color:var(--success);}
.tag-orange{background:#FFF7E6;color:var(--warning);}
/* 模态弹窗(iframe覆盖层) */
.overlay-modal{display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.45);z-index:1000;align-items:center;justify-content:center;}
.overlay-modal.open{display:flex;}
.overlay-modal__box{background:#fff;border-radius:var(--radius-md);overflow:hidden;box-shadow:0 4px 16px rgba(0,0,0,0.15);position:relative;max-height:90vh;display:flex;flex-direction:column;}
.overlay-modal__close{position:absolute;top:12px;right:12px;width:32px;height:32px;border-radius:50%;background:rgba(0,0,0,0.04);border:none;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#999;z-index:10;transition:all .15s;}
.overlay-modal__close:hover{background:rgba(0,0,0,0.08);color:#333;}
.overlay-modal iframe{border:none;display:block;}
</style>
</head>
<body>
<div class="top-bar">
<div class="top-bar__logo"><svg viewBox="0 0 28 28" fill="none"><rect width="28" height="28" rx="6" fill="#52C41A"/><path d="M9 14.5l3 3 7-7" stroke="#fff" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/></svg>专家咨询–小助手</div>
<nav class="top-bar__nav">
<a href="current-consult.html">当前咨询</a>
<a href="chat-message.html">对话消息</a>
<a href="history-consult.html">历史咨询</a>
<a href="checkup-standard.html" class="active">体检标准化</a>
<a href="sms-send.html">短信发送</a>
<a href="consult-settle.html">咨询结算</a>
</nav>
<div class="top-bar__right">
<a class="btn-back" href="../../index.html"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>返回首页</a>
<div class="avatar"></div><span style="color:rgba(255,255,255,0.65);">健康小助手 ▾</span>
</div>
</div>
<main class="main">
<div class="category-panel">
<div class="category-panel__header">体检分类</div>
<input class="category-panel__search" type="text" placeholder="搜索分类">
<div class="category-list">
<div class="cat-item active" onclick="selectCat(this)">一般检查 <span class="cat-item__count">8</span></div>
<div class="cat-item" onclick="selectCat(this)">血液检查 <span class="cat-item__count">15</span></div>
<div class="cat-item" onclick="selectCat(this)">尿液检查 <span class="cat-item__count">10</span></div>
<div class="cat-item" onclick="selectCat(this)">肝功能 <span class="cat-item__count">12</span></div>
<div class="cat-item" onclick="selectCat(this)">肾功能 <span class="cat-item__count">6</span></div>
<div class="cat-item" onclick="selectCat(this)">血脂检查 <span class="cat-item__count">7</span></div>
<div class="cat-item" onclick="selectCat(this)">血糖检查 <span class="cat-item__count">4</span></div>
<div class="cat-item" onclick="selectCat(this)">甲状腺功能 <span class="cat-item__count">6</span></div>
<div class="cat-item" onclick="selectCat(this)">肿瘤标志物 <span class="cat-item__count">8</span></div>
<div class="cat-item" onclick="selectCat(this)">心电图 <span class="cat-item__count">3</span></div>
<div class="cat-item" onclick="selectCat(this)">影像检查 <span class="cat-item__count">9</span></div>
<div class="cat-item" onclick="selectCat(this)">眼科检查 <span class="cat-item__count">5</span></div>
<div class="cat-item" onclick="selectCat(this)">耳鼻喉科 <span class="cat-item__count">4</span></div>
</div>
</div>
<div class="items-panel">
<div class="items-panel__header">
<div class="items-panel__title">一般检查 · 8个项目</div>
</div>
<div class="items-panel__body">
<table>
<thead>
<tr><th>项目名称</th><th>项目编码</th><th>参考范围</th><th>单位</th><th>临床意义</th><th>操作</th></tr>
</thead>
<tbody>
<tr><td>身高</td><td style="font-family:monospace;color:var(--text-secondary);">GE001</td><td></td><td>cm</td><td>基础体格指标</td><td><span class="link" onclick="openOverlay('item-detail-dialog.html',600,560)">查看明细</span></td></tr>
<tr><td>体重</td><td style="font-family:monospace;color:var(--text-secondary);">GE002</td><td></td><td>kg</td><td>基础体格指标</td><td><span class="link" onclick="openOverlay('item-detail-dialog.html',600,560)">查看明细</span></td></tr>
<tr><td>BMI</td><td style="font-family:monospace;color:var(--text-secondary);">GE003</td><td>18.5 ~ 23.9</td><td>kg/m²</td><td>评估体重是否正常</td><td><span class="link" onclick="openOverlay('item-detail-dialog.html',600,560)">查看明细</span></td></tr>
<tr><td>收缩压</td><td style="font-family:monospace;color:var(--text-secondary);">GE004</td><td>90 ~ 139</td><td>mmHg</td><td>评估血压水平</td><td><span class="link" onclick="openOverlay('item-detail-dialog.html',600,560)">查看明细</span></td></tr>
<tr><td>舒张压</td><td style="font-family:monospace;color:var(--text-secondary);">GE005</td><td>60 ~ 89</td><td>mmHg</td><td>评估血压水平</td><td><span class="link" onclick="openOverlay('item-detail-dialog.html',600,560)">查看明细</span></td></tr>
<tr><td>脉搏</td><td style="font-family:monospace;color:var(--text-secondary);">GE006</td><td>60 ~ 100</td><td>次/分</td><td>评估心率</td><td><span class="link" onclick="openOverlay('item-detail-dialog.html',600,560)">查看明细</span></td></tr>
<tr><td>腰围</td><td style="font-family:monospace;color:var(--text-secondary);">GE007</td><td>&lt;85 女&lt;80</td><td>cm</td><td>评估腹型肥胖</td><td><span class="link" onclick="openOverlay('item-detail-dialog.html',600,560)">查看明细</span></td></tr>
<tr><td>体脂率</td><td style="font-family:monospace;color:var(--text-secondary);">GE008</td><td>男10~20 女18~28</td><td>%</td><td>评估体脂水平</td><td><span class="link" onclick="openOverlay('item-detail-dialog.html',600,560)">查看明细</span></td></tr>
</tbody>
</table>
</div>
</div>
</main>
<!-- 模态弹窗容器 -->
<div class="overlay-modal" id="overlayModal" onclick="if(event.target===this)closeOverlay()">
<div class="overlay-modal__box" id="overlayBox">
<button class="overlay-modal__close" onclick="closeOverlay()"></button>
<iframe id="overlayFrame" src=""></iframe>
</div>
</div>
<script>
function openOverlay(url, w, h) {
var box = document.getElementById('overlayBox');
box.style.width = w + 'px';
var frame = document.getElementById('overlayFrame');
frame.style.width = w + 'px';
frame.style.height = h + 'px';
frame.src = url;
document.getElementById('overlayModal').classList.add('open');
document.body.style.overflow = 'hidden';
}
function closeOverlay() {
document.getElementById('overlayModal').classList.remove('open');
document.getElementById('overlayFrame').src = '';
document.body.style.overflow = '';
}
window.addEventListener('message', function(e) {
if (e.data === 'close-dialog') closeOverlay();
});
function selectCat(el){
document.querySelectorAll('.cat-item').forEach(i=>i.classList.remove('active'));
el.classList.add('active');
}
</script>
</body>
</html>
@@ -0,0 +1,195 @@
<!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>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;min-width:1280px;}
:root{--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;--text-primary:#333;--text-secondary:#666;--border:#E8E8E8;--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--font-xl:20px;--font-xxl:24px;--radius-sm:4px;--radius-md:8px;--shadow-sm:0 1px 4px rgba(0,0,0,0.08);}
.top-bar{display:flex;align-items:center;height:56px;background:#001529;padding:0 24px;position:fixed;top:0;left:0;right:0;z-index:100;}
.top-bar__logo{display:flex;align-items:center;gap:8px;color:#fff;font-size:var(--font-lg);font-weight:600;width:240px;flex-shrink:0;white-space:nowrap;}
.top-bar__logo svg{width:28px;height:28px;}
.top-bar__nav{display:flex;align-items:center;gap:4px;flex:1;}
.top-bar__nav a{color:rgba(255,255,255,0.65);text-decoration:none;padding:6px 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);transition:all .2s;}
.top-bar__nav a:hover{color:#fff;background:rgba(255,255,255,0.08);}
.top-bar__nav a.active{color:#fff;background:var(--primary);}
.top-bar__right{display:flex;align-items:center;gap:16px;font-size:var(--font-sm);margin-left:auto;}
.btn-back{color:rgba(255,255,255,0.65);cursor:pointer;display:flex;align-items:center;gap:4px;text-decoration:none;}.btn-back:hover{color:#fff;}
.avatar{width:32px;height:32px;border-radius:50%;background:var(--success);display:flex;align-items:center;justify-content:center;color:#fff;font-size:var(--font-sm);}
.main{margin-top:56px;padding:24px;}
.stat-cards{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:16px;}
.stat-card{background:#fff;border-radius:var(--radius-md);padding:20px 24px;box-shadow:var(--shadow-sm);}
.stat-card__label{font-size:var(--font-sm);color:var(--text-secondary);}
.stat-card__value{font-size:var(--font-xxl);font-weight:700;margin-top:8px;}
.stat-card__sub{font-size:var(--font-xs);color:var(--text-secondary);margin-top:4px;}
.filter-bar{background:#fff;border-radius:var(--radius-md);padding:20px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:flex;align-items:center;gap:16px;flex-wrap:wrap;}
.filter-item{display:flex;align-items:center;gap:8px;}
.filter-item label{font-size:var(--font-sm);color:var(--text-secondary);white-space:nowrap;}
.filter-input{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);outline:none;background:#fff;min-width:180px;}
.filter-input:focus{border-color:var(--primary);}
.filter-select{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);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 10px center;appearance:none;min-width:120px;}
.btn{height:36px;padding:0 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;}
.btn-primary{background:var(--primary);color:#fff;}.btn-primary:hover{background:#40a9ff;}
.btn-default{background:#fff;color:var(--text-primary);border:1px solid var(--border);}.btn-default:hover{color:var(--primary);border-color:var(--primary);}
.btn-success{background:var(--success);color:#fff;}.btn-success:hover{background:#73d13d;}
.table-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);overflow:hidden;}
.table-card__header{display:flex;align-items:center;justify-content:space-between;padding:16px 24px;border-bottom:1px solid var(--border);}
.table-card__title{font-size:var(--font-base);font-weight:600;}
table{width:100%;border-collapse:collapse;}
thead th{background:#FAFAFA;padding:12px 16px;text-align:left;font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);white-space:nowrap;}
tbody td{padding:14px 16px;font-size:var(--font-sm);border-bottom:1px solid var(--border);white-space:nowrap;}
tbody tr:last-child td{border-bottom:none;}
tbody tr:hover{background:#F8FBFF;}
.tag{display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:var(--font-xs);}
.tag-green{background:#F6FFED;color:var(--success);}
.tag-orange{background:#FFF7E6;color:var(--warning);}
.tag-blue{background:var(--primary-light);color:var(--primary);}
.amount-total{font-weight:700;color:var(--warning);font-size:var(--font-base);}
.expert-info{display:flex;align-items:center;gap:10px;}
.expert-avatar{width:36px;height:36px;border-radius:50%;background:var(--primary-light);display:flex;align-items:center;justify-content:center;color:var(--primary);font-weight:600;font-size:var(--font-sm);flex-shrink:0;}
.expert-name{font-weight:500;}
.expert-dept{font-size:var(--font-xs);color:var(--text-secondary);}
.link{color:var(--primary);cursor:pointer;font-size:var(--font-sm);}.link:hover{color:#40a9ff;}
.pagination{display:flex;align-items:center;justify-content:flex-end;padding:16px 24px;gap:8px;border-top:1px solid var(--border);}
.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);}
/* 模态弹窗(iframe覆盖层) */
.overlay-modal{display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.45);z-index:1000;align-items:center;justify-content:center;}
.overlay-modal.open{display:flex;}
.overlay-modal__box{background:#fff;border-radius:var(--radius-md);overflow:hidden;box-shadow:0 4px 16px rgba(0,0,0,0.15);position:relative;max-height:90vh;display:flex;flex-direction:column;}
.overlay-modal__close{position:absolute;top:12px;right:12px;width:32px;height:32px;border-radius:50%;background:rgba(0,0,0,0.04);border:none;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#999;z-index:10;transition:all .15s;}
.overlay-modal__close:hover{background:rgba(0,0,0,0.08);color:#333;}
.overlay-modal iframe{border:none;display:block;}
</style>
</head>
<body>
<div class="top-bar">
<div class="top-bar__logo"><svg viewBox="0 0 28 28" fill="none"><rect width="28" height="28" rx="6" fill="#52C41A"/><path d="M9 14.5l3 3 7-7" stroke="#fff" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/></svg>专家咨询–小助手</div>
<nav class="top-bar__nav">
<a href="current-consult.html">当前咨询</a>
<a href="chat-message.html">对话消息</a>
<a href="history-consult.html">历史咨询</a>
<a href="checkup-standard.html">体检标准化</a>
<a href="sms-send.html">短信发送</a>
<a href="consult-settle.html" class="active">咨询结算</a>
</nav>
<div class="top-bar__right">
<a class="btn-back" href="../../index.html"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>返回首页</a>
<div class="avatar"></div><span style="color:rgba(255,255,255,0.65);">健康小助手 ▾</span>
</div>
</div>
<main class="main">
<div class="stat-cards">
<div class="stat-card"><div class="stat-card__label">本月待结算金额</div><div class="stat-card__value" style="color:var(--warning);">¥ 32,450</div><div class="stat-card__sub">2026年4月</div></div>
<div class="stat-card"><div class="stat-card__label">本月已结算金额</div><div class="stat-card__value" style="color:var(--success);">¥ 18,200</div><div class="stat-card__sub">已完成结算</div></div>
<div class="stat-card"><div class="stat-card__label">本年累计结算</div><div class="stat-card__value" style="color:var(--primary);">¥ 248,600</div><div class="stat-card__sub">2026年度</div></div>
<div class="stat-card"><div class="stat-card__label">待结算专家数</div><div class="stat-card__value">28</div><div class="stat-card__sub">本月待处理</div></div>
</div>
<div class="filter-bar">
<div class="filter-item"><label>结算周期</label>
<select class="filter-select" style="min-width:140px;"><option>2026年4月</option><option>2026年3月</option><option>2026年2月</option><option>2026年1月</option></select>
</div>
<div class="filter-item"><label>专家姓名</label><input class="filter-input" type="text" placeholder="请输入专家姓名"></div>
<div class="filter-item"><label>结算状态</label>
<select class="filter-select"><option>全部状态</option><option>待结算</option><option>已结算</option><option>结算中</option></select>
</div>
<button class="btn btn-primary"><svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4" stroke="currentColor" stroke-width="1.4"/><path d="M10 10l2.5 2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>查询</button>
<button class="btn btn-default">重置</button>
<button class="btn btn-success" style="margin-left:auto;"><svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M7 2v7M4.5 6.5L7 9l2.5-2.5M2 10v2h10v-2" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>生成结算报表</button>
</div>
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-default"><svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 10v2h10v-2M7 2v7M4.5 6.5L7 9l2.5-2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>导出列表数据</button>
<button class="btn btn-default"><svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 10v2h10v-2M7 2v7M4.5 6.5L7 9l2.5-2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>下载报表</button>
</div>
<div class="table-card">
<div class="table-card__header">
<div class="table-card__title">结算明细列表(2026年4月)</div>
<div style="font-size:var(--font-sm);color:var(--text-secondary);">共 42 位专家</div>
</div>
<table>
<thead><tr><th>专家信息</th><th>图文咨询次数</th><th>图文单价</th><th>视频咨询次数</th><th>视频单价</th><th>应结算金额</th><th>结算状态</th><th>结算时间</th><th>操作</th></tr></thead>
<tbody>
<tr>
<td><div class="expert-info"><div class="expert-avatar"></div><div><div class="expert-name">李医生</div><div class="expert-dept">心血管内科</div></div></div></td>
<td>312</td><td>¥ 30</td><td>86</td><td>¥ 80</td>
<td><span class="amount-total">¥ 16,240</span></td>
<td><span class="tag tag-orange">待结算</span></td><td></td>
<td><span class="link" onclick="openOverlay('report-detail-dialog.html',680,640)">查看明细</span></td>
</tr>
<tr>
<td><div class="expert-info"><div class="expert-avatar"></div><div><div class="expert-name">王医生</div><div class="expert-dept">内分泌科</div></div></div></td>
<td>245</td><td>¥ 30</td><td>62</td><td>¥ 80</td>
<td><span class="amount-total">¥ 12,310</span></td>
<td><span class="tag tag-green">已结算</span></td><td>2026-04-05</td>
<td><span class="link" onclick="openOverlay('report-detail-dialog.html',680,640)">查看明细</span></td>
</tr>
<tr>
<td><div class="expert-info"><div class="expert-avatar"></div><div><div class="expert-name">张医生</div><div class="expert-dept">神经内科</div></div></div></td>
<td>198</td><td>¥ 30</td><td>45</td><td>¥ 80</td>
<td><span class="amount-total">¥ 9,540</span></td>
<td><span class="tag tag-blue">结算中</span></td><td></td>
<td><span class="link" onclick="openOverlay('report-detail-dialog.html',680,640)">查看明细</span></td>
</tr>
<tr>
<td><div class="expert-info"><div class="expert-avatar"></div><div><div class="expert-name">陈医生</div><div class="expert-dept">骨科</div></div></div></td>
<td>156</td><td>¥ 30</td><td>18</td><td>¥ 80</td>
<td><span class="amount-total">¥ 6,120</span></td>
<td><span class="tag tag-orange">待结算</span></td><td></td>
<td><span class="link" onclick="openOverlay('report-detail-dialog.html',680,640)">查看明细</span></td>
</tr>
<tr>
<td><div class="expert-info"><div class="expert-avatar"></div><div><div class="expert-name">孙医生</div><div class="expert-dept">消化内科</div></div></div></td>
<td>89</td><td>¥ 30</td><td>12</td><td>¥ 80</td>
<td><span class="amount-total">¥ 3,630</span></td>
<td><span class="tag tag-green">已结算</span></td><td>2026-04-06</td>
<td><span class="link" onclick="openOverlay('report-detail-dialog.html',680,640)">查看明细</span></td>
</tr>
</tbody>
</table>
<div class="pagination">
<span>共 42 条</span>
<button class="page-btn"></button>
<button class="page-btn active">1</button>
<button class="page-btn">2</button>
<button class="page-btn">3</button>
<button class="page-btn">4</button>
<button class="page-btn">5</button>
<button class="page-btn"></button>
<select class="filter-select" style="min-width:70px;height:32px;"><option>10条</option><option>20条</option></select>
</div>
</div>
</main>
<!-- 模态弹窗容器 -->
<div class="overlay-modal" id="overlayModal" onclick="if(event.target===this)closeOverlay()">
<div class="overlay-modal__box" id="overlayBox">
<button class="overlay-modal__close" onclick="closeOverlay()"></button>
<iframe id="overlayFrame" src=""></iframe>
</div>
</div>
<script>
function openOverlay(url, w, h) {
var box = document.getElementById('overlayBox');
box.style.width = w + 'px';
var frame = document.getElementById('overlayFrame');
frame.style.width = w + 'px';
frame.style.height = h + 'px';
frame.src = url;
document.getElementById('overlayModal').classList.add('open');
document.body.style.overflow = 'hidden';
}
function closeOverlay() {
document.getElementById('overlayModal').classList.remove('open');
document.getElementById('overlayFrame').src = '';
document.body.style.overflow = '';
}
window.addEventListener('message', function(e) {
if (e.data === 'close-dialog') closeOverlay();
});
</script>
</body>
</html>
@@ -0,0 +1,140 @@
<!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>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#fff;color:#333;}
:root{--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;--text-primary:#333;--text-secondary:#666;--border:#E8E8E8;--font-xs:11px;--font-sm:13px;--font-base:15px;--radius-sm:4px;--radius-md:8px;}
.dialog{display:flex;flex-direction:column;height:100vh;overflow:hidden;}
.dialog__header{padding:20px 24px 0;flex-shrink:0;}
.dialog__title{font-size:var(--font-base);font-weight:600;margin-bottom:16px;}
.filter-bar{display:flex;gap:8px;margin-bottom:12px;}
.filter-bar__search{flex:1;height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px 0 36px;font-size:var(--font-sm);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='none'%3E%3Ccircle cx='6' cy='6' r='4' stroke='%23999' stroke-width='1.4'/%3E%3Cpath d='M10 10l2.5 2.5' stroke='%23999' stroke-width='1.4' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat 12px center;}
.filter-bar__search:focus{border-color:var(--primary);}
.filter-bar__select{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);outline:none;background:#fff;min-width:120px;}
.filter-bar__select:focus{border-color:var(--primary);}
.contact-list{flex:1;overflow-y:auto;border-top:1px solid var(--border);}
.contact-item{display:flex;align-items:center;gap:12px;padding:12px 24px;cursor:pointer;border-bottom:1px solid #F5F5F5;transition:background .15s;}
.contact-item:hover{background:#FAFAFA;}
.contact-item.selected{background:var(--primary-light);}
.contact-item__avatar{width:40px;height:40px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:var(--font-sm);font-weight:600;flex-shrink:0;}
.av--expert{background:#F6FFED;color:var(--success);}
.av--operator{background:var(--primary-light);color:var(--primary);}
.av--professional{background:#FFF7E6;color:var(--warning);}
.av--onsite{background:#F9F0FF;color:#722ED1;}
.av--admin{background:#FFF1F0;color:var(--danger);}
.contact-item__info{flex:1;min-width:0;}
.contact-item__row1{display:flex;align-items:center;gap:8px;}
.contact-item__name{font-size:var(--font-sm);font-weight:500;}
.role-tag{font-size:10px;padding:1px 6px;border-radius:3px;white-space:nowrap;}
.role-tag--expert{background:#F6FFED;color:var(--success);}
.role-tag--operator{background:var(--primary-light);color:var(--primary);}
.role-tag--professional{background:#FFF7E6;color:var(--warning);}
.role-tag--onsite{background:#F9F0FF;color:#722ED1;}
.role-tag--admin{background:#FFF1F0;color:var(--danger);}
.contact-item__detail{font-size:var(--font-xs);color:var(--text-secondary);margin-top:3px;}
.contact-item__check{width:20px;height:20px;border-radius:50%;border:1.5px solid var(--border);flex-shrink:0;display:flex;align-items:center;justify-content:center;transition:all .15s;}
.contact-item.selected .contact-item__check{border-color:var(--primary);background:var(--primary);}
.dialog__footer{padding:12px 24px;border-top:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;flex-shrink:0;background:#FAFAFA;}
.dialog__footer-info{font-size:var(--font-sm);color:var(--text-secondary);}
.dialog__footer-info span{color:var(--primary);font-weight:500;}
.btn{height:36px;padding:0 20px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;}
.btn-primary{background:var(--primary);color:#fff;}
.btn-primary:hover{background:#40a9ff;}
.btn-primary:disabled{background:#d9d9d9;cursor:not-allowed;}
.btn-default{background:#fff;color:var(--text-primary);border:1px solid var(--border);margin-right:8px;}
.btn-default:hover{color:var(--primary);border-color:var(--primary);}
</style>
</head>
<body>
<div class="dialog">
<div class="dialog__header">
<div class="dialog__title">通讯录</div>
<div class="filter-bar">
<input class="filter-bar__search" type="text" placeholder="搜索姓名" oninput="filterList()">
<select class="filter-bar__select" onchange="filterList()">
<option value="">全部角色</option>
<option value="咨询专家">咨询专家</option>
<option value="操作人员">操作人员</option>
<option value="专业人员">专业人员</option>
<option value="驻场人员">驻场人员</option>
<option value="管理员">管理员</option>
</select>
</div>
</div>
<div class="contact-list" id="contactList"></div>
<div class="dialog__footer">
<div class="dialog__footer-info">已选择 <span id="selectedCount">0</span></div>
<div>
<button class="btn btn-default" onclick="parent.postMessage('close-dialog','*')">取消</button>
<button class="btn btn-primary" id="btnConfirm" disabled onclick="confirmAdd()">确认添加</button>
</div>
</div>
</div>
<script>
var contacts = [
{name:'王医生',role:'咨询专家',roleClass:'expert',detail:'北京协和医院 · 内分泌科 · 主任医师'},
{name:'李教授',role:'咨询专家',roleClass:'expert',detail:'华西医院 · 心血管内科 · 教授'},
{name:'张医生',role:'咨询专家',roleClass:'expert',detail:'北京安贞医院 · 神经内科 · 副主任医师'},
{name:'周丽',role:'操作人员',roleClass:'operator',detail:'长庆油田应急救援中心'},
{name:'吴敏',role:'操作人员',roleClass:'operator',detail:'西安应急保障中心'},
{name:'林护士',role:'专业人员',roleClass:'professional',detail:'主管护师'},
{name:'黄技师',role:'专业人员',roleClass:'professional',detail:'副主任技师'},
{name:'郑营养师',role:'专业人员',roleClass:'professional',detail:'高级营养师'},
{name:'赵刚',role:'驻场人员',roleClass:'onsite',detail:'长庆油田总医院'},
{name:'钱磊',role:'驻场人员',roleClass:'onsite',detail:'庆阳市人民医院'},
{name:'孙主任',role:'管理员',roleClass:'admin',detail:'长庆油田 · 健康管理部'},
{name:'马处长',role:'管理员',roleClass:'admin',detail:'长庆油田 · 安全环保部'}
];
var selectedIdx = -1;
function renderList(list) {
var html = '';
list.forEach(function(c, i) {
var origIdx = contacts.indexOf(c);
var sel = origIdx === selectedIdx ? ' selected' : '';
html += '<div class="contact-item' + sel + '" data-idx="' + origIdx + '" onclick="toggleSelect(this,' + origIdx + ')">'
+ '<div class="contact-item__avatar av--' + c.roleClass + '">' + c.name.charAt(0) + '</div>'
+ '<div class="contact-item__info">'
+ '<div class="contact-item__row1"><span class="contact-item__name">' + c.name + '</span><span class="role-tag role-tag--' + c.roleClass + '">' + c.role + '</span></div>'
+ '<div class="contact-item__detail">' + c.detail + '</div>'
+ '</div>'
+ '<div class="contact-item__check">' + (sel ? '<svg width="12" height="12" viewBox="0 0 12 12" fill="none"><path d="M2.5 6l2.5 2.5 4.5-5" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>' : '') + '</div>'
+ '</div>';
});
document.getElementById('contactList').innerHTML = html;
}
function toggleSelect(el, idx) {
if (selectedIdx === idx) { selectedIdx = -1; } else { selectedIdx = idx; }
filterList();
document.getElementById('selectedCount').textContent = selectedIdx >= 0 ? '1' : '0';
document.getElementById('btnConfirm').disabled = selectedIdx < 0;
}
function filterList() {
var keyword = document.querySelector('.filter-bar__search').value.trim();
var role = document.querySelector('.filter-bar__select').value;
var filtered = contacts.filter(function(c) {
var matchName = !keyword || c.name.indexOf(keyword) >= 0;
var matchRole = !role || c.role === role;
return matchName && matchRole;
});
renderList(filtered);
}
function confirmAdd() {
if (selectedIdx < 0) return;
var c = contacts[selectedIdx];
parent.postMessage({type:'add-contact', name:c.name, role:c.role}, '*');
}
renderList(contacts);
</script>
</body>
</html>
@@ -0,0 +1,396 @@
<!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>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;min-width:1280px;}
:root{--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;--text-primary:#333;--text-secondary:#666;--border:#E8E8E8;--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--font-xl:20px;--radius-sm:4px;--radius-md:8px;--shadow-sm:0 1px 4px rgba(0,0,0,0.08);}
/* ===== 顶部栏 ===== */
.top-bar{display:flex;align-items:center;height:56px;background:#001529;padding:0 24px;position:fixed;top:0;left:0;right:0;z-index:100;}
.top-bar__logo{display:flex;align-items:center;gap:8px;color:#fff;font-size:var(--font-lg);font-weight:600;width:240px;flex-shrink:0;white-space:nowrap;}
.top-bar__logo svg{width:28px;height:28px;}
.top-bar__nav{display:flex;align-items:center;gap:4px;flex:1;}
.top-bar__nav a{color:rgba(255,255,255,0.65);text-decoration:none;padding:6px 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);transition:all .2s;}
.top-bar__nav a:hover{color:#fff;background:rgba(255,255,255,0.08);}
.top-bar__nav a.active{color:#fff;background:var(--primary);}
.top-bar__right{display:flex;align-items:center;gap:16px;font-size:var(--font-sm);margin-left:auto;}
.btn-back{color:rgba(255,255,255,0.65);cursor:pointer;display:flex;align-items:center;gap:4px;text-decoration:none;}
.btn-back:hover{color:#fff;}
.avatar{width:32px;height:32px;border-radius:50%;background:var(--success);display:flex;align-items:center;justify-content:center;color:#fff;font-size:var(--font-sm);}
/* ===== 主内容区 ===== */
.main{margin-top:56px;height:calc(100vh - 56px);display:flex;overflow:hidden;}
/* ===== 左侧对话列表 ===== */
.conv-list{width:320px;background:#fff;border-right:1px solid var(--border);display:flex;flex-direction:column;flex-shrink:0;}
.conv-list__header{padding:16px;border-bottom:1px solid var(--border);}
.conv-list__search{width:100%;height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px 0 36px;font-size:var(--font-sm);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='none'%3E%3Ccircle cx='6' cy='6' r='4' stroke='%23999' stroke-width='1.4'/%3E%3Cpath d='M10 10l2.5 2.5' stroke='%23999' stroke-width='1.4' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat 12px center;}
.conv-list__search:focus{border-color:var(--primary);}
.conv-list__body{flex:1;overflow-y:auto;}
.conv-item{display:flex;gap:12px;padding:14px 16px;cursor:pointer;border-bottom:1px solid #F5F5F5;transition:background .15s;}
.conv-item:hover{background:#FAFAFA;}
.conv-item.active{background:var(--primary-light);}
.conv-avatar{width:40px;height:40px;border-radius:50%;background:var(--primary-light);color:var(--primary);display:flex;align-items:center;justify-content:center;font-size:var(--font-sm);font-weight:600;flex-shrink:0;}
.conv-info{flex:1;min-width:0;}
.conv-info__top{display:flex;justify-content:space-between;align-items:center;}
.conv-info__name{font-size:var(--font-sm);font-weight:500;color:var(--text-primary);}
.conv-info__time{font-size:var(--font-xs);color:#bbb;}
.conv-info__msg{font-size:var(--font-xs);color:var(--text-secondary);margin-top:4px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.conv-badge{width:18px;height:18px;border-radius:50%;background:var(--danger);color:#fff;font-size:10px;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:2px;}
/* ===== 右侧聊天区 ===== */
.chat-area{flex:1;display:flex;flex-direction:column;background:#F5F7FA;}
.chat-header{height:56px;background:#fff;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;padding:0 20px;flex-shrink:0;}
.chat-header__left{display:flex;align-items:center;gap:12px;}
.chat-header__name{font-size:var(--font-base);font-weight:600;}
.chat-header__tag{font-size:var(--font-xs);padding:2px 8px;border-radius:10px;background:#F6FFED;color:var(--success);}
.chat-header__actions{display:flex;gap:8px;}
.btn{height:36px;padding:0 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;}
.btn-primary{background:var(--primary);color:#fff;}
.btn-primary:hover{background:#40a9ff;}
.btn-default{background:#fff;color:var(--text-primary);border:1px solid var(--border);}
.btn-default:hover{color:var(--primary);border-color:var(--primary);}
.btn-sm{height:30px;padding:0 12px;font-size:var(--font-xs);}
/* 聊天消息 */
.chat-body{flex:1;overflow-y:auto;padding:20px;display:flex;flex-direction:column;gap:16px;}
.system-msg{text-align:center;font-size:var(--font-xs);color:#bbb;padding:4px 0;}
.msg{display:flex;gap:12px;align-items:flex-start;}
.msg.right{flex-direction:row-reverse;}
.msg__avatar{width:36px;height:36px;border-radius:50%;flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:var(--font-sm);font-weight:600;}
.msg__avatar.emp{background:var(--primary-light);color:var(--primary);}
.msg__avatar.asst{background:#F6FFED;color:var(--success);}
.msg__content{max-width:60%;}
.msg__name{font-size:var(--font-xs);color:var(--text-secondary);margin-bottom:4px;}
.msg.right .msg__name{text-align:right;}
.msg__bubble{background:#fff;border-radius:var(--radius-md);padding:12px 16px;font-size:var(--font-sm);line-height:1.7;box-shadow:var(--shadow-sm);word-break:break-word;}
.msg.right .msg__bubble{background:var(--success);color:#fff;}
.msg__time{font-size:var(--font-xs);color:#bbb;margin-top:4px;}
.msg.right .msg__time{text-align:right;}
/* 专家卡片(发送到对话中的) */
.expert-card-msg{background:#fff;border:1px solid var(--border);border-radius:var(--radius-md);padding:12px 16px;display:flex;align-items:center;gap:12px;box-shadow:var(--shadow-sm);}
.expert-card-msg__avatar{width:40px;height:40px;border-radius:50%;background:var(--primary-light);color:var(--primary);display:flex;align-items:center;justify-content:center;font-weight:600;font-size:var(--font-sm);flex-shrink:0;}
.expert-card-msg__info{flex:1;}
.expert-card-msg__name{font-size:var(--font-sm);font-weight:500;}
.expert-card-msg__dept{font-size:var(--font-xs);color:var(--text-secondary);}
.expert-card-msg__btn{font-size:var(--font-xs);color:var(--primary);cursor:pointer;}
/* 底部输入区 */
.chat-footer{background:#fff;border-top:1px solid var(--border);padding:12px 20px;flex-shrink:0;}
.chat-toolbar{display:flex;gap:8px;margin-bottom:8px;}
.toolbar-btn{background:none;border:none;cursor:pointer;color:var(--text-secondary);display:flex;align-items:center;gap:4px;font-size:var(--font-xs);padding:4px 8px;border-radius:var(--radius-sm);transition:all .15s;}
.toolbar-btn:hover{background:#F5F5F5;color:var(--primary);}
.toolbar-btn svg{width:16px;height:16px;}
/* 常用语弹出面板 */
.phrase-wrap{position:relative;}
.phrase-pop{display:none;position:absolute;bottom:calc(100% + 8px);left:0;width:260px;background:#fff;border-radius:var(--radius-md);box-shadow:0 4px 16px rgba(0,0,0,0.15);z-index:50;overflow:hidden;}
.phrase-pop.open{display:block;}
.phrase-pop__title{padding:10px 14px;font-size:var(--font-xs);color:var(--text-secondary);border-bottom:1px solid var(--border);font-weight:500;}
.phrase-pop__list{max-height:220px;overflow-y:auto;}
.phrase-pop__item{padding:9px 14px;font-size:var(--font-sm);cursor:pointer;transition:background .12s;border-bottom:1px solid #F5F5F5;}
.phrase-pop__item:last-child{border-bottom:none;}
.phrase-pop__item:hover{background:var(--primary-light);color:var(--primary);}
.phrase-pop::after{content:'';position:absolute;bottom:-6px;left:24px;width:10px;height:10px;background:#fff;transform:rotate(45deg);box-shadow:2px 2px 4px rgba(0,0,0,0.06);}
.chat-input-wrap{display:flex;gap:8px;align-items:flex-end;}
.chat-input{flex:1;min-height:40px;max-height:120px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:8px 12px;font-size:var(--font-sm);outline:none;resize:none;font-family:inherit;line-height:1.6;}
.chat-input:focus{border-color:var(--primary);}
/* 弹窗通用 */
.modal{display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.45);z-index:1000;align-items:center;justify-content:center;}
.modal.open{display:flex;}
/* 模态弹窗(iframe覆盖层) */
.overlay-modal{display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.45);z-index:1000;align-items:center;justify-content:center;}
.overlay-modal.open{display:flex;}
.overlay-modal__box{background:#fff;border-radius:var(--radius-md);overflow:hidden;box-shadow:0 4px 16px rgba(0,0,0,0.15);position:relative;max-height:90vh;display:flex;flex-direction:column;}
.overlay-modal__close{position:absolute;top:12px;right:12px;width:32px;height:32px;border-radius:50%;background:rgba(0,0,0,0.04);border:none;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#999;z-index:10;transition:all .15s;}
.overlay-modal__close:hover{background:rgba(0,0,0,0.08);color:#333;}
.overlay-modal iframe{border:none;display:block;}
</style>
</head>
<body>
<!-- ===== 顶部栏 ===== -->
<div class="top-bar">
<div class="top-bar__logo">
<svg viewBox="0 0 28 28" fill="none"><rect width="28" height="28" rx="6" fill="#52C41A"/><path d="M9 14.5l3 3 7-7" stroke="#fff" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
专家咨询–小助手
</div>
<nav class="top-bar__nav">
<a href="current-consult.html" class="active">当前咨询</a>
<a href="chat-message.html">对话消息</a>
<a href="history-consult.html">历史咨询</a>
<a href="checkup-standard.html">体检标准化</a>
<a href="sms-send.html">短信发送</a>
<a href="consult-settle.html">咨询结算</a>
</nav>
<div class="top-bar__right">
<a class="btn-back" href="../../index.html">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
返回首页
</a>
<div class="avatar"></div>
<span style="color:rgba(255,255,255,0.65);">健康小助手 ▾</span>
</div>
</div>
<!-- ===== 侧边栏 ===== -->
<!-- ===== 主内容区 ===== -->
<main class="main">
<!-- 左侧:对话列表 -->
<div class="conv-list">
<div class="conv-list__header">
<input class="conv-list__search" type="text" placeholder="搜索员工姓名/工号">
</div>
<div class="conv-list__body">
<!-- [交互] 点击切换右侧对话内容 -->
<div class="conv-item active" onclick="selectConv(this,0)">
<div class="conv-avatar"></div>
<div class="conv-info">
<div class="conv-info__top">
<span class="conv-info__name">李明</span>
<span class="conv-info__time">10:32</span>
</div>
<div class="conv-info__msg">我体检报告显示空腹血糖6.8,这是糖尿病吗?</div>
</div>
<div class="conv-badge">2</div>
</div>
<div class="conv-item" onclick="selectConv(this,1)">
<div class="conv-avatar"></div>
<div class="conv-info">
<div class="conv-info__top">
<span class="conv-info__name">张伟</span>
<span class="conv-info__time">09:58</span>
</div>
<div class="conv-info__msg">最近总是头疼,需要做什么检查?</div>
</div>
</div>
<div class="conv-item" onclick="selectConv(this,2)">
<div class="conv-avatar"></div>
<div class="conv-info">
<div class="conv-info__top">
<span class="conv-info__name">王芳</span>
<span class="conv-info__time">09:45</span>
</div>
<div class="conv-info__msg">请问体检套餐B包含哪些项目?</div>
</div>
</div>
<div class="conv-item" onclick="selectConv(this,3)">
<div class="conv-avatar"></div>
<div class="conv-info">
<div class="conv-info__top">
<span class="conv-info__name">赵静</span>
<span class="conv-info__time">昨天</span>
</div>
<div class="conv-info__msg">我想了解一下高血压的日常注意事项</div>
</div>
</div>
<div class="conv-item" onclick="selectConv(this,4)">
<div class="conv-avatar"></div>
<div class="conv-info">
<div class="conv-info__top">
<span class="conv-info__name">刘洋</span>
<span class="conv-info__time">昨天</span>
</div>
<div class="conv-info__msg">帮我推荐一个心血管方面的专家</div>
</div>
<div class="conv-badge">1</div>
</div>
<div class="conv-item" onclick="selectConv(this,5)">
<div class="conv-avatar"></div>
<div class="conv-info">
<div class="conv-info__top">
<span class="conv-info__name">陈强</span>
<span class="conv-info__time">04-08</span>
</div>
<div class="conv-info__msg">我的体检报告有几项异常,帮我看看</div>
</div>
</div>
</div>
</div>
<!-- 右侧:聊天区 -->
<div class="chat-area">
<div class="chat-header">
<div class="chat-header__left">
<span class="chat-header__name" id="chatName">李明</span>
<span class="chat-header__tag">咨询中</span>
</div>
<div class="chat-header__actions">
<!-- [交互] 点击打开咨询人档案弹窗 -->
<button class="btn btn-default btn-sm" onclick="openOverlay('employee-profile-dialog.html',680,720)">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="7" cy="5" r="3" stroke="currentColor" stroke-width="1.2"/><path d="M2 13c0-2.8 2.2-5 5-5s5 2.2 5 5" stroke="currentColor" stroke-width="1.2"/></svg>
查看档案
</button>
<!-- [交互] 点击结束当前咨询 -->
<button class="btn btn-default btn-sm" style="color:var(--danger);border-color:var(--danger);">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="7" cy="7" r="5" stroke="currentColor" stroke-width="1.2"/><path d="M5 5l4 4M9 5l-4 4" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>
结束咨询
</button>
</div>
</div>
<div class="chat-body" id="chatBody">
<div class="system-msg">会话开始 · 2026-04-10 10:20</div>
<div class="msg right">
<div class="msg__avatar asst"></div>
<div class="msg__content">
<div class="msg__name">健康小助手</div>
<div class="msg__bubble">您好!我是健康咨询小助手,很高兴为您服务。请问您有什么健康问题需要咨询?</div>
<div class="msg__time">10:20</div>
</div>
</div>
<div class="msg">
<div class="msg__avatar emp"></div>
<div class="msg__content">
<div class="msg__name">李明(采油二厂)</div>
<div class="msg__bubble">我体检报告显示空腹血糖6.8,这是糖尿病吗?</div>
<div class="msg__time">10:25</div>
</div>
</div>
<div class="msg right">
<div class="msg__avatar asst"></div>
<div class="msg__content">
<div class="msg__name">健康小助手</div>
<div class="msg__bubble">您好!空腹血糖6.8 mmol/L属于糖尿病前期(正常值3.9-6.1,6.1-7.0为糖前期,≥7.0为糖尿病)。<br><br>建议您:<br>1. 不要过于担心,糖尿病前期可以逆转<br>2. 控制饮食,减少精制碳水摄入<br>3. 每天至少30分钟中等强度运动<br>4. 建议咨询内分泌科专家进一步评估</div>
<div class="msg__time">10:27</div>
</div>
</div>
<div class="msg">
<div class="msg__avatar emp"></div>
<div class="msg__content">
<div class="msg__name">李明(采油二厂)</div>
<div class="msg__bubble">能帮我推荐一个内分泌科的专家吗?</div>
<div class="msg__time">10:30</div>
</div>
</div>
<div class="msg right">
<div class="msg__avatar asst"></div>
<div class="msg__content">
<div class="msg__name">健康小助手</div>
<div class="msg__bubble">好的,为您推荐以下内分泌科专家:</div>
<div class="msg__time">10:32</div>
</div>
</div>
<!-- 专家卡片消息 -->
<div class="msg right">
<div class="msg__avatar asst"></div>
<div class="msg__content">
<div class="expert-card-msg">
<div class="expert-card-msg__avatar"></div>
<div class="expert-card-msg__info">
<div class="expert-card-msg__name">王医生 · 主任医师</div>
<div class="expert-card-msg__dept">北京协和医院 · 内分泌科</div>
</div>
<div class="expert-card-msg__btn">去咨询 →</div>
</div>
</div>
</div>
</div>
<div class="chat-footer">
<div class="chat-toolbar">
<!-- [交互] 点击打开选择专家弹窗 -->
<button class="toolbar-btn" onclick="openOverlay('select-expert-dialog.html',720,600)">
<svg viewBox="0 0 16 16" fill="none"><circle cx="8" cy="5" r="3" stroke="currentColor" stroke-width="1.2"/><path d="M3 15c0-2.8 2.2-5 5-5s5 2.2 5 5" stroke="currentColor" stroke-width="1.2"/><path d="M12 2v4M10 4h4" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>
发送专家
</button>
<div class="phrase-wrap">
<button class="toolbar-btn" onclick="togglePhrase(event)">
<svg viewBox="0 0 16 16" fill="none"><rect x="2" y="2" width="12" height="12" rx="2" stroke="currentColor" stroke-width="1.2"/><path d="M5 7l2 2 4-4" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
常用语
</button>
<div class="phrase-pop" id="phrasePop">
<div class="phrase-pop__title">选择常用语</div>
<div class="phrase-pop__list">
<div class="phrase-pop__item" onclick="sendPhrase(this)">您好,我是健康咨询小助手,请问有什么可以帮您?</div>
<div class="phrase-pop__item" onclick="sendPhrase(this)">请您稍等,我为您查询一下相关信息。</div>
<div class="phrase-pop__item" onclick="sendPhrase(this)">根据您的体检报告,建议您进一步咨询专科医生。</div>
<div class="phrase-pop__item" onclick="sendPhrase(this)">我为您推荐一位擅长该领域的专家,请查看。</div>
<div class="phrase-pop__item" onclick="sendPhrase(this)">建议您保持健康饮食,适量运动,定期复查。</div>
<div class="phrase-pop__item" onclick="sendPhrase(this)">您的咨询已记录,如有需要可随时联系我们。</div>
<div class="phrase-pop__item" onclick="sendPhrase(this)">感谢您的咨询,祝您身体健康!</div>
</div>
</div>
</div>
<button class="toolbar-btn">
<svg viewBox="0 0 16 16" fill="none"><rect x="2" y="2" width="12" height="12" rx="2" stroke="currentColor" stroke-width="1.2"/><circle cx="5.5" cy="6" r="1" fill="currentColor"/><path d="M2 11l3-3 2 2 3-3 4 4" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/></svg>
图片
</button>
</div>
<div class="chat-input-wrap">
<textarea class="chat-input" rows="1" placeholder="输入消息..."></textarea>
<button class="btn btn-primary">发送</button>
</div>
</div>
</div>
</main>
<!-- 模态弹窗容器 -->
<div class="overlay-modal" id="overlayModal" onclick="if(event.target===this)closeOverlay()">
<div class="overlay-modal__box" id="overlayBox">
<button class="overlay-modal__close" onclick="closeOverlay()"></button>
<iframe id="overlayFrame" src=""></iframe>
</div>
</div>
<script>
function openOverlay(url, w, h) {
var box = document.getElementById('overlayBox');
box.style.width = w + 'px';
var frame = document.getElementById('overlayFrame');
frame.style.width = w + 'px';
frame.style.height = h + 'px';
frame.src = url;
document.getElementById('overlayModal').classList.add('open');
document.body.style.overflow = 'hidden';
}
function closeOverlay() {
document.getElementById('overlayModal').classList.remove('open');
document.getElementById('overlayFrame').src = '';
document.body.style.overflow = '';
}
window.addEventListener('message', function(e) {
if (e.data === 'close-dialog') closeOverlay();
});
function selectConv(el, idx) {
document.querySelectorAll('.conv-item').forEach(i => i.classList.remove('active'));
el.classList.add('active');
const badge = el.querySelector('.conv-badge');
if (badge) badge.remove();
const name = el.querySelector('.conv-info__name').textContent;
document.getElementById('chatName').textContent = name;
}
/* 常用语弹出 */
function togglePhrase(e) {
e.stopPropagation();
document.getElementById('phrasePop').classList.toggle('open');
}
function sendPhrase(el) {
var text = el.textContent;
var body = document.getElementById('chatBody');
var now = new Date();
var time = now.getHours().toString().padStart(2,'0') + ':' + now.getMinutes().toString().padStart(2,'0');
var html = '<div class="msg right">'
+ '<div class="msg__avatar asst">助</div>'
+ '<div class="msg__content">'
+ '<div class="msg__name">健康小助手</div>'
+ '<div class="msg__bubble">' + text + '</div>'
+ '<div class="msg__time">' + time + '</div>'
+ '</div></div>';
body.insertAdjacentHTML('beforeend', html);
body.scrollTop = body.scrollHeight;
document.getElementById('phrasePop').classList.remove('open');
}
document.addEventListener('click', function() {
document.getElementById('phrasePop').classList.remove('open');
});
</script>
</body>
</html>
@@ -0,0 +1,50 @@
# 变更记录 - 专家咨询·小助手角色(后台管理系统)
## 2026-04-10
### feat: 新增对话消息模块及通讯录功能
**涉及文件:**
- `chat-message.html` — 新增对话消息主页面(IM风格左右分栏,左侧消息列表含角色标签,右侧聊天对话区)
- `contacts-dialog.html` — 新增通讯录弹窗(按角色分类筛选,不同角色显示不同附加信息)
- `current-consult.html` — 顶部导航栏增加"对话消息"链接
- `history-consult.html` — 顶部导航栏增加"对话消息"链接
- `checkup-standard.html` — 顶部导航栏增加"对话消息"链接
- `sms-send.html` — 顶部导航栏增加"对话消息"链接
- `consult-settle.html` — 顶部导航栏增加"对话消息"链接
**变更说明:**
- 新增"对话消息"一级菜单,位于"当前咨询"之后,用于小助手与内部人员(咨询专家、操作人员、专业人员、驻场人员、管理员)之间的即时通讯
- 通讯录弹窗支持按角色筛选和姓名搜索,选中人员后添加到消息列表
- 不同角色显示差异化附加信息:咨询专家显示医院/科室/职称,操作人员显示应急中心,专业人员显示职称,驻场人员显示所在医院,管理员显示单位/部门
- 同步更新全部5个同级页面的顶部导航栏
## 2026-04-10
### init: 初始化小助手角色后台管理模块
**涉及文件:**
- `current-consult.html` — 当前咨询主页面(IM风格左右分栏)
- `employee-profile-dialog.html` — 咨询人档案弹窗
- `select-expert-dialog.html` — 选择专家弹窗
- `history-consult.html` — 历史咨询列表页
- `chat-detail-dialog.html` — 历史对话详情弹窗
- `checkup-standard.html` — 体检标准化页面(左侧分类树+右侧列表)
- `item-detail-dialog.html` — 体检项目明细弹窗
- `sms-send.html` — 短信发送记录列表页
- `send-dialog.html` — 新建短信弹窗
- `sms-detail-dialog.html` — 短信发送详情弹窗
- `consult-settle.html` — 咨询结算列表页
- `report-detail-dialog.html` — 报表详情弹窗
- `doc/CHANGELOG.md` — 变更记录
- `doc/PRD.md` — 产品需求文档
**变更说明:**
- 新建小助手角色后台管理系统全部原型页面,共5个功能模块、12个HTML文件
- 整体风格复用管理员角色设计规范(顶部栏、侧边栏、表格、弹窗等)
- Logo标识改为绿色(#52C41A),角色标识"助"
- 侧边栏包含:当前咨询、历史咨询、体检标准化、短信发送、咨询结算
@@ -0,0 +1,239 @@
# 专家咨询·小助手角色 — 产品需求文档(后台管理系统)
## 模块概述
小助手角色是后台管理系统中面向健康咨询小助手的工作台,用于实时处理员工咨询、管理历史记录、查阅体检标准、发送通知短信及管理专家结算。
### 页面导航结构
```
小助手工作台
├── 当前咨询(IM对话)
├── 对话消息(内部IM
├── 历史咨询(列表)
├── 体检标准化(分类+列表)
├── 短信发送(列表)
└── 咨询结算(列表)
```
### 状态流转图
```mermaid
stateDiagram-v2
[*] --> 咨询中: 员工发起咨询
咨询中 --> 已完成: 小助手结束咨询
咨询中 --> 已转专家: 小助手推荐专家
咨询中 --> 已取消: 员工取消
已完成 --> [*]
已转专家 --> [*]
已取消 --> [*]
```
## 页面清单
| 序号 | 模块 | 页面/弹窗 | 文件 |
|------|------|-----------|------|
| 1 | 当前咨询 | 当前咨询主页面 | current-consult.html |
| 2 | | 咨询人档案弹窗 | employee-profile-dialog.html |
| 3 | | 选择专家弹窗 | select-expert-dialog.html |
| 4 | 对话消息 | 对话消息主页面 | chat-message.html |
| 5 | | 通讯录弹窗 | contacts-dialog.html |
| 6 | 历史咨询 | 历史咨询列表页 | history-consult.html |
| 7 | | 历史对话详情弹窗 | chat-detail-dialog.html |
| 8 | 体检标准化 | 体检标准化页面 | checkup-standard.html |
| 9 | | 体检项目明细弹窗 | item-detail-dialog.html |
| 10 | 短信发送 | 短信发送记录列表 | sms-send.html |
| 11 | | 新建短信弹窗 | send-dialog.html |
| 12 | | 短信发送详情弹窗 | sms-detail-dialog.html |
| 13 | 咨询结算 | 咨询结算列表页 | consult-settle.html |
| 14 | | 报表详情弹窗 | report-detail-dialog.html |
---
## 逐页说明
### 1. 当前咨询主页面
**功能说明:** IM风格左右分栏布局,左侧为正在咨询的员工对话列表,右侧为选中对话的聊天详情区。小助手在此页面实时回复员工咨询。
**业务规则:**
- 对话列表按最新消息时间倒序排列
- 未读消息显示红色角标
- 咨询状态为"咨询中"的对话才出现在此列表
**交互说明:**
- 点击左侧对话项 → 右侧切换为该员工的聊天内容
- 点击顶部「查看档案」按钮 → 打开咨询人档案弹窗
- 点击底部工具栏「发送专家」按钮 → 打开选择专家弹窗
- 选中专家确认后 → 专家卡片以消息形式发送到对话中
- 点击「结束咨询」按钮 → 结束当前咨询会话
- 底部输入框支持文字输入和发送
### 2. 咨询人档案弹窗
**功能说明:** 展示当前咨询员工的个人信息、健康概况和历史咨询记录,帮助小助手了解员工背景。
**业务规则:**
- 健康指标来源于最近一次体检数据
- 指标按正常/偏高/偏低三色标识
**交互说明:**
- 以新窗口弹窗形式打开
- 点击右上角关闭按钮 → 关闭弹窗
### 3. 选择专家弹窗
**功能说明:** 小助手为员工推荐专家时使用,展示平台所有专家列表,支持搜索和筛选。
**业务规则:**
- 专家列表显示在线状态、科室、擅长领域、咨询次数
- 支持按科室和在线状态筛选
**交互说明:**
- 点击专家行 → 选中高亮
- 底部显示已选专家姓名
- 点击「确认发送」→ 将专家卡片发送到对话框,关闭弹窗
### 4. 对话消息主页面
**功能说明:** IM风格左右分栏布局,用于小助手与内部人员(咨询专家、操作人员、专业人员、驻场人员、管理员)之间的即时通讯。左侧为消息联系人列表,右侧为选中联系人的聊天对话区。
**业务规则:**
- 消息列表按最新消息时间倒序排列
- 每个联系人显示头像、昵称、角色标签、最后一条消息预览
- 角色类型包括:咨询专家、操作人员、专业人员、驻场人员、管理员
- 未读消息显示红色角标
**交互说明:**
- 点击左侧联系人 → 右侧切换为该联系人的聊天内容
- 点击「通讯录」按钮 → 打开通讯录弹窗
- 从通讯录选中人员确认后 → 该人员添加到左侧消息列表顶部
- 搜索框支持按联系人姓名搜索
- 底部输入框支持文字输入和发送
### 5. 通讯录弹窗
**功能说明:** 展示系统内所有可联系的内部人员,支持按角色筛选和姓名搜索,选中后添加到对话消息列表。
**业务规则:**
- 人员按角色分类,不同角色显示差异化附加信息:
- 咨询专家:所在医院、科室、职称
- 操作人员:应急中心名称
- 专业人员:职称
- 驻场人员:所在医院
- 管理员:单位、部门
- 单次只能选择一位联系人
- 已存在于消息列表中的联系人不会重复添加
**交互说明:**
- 以弹窗形式打开
- 顶部搜索框输入姓名实时过滤列表
- 角色下拉框筛选指定角色的人员
- 点击人员行 → 选中高亮,右侧显示勾选标记
- 底部显示已选人数
- 点击「确认添加」→ 将选中人员添加到消息列表,关闭弹窗
- 点击「取消」→ 关闭弹窗
### 6. 历史咨询列表页
**功能说明:** 展示所有已结束的员工咨询记录,支持多条件筛选和数据导出。
**业务规则:**
- 咨询状态包括:已完成、已转专家、已取消
- 列表按发起时间倒序排列
**交互说明:**
- 筛选条件:员工姓名、工号、咨询状态、时间范围
- 点击「查询」→ 按条件过滤列表
- 点击「导出列表数据」→ 导出当前筛选结果
- 点击行末「查看对话」→ 打开历史对话详情弹窗
### 7. 历史对话详情弹窗
**功能说明:** 展示某次咨询的完整对话记录,包含咨询摘要信息和消息流。
**交互说明:**
- 顶部显示咨询单号、员工信息、状态等摘要
- 中部为完整对话消息流
- 转专家记录以黄色提示条展示
### 8. 体检标准化页面
**功能说明:** 左侧体检分类树 + 右侧项目列表,供小助手查阅体检项目明细以回答员工相关问题。
**业务规则:**
- 分类包括:一般检查、血液检查、肝功能、肾功能、血脂、血糖、甲状腺、肿瘤标志物等
- 每个项目包含编码、参考范围、单位、临床意义
**交互说明:**
- 点击左侧分类 → 右侧切换为该分类下的项目列表
- 点击行末「查看明细」→ 打开体检项目明细弹窗
### 9. 体检项目明细弹窗
**功能说明:** 展示单个体检项目的详细信息,包括参考范围、临床意义、关联套餐和注意事项。
**交互说明:**
- 以新窗口弹窗形式打开
- 参考范围以可视化条形图辅助展示
### 10. 短信发送记录列表
**功能说明:** 展示短信发送历史记录和统计概览,支持新建短信。
**业务规则:**
- 顶部统计卡片显示本月发送总量、成功数、失败数、待发送数
- 发送状态:已发送、发送失败、待发送(定时)
**交互说明:**
- 点击「新建短信」→ 打开新建短信弹窗
- 点击行末「查看详情」→ 打开短信发送详情弹窗
- 支持按状态和时间范围筛选
### 11. 新建短信弹窗
**功能说明:** 创建并发送通知短信,支持选择发送对象和定时发送。
**交互说明:**
- 发送对象支持四种模式:按单位、按部门、指定人员、全部员工
- 点击对象类型切换 → 下方选择器联动变化
- 短信内容实时字数统计(70字限制)
- 定时发送开关 → 开启后显示时间选择器
- 点击「确认发送」→ 发送短信并关闭弹窗
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|------|
| 发送对象 | 选择 | 是 | 四种模式选一 |
| 短信签名 | 下拉 | 是 | 预设签名 |
| 短信内容 | 文本域 | 是 | 不超过70字 |
| 定时发送 | 开关+时间 | 否 | 开启后必填时间 |
### 12. 短信发送详情弹窗
**功能说明:** 展示某批次短信的发送结果,包括基本信息、短信内容预览、发送统计和失败记录。
**交互说明:**
- 以新窗口弹窗形式打开
- 失败记录列出失败人员和原因
### 13. 咨询结算列表页
**功能说明:** 按月展示各专家的咨询结算数据,支持生成和下载结算报表。
**业务规则:**
- 顶部统计卡片显示待结算金额、已结算金额、年度累计、待结算专家数
- 结算状态:待结算、结算中、已结算
- 结算金额 = 图文次数×图文单价 + 视频次数×视频单价
**交互说明:**
- 点击「生成结算报表」→ 生成当月报表
- 点击「下载报表」→ 下载报表文件
- 点击行末「查看明细」→ 打开报表详情弹窗
### 14. 报表详情弹窗
**功能说明:** 展示单个专家的结算明细,包括专家信息、结算金额、咨询明细和月度趋势。
**交互说明:**
- 以新窗口弹窗形式打开
- 点击「打印结算单」→ 调用浏览器打印功能
@@ -0,0 +1,151 @@
<!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>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;}
:root{--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;--text-primary:#333;--text-secondary:#666;--border:#E8E8E8;--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--radius-sm:4px;--radius-md:8px;--shadow-sm:0 1px 4px rgba(0,0,0,0.08);}
.dialog{max-width:640px;margin:0 auto;background:#fff;min-height:100vh;}
.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px;border-bottom:1px solid var(--border);position:sticky;top:0;background:#fff;z-index:10;}
.dialog-title{font-size:var(--font-lg);font-weight:600;}
.dialog-close{background:none;border:none;font-size:20px;cursor:pointer;color:var(--text-secondary);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-sm);}
.dialog-close:hover{background:#F5F5F5;color:var(--text-primary);}
.dialog-body{padding:24px;}
/* 头部信息卡 */
.profile-header{display:flex;gap:16px;align-items:center;padding-bottom:20px;border-bottom:1px solid var(--border);margin-bottom:20px;}
.profile-avatar{width:56px;height:56px;border-radius:50%;background:var(--primary-light);color:var(--primary);display:flex;align-items:center;justify-content:center;font-size:22px;font-weight:600;flex-shrink:0;}
.profile-name{font-size:var(--font-lg);font-weight:600;}
.profile-meta{font-size:var(--font-xs);color:var(--text-secondary);margin-top:4px;}
.tag{display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:var(--font-xs);margin-left:8px;}
.tag-green{background:#F6FFED;color:var(--success);}
/* 信息区块 */
.section{margin-bottom:24px;}
.section__title{font-size:var(--font-base);font-weight:600;margin-bottom:14px;display:flex;align-items:center;gap:8px;}
.section__title::before{content:'';width:3px;height:16px;background:var(--primary);border-radius:2px;}
.info-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:12px 24px;}
.info-item{display:flex;flex-direction:column;gap:4px;}
.info-item__label{font-size:var(--font-xs);color:var(--text-secondary);}
.info-item__value{font-size:var(--font-sm);color:var(--text-primary);}
/* 健康指标 */
.health-indicators{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;}
.indicator{background:#FAFAFA;border-radius:var(--radius-md);padding:12px;text-align:center;}
.indicator__value{font-size:var(--font-lg);font-weight:700;}
.indicator__label{font-size:var(--font-xs);color:var(--text-secondary);margin-top:4px;}
.indicator--normal .indicator__value{color:var(--success);}
.indicator--warning .indicator__value{color:var(--warning);}
.indicator--danger .indicator__value{color:var(--danger);}
/* 咨询历史 */
.history-list{display:flex;flex-direction:column;gap:10px;}
.history-item{display:flex;justify-content:space-between;align-items:center;padding:10px 14px;background:#FAFAFA;border-radius:var(--radius-sm);font-size:var(--font-sm);}
.history-item__left{display:flex;flex-direction:column;gap:2px;}
.history-item__title{color:var(--text-primary);}
.history-item__time{font-size:var(--font-xs);color:var(--text-secondary);}
.history-item__type{font-size:var(--font-xs);padding:2px 6px;border-radius:8px;}
.type-expert{background:var(--primary-light);color:var(--primary);}
.type-assistant{background:#F6FFED;color:var(--success);}
</style>
</head>
<body>
<div class="dialog">
<div class="dialog-header">
<div class="dialog-title">咨询人档案</div>
</div>
<div class="dialog-body">
<!-- 头部信息 -->
<div class="profile-header">
<div class="profile-avatar"></div>
<div>
<div class="profile-name">李明 <span class="tag tag-green">在职</span></div>
<div class="profile-meta">工号:CQ002571 · 采油二厂 · 生产运行科 · 班长</div>
</div>
</div>
<!-- 基本信息 -->
<div class="section">
<div class="section__title">基本信息</div>
<div class="info-grid">
<div class="info-item"><span class="info-item__label">性别</span><span class="info-item__value"></span></div>
<div class="info-item"><span class="info-item__label">年龄</span><span class="info-item__value">38岁</span></div>
<div class="info-item"><span class="info-item__label">联系电话</span><span class="info-item__value">138****5678</span></div>
<div class="info-item"><span class="info-item__label">入职日期</span><span class="info-item__value">2012-07-01</span></div>
<div class="info-item"><span class="info-item__label">所属单位</span><span class="info-item__value">采油二厂</span></div>
<div class="info-item"><span class="info-item__label">所属部门</span><span class="info-item__value">生产运行科</span></div>
</div>
</div>
<!-- 健康概况 -->
<div class="section">
<div class="section__title">健康概况</div>
<div class="health-indicators">
<div class="indicator indicator--warning">
<div class="indicator__value">6.8</div>
<div class="indicator__label">空腹血糖(mmol/L)</div>
</div>
<div class="indicator indicator--normal">
<div class="indicator__value">125/82</div>
<div class="indicator__label">血压(mmHg)</div>
</div>
<div class="indicator indicator--normal">
<div class="indicator__value">24.5</div>
<div class="indicator__label">BMI</div>
</div>
<div class="indicator indicator--normal">
<div class="indicator__value">4.8</div>
<div class="indicator__label">总胆固醇(mmol/L)</div>
</div>
<div class="indicator indicator--warning">
<div class="indicator__value">1.9</div>
<div class="indicator__label">甘油三酯(mmol/L)</div>
</div>
<div class="indicator indicator--normal">
<div class="indicator__value">68</div>
<div class="indicator__label">心率(次/分)</div>
</div>
</div>
</div>
<!-- 最近咨询记录 -->
<div class="section">
<div class="section__title">最近咨询记录</div>
<div class="history-list">
<div class="history-item">
<div class="history-item__left">
<span class="history-item__title">空腹血糖偏高咨询</span>
<span class="history-item__time">2026-04-10 10:20</span>
</div>
<span class="history-item__type type-assistant">小助手</span>
</div>
<div class="history-item">
<div class="history-item__left">
<span class="history-item__title">体检报告解读</span>
<span class="history-item__time">2026-03-15 14:30</span>
</div>
<span class="history-item__type type-expert">专家</span>
</div>
<div class="history-item">
<div class="history-item__left">
<span class="history-item__title">颈椎不适咨询</span>
<span class="history-item__time">2026-02-20 09:10</span>
</div>
<span class="history-item__type type-assistant">小助手</span>
</div>
<div class="history-item">
<div class="history-item__left">
<span class="history-item__title">高血脂饮食建议</span>
<span class="history-item__time">2025-12-08 16:45</span>
</div>
<span class="history-item__type type-expert">专家</span>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,319 @@
<!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>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;min-width:1280px;}
:root{--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;--text-primary:#333;--text-secondary:#666;--border:#E8E8E8;--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--font-xl:20px;--radius-sm:4px;--radius-md:8px;--shadow-sm:0 1px 4px rgba(0,0,0,0.08);}
.top-bar{display:flex;align-items:center;height:56px;background:#001529;padding:0 24px;position:fixed;top:0;left:0;right:0;z-index:100;}
.top-bar__logo{display:flex;align-items:center;gap:8px;color:#fff;font-size:var(--font-lg);font-weight:600;width:240px;flex-shrink:0;white-space:nowrap;}
.top-bar__logo svg{width:28px;height:28px;}
.top-bar__nav{display:flex;align-items:center;gap:4px;flex:1;}
.top-bar__nav a{color:rgba(255,255,255,0.65);text-decoration:none;padding:6px 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);transition:all .2s;}
.top-bar__nav a:hover{color:#fff;background:rgba(255,255,255,0.08);}
.top-bar__nav a.active{color:#fff;background:var(--primary);}
.top-bar__right{display:flex;align-items:center;gap:16px;font-size:var(--font-sm);margin-left:auto;}
.btn-back{color:rgba(255,255,255,0.65);cursor:pointer;display:flex;align-items:center;gap:4px;text-decoration:none;}
.btn-back:hover{color:#fff;}
.avatar{width:32px;height:32px;border-radius:50%;background:var(--success);display:flex;align-items:center;justify-content:center;color:#fff;font-size:var(--font-sm);}
.main{margin-top:56px;padding:24px;}
.filter-bar{background:#fff;border-radius:var(--radius-md);padding:20px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:flex;align-items:center;gap:16px;flex-wrap:wrap;}
.filter-item{display:flex;align-items:center;gap:8px;}
.filter-item label{font-size:var(--font-sm);color:var(--text-secondary);white-space:nowrap;}
.filter-input{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);outline:none;background:#fff;min-width:180px;}
.filter-input:focus{border-color:var(--primary);}
.filter-select{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);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 10px center;appearance:none;min-width:120px;}
.btn{height:36px;padding:0 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;}
.btn-primary{background:var(--primary);color:#fff;}
.btn-primary:hover{background:#40a9ff;}
.btn-default{background:#fff;color:var(--text-primary);border:1px solid var(--border);}
.btn-default:hover{color:var(--primary);border-color:var(--primary);}
.table-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);overflow:hidden;}
.table-card__header{display:flex;align-items:center;justify-content:space-between;padding:16px 24px;border-bottom:1px solid var(--border);}
.table-card__title{font-size:var(--font-base);font-weight:600;}
.table-card__content{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;}
table{width:100%;border-collapse:collapse;}
thead th{background:#FAFAFA;padding:12px 16px;text-align:left;font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);white-space:nowrap;}
tbody td{padding:14px 16px;font-size:var(--font-sm);border-bottom:1px solid var(--border);white-space:nowrap;}
tbody tr:last-child td{border-bottom:none;}
tbody tr:hover{background:#F8FBFF;}
.tag{display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:var(--font-xs);}
.tag-green{background:#F6FFED;color:var(--success);}
.tag-blue{background:var(--primary-light);color:var(--primary);}
.tag-gray{background:#F5F5F5;color:var(--text-secondary);}
.tag-orange{background:#FFF7E6;color:var(--warning);}
.link{color:var(--primary);cursor:pointer;font-size:var(--font-sm);}
.link:hover{color:#40a9ff;}
.org-select-wrap{position:relative;display:inline-block;}
.org-trigger{height:36px;min-width:160px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);color:var(--text-primary);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 10px center;cursor:pointer;display:flex;align-items:center;user-select:none;white-space:nowrap;}
.org-trigger.open,.org-trigger:hover{border-color:var(--primary);}
.org-panel{display:none;position:absolute;top:40px;left:0;z-index:300;background:#fff;border:1px solid var(--border);border-radius:var(--radius-sm);box-shadow:0 2px 8px rgba(0,0,0,0.12);width:420px;}
.org-panel.open{display:flex;}
.org-col{flex:1;overflow-y:auto;max-height:240px;border-right:1px solid var(--border);}
.org-col:last-child{border-right:none;}
.org-col__title{padding:8px 14px;font-size:var(--font-xs);color:#999;background:#FAFAFA;border-bottom:1px solid var(--border);font-weight:500;}
.org-item{padding:9px 14px;font-size:var(--font-sm);color:var(--text-primary);cursor:pointer;display:flex;align-items:center;justify-content:space-between;gap:4px;}
.org-item:hover{background:#F0F8FF;color:var(--primary);}
.org-item.active{background:#E6F7FF;color:var(--primary);font-weight:500;}
.org-item svg{flex-shrink:0;opacity:.45;}
.org-item.active svg{opacity:1;}
.pagination{display:flex;align-items:center;justify-content:flex-end;padding:16px 24px;gap:8px;border-top:1px solid var(--border);}
.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);}
/* 模态弹窗(iframe覆盖层) */
.overlay-modal{display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.45);z-index:1000;align-items:center;justify-content:center;}
.overlay-modal.open{display:flex;}
.overlay-modal__box{background:#fff;border-radius:var(--radius-md);overflow:hidden;box-shadow:0 4px 16px rgba(0,0,0,0.15);position:relative;max-height:90vh;display:flex;flex-direction:column;}
.overlay-modal__close{position:absolute;top:12px;right:12px;width:32px;height:32px;border-radius:50%;background:rgba(0,0,0,0.04);border:none;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#999;z-index:10;transition:all .15s;}
.overlay-modal__close:hover{background:rgba(0,0,0,0.08);color:#333;}
.overlay-modal iframe{border:none;display:block;}
</style>
</head>
<body>
<div class="top-bar">
<div class="top-bar__logo">
<svg viewBox="0 0 28 28" fill="none"><rect width="28" height="28" rx="6" fill="#52C41A"/><path d="M9 14.5l3 3 7-7" stroke="#fff" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
专家咨询–小助手
</div>
<nav class="top-bar__nav">
<a href="current-consult.html">当前咨询</a>
<a href="chat-message.html">对话消息</a>
<a href="history-consult.html" class="active">历史咨询</a>
<a href="checkup-standard.html">体检标准化</a>
<a href="sms-send.html">短信发送</a>
<a href="consult-settle.html">咨询结算</a>
</nav>
<div class="top-bar__right">
<a class="btn-back" href="../../index.html"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>返回首页</a>
<div class="avatar"></div>
<span style="color:rgba(255,255,255,0.65);">健康小助手 ▾</span>
</div>
</div>
<main class="main">
<div class="filter-bar">
<div class="filter-item">
<label>咨询单号</label>
<input class="filter-input" type="text" placeholder="请输入咨询单号">
</div>
<div class="filter-item">
<label>姓名</label>
<input class="filter-input" type="text" placeholder="请输入姓名">
</div>
<div class="filter-item">
<label>员工编号</label>
<input class="filter-input" type="text" placeholder="请输入员工编号">
</div>
<div class="filter-item">
<label style="white-space:nowrap;">所属单位部门</label>
<div class="org-select-wrap" id="orgWrap">
<div class="org-trigger" id="orgTrigger" onclick="toggleOrg()">全部单位/部门</div>
<div class="org-panel" id="orgPanel">
<div class="org-col" id="orgUnitCol">
<div class="org-col__title">单位</div>
<div class="org-item active" data-unit="" onclick="selectUnit(this,'全部单位/部门','')">全部单位/部门</div>
<div class="org-item" data-unit="cy1" onclick="selectUnit(this,'采油一厂','cy1')">采油一厂</div>
<div class="org-item" data-unit="cy2" onclick="selectUnit(this,'采油二厂','cy2')">采油二厂</div>
<div class="org-item" data-unit="cy3" onclick="selectUnit(this,'采油三厂','cy3')">采油三厂</div>
<div class="org-item" data-unit="kfyj" onclick="selectUnit(this,'勘探开发研究院','kfyj')">勘探开发研究院</div>
<div class="org-item" data-unit="jgsh" onclick="selectUnit(this,'机关事务服务中心','jgsh')">机关事务服务中心</div>
</div>
<div class="org-col" id="orgDeptCol">
<div class="org-col__title">部门</div>
<div class="org-item active" data-dept="" onclick="selectDept(this,'全部部门','')">全部部门</div>
</div>
</div>
</div>
</div>
<div class="filter-item">
<label>发起咨询时间</label>
<input class="filter-input" type="date" style="min-width:140px;">
<span style="color:var(--text-secondary);font-size:var(--font-sm);"></span>
<input class="filter-input" type="date" style="min-width:140px;">
</div>
<button class="btn btn-primary"><svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4" stroke="currentColor" stroke-width="1.4"/><path d="M10 10l2.5 2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>查询</button>
<button class="btn btn-default">重置</button>
</div>
<div style="display:flex;gap:12px;margin-bottom:16px;">
<button class="btn btn-default"><svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 10v2h10v-2M7 2v7M4.5 6.5L7 9l2.5-2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>导出列表数据</button>
<button class="btn btn-default"><svg width="14" height="14" viewBox="0 0 14 14" fill="none"><rect x="2" y="2" width="10" height="10" rx="1.5" stroke="currentColor" stroke-width="1.4"/><path d="M4 5h6M4 7.5h4" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>查看导出任务</button>
</div>
<div class="table-card">
<div class="table-card__header">
<div class="table-card__title">咨询记录列表</div>
<div style="font-size:var(--font-sm);color:var(--text-secondary);">共 38,920 条</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 style="font-family:monospace;color:var(--text-secondary);">ZX20260409001</td>
<td>张伟</td>
<td style="font-family:monospace;color:var(--text-secondary);">EMP001</td>
<td>采油一厂</td>
<td>心血管科</td>
<td>健康小助手</td>
<td><span class="tag tag-gray">已结束</span></td>
<td>2026-04-09 08:30</td>
<td>2026-04-09 08:35</td>
<td>2026-04-09 08:38</td>
<td>8分钟</td>
<td><span class="link" onclick="openOverlay('chat-detail-dialog.html',720,680)">查看对话</span></td>
</tr>
<tr>
<td style="font-family:monospace;color:var(--text-secondary);">ZX20260409002</td>
<td>李明</td>
<td style="font-family:monospace;color:var(--text-secondary);">EMP002</td>
<td>采油二厂</td>
<td>内分泌科</td>
<td>健康小助手</td>
<td><span class="tag tag-blue">进行中</span></td>
<td>2026-04-09 09:45</td>
<td>2026-04-09 09:50</td>
<td></td>
<td>15分钟</td>
<td><span class="link" onclick="openOverlay('chat-detail-dialog.html',720,680)">查看对话</span></td>
</tr>
<tr>
<td style="font-family:monospace;color:var(--text-secondary);">ZX20260409003</td>
<td>王芳</td>
<td style="font-family:monospace;color:var(--text-secondary);">EMP003</td>
<td>勘探开发研究院</td>
<td>医学研究部</td>
<td>健康小助手</td>
<td><span class="tag tag-gray">已结束</span></td>
<td>2026-04-09 10:12</td>
<td>2026-04-09 10:14</td>
<td>2026-04-09 10:15</td>
<td>3分钟</td>
<td><span class="link" onclick="openOverlay('chat-detail-dialog.html',720,680)">查看对话</span></td>
</tr>
<tr>
<td style="font-family:monospace;color:var(--text-secondary);">ZX20260408004</td>
<td>刘洋</td>
<td style="font-family:monospace;color:var(--text-secondary);">EMP004</td>
<td>采油三厂</td>
<td>生产部</td>
<td>健康小助手</td>
<td><span class="tag tag-orange">待回复</span></td>
<td>2026-04-08 14:55</td>
<td></td>
<td></td>
<td>6分钟</td>
<td><span class="link" onclick="openOverlay('chat-detail-dialog.html',720,680)">查看对话</span></td>
</tr>
<tr>
<td style="font-family:monospace;color:var(--text-secondary);">ZX20260408005</td>
<td>赵静</td>
<td style="font-family:monospace;color:var(--text-secondary);">EMP005</td>
<td>机关事务服务中心</td>
<td>行政部</td>
<td>健康小助手</td>
<td><span class="tag tag-gray">已结束</span></td>
<td>2026-04-08 16:20</td>
<td>2026-04-08 16:22</td>
<td>2026-04-08 16:24</td>
<td>4分钟</td>
<td><span class="link" onclick="openOverlay('chat-detail-dialog.html',720,680)">查看对话</span></td>
</tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>共 38,920 条</span>
<button class="page-btn"></button>
<button class="page-btn active">1</button>
<button class="page-btn">2</button>
<button class="page-btn">3</button>
<span>...</span>
<button class="page-btn">3892</button>
<button class="page-btn"></button>
<select class="filter-select" style="min-width:70px;height:32px;"><option>10条</option><option>20条</option></select>
</div>
</div>
</main>
<!-- 模态弹窗容器 -->
<div class="overlay-modal" id="overlayModal" onclick="if(event.target===this)closeOverlay()">
<div class="overlay-modal__box" id="overlayBox">
<button class="overlay-modal__close" onclick="closeOverlay()"></button>
<iframe id="overlayFrame" src=""></iframe>
</div>
</div>
<script>
function openOverlay(url, w, h) {
var box = document.getElementById('overlayBox');
box.style.width = w + 'px';
var frame = document.getElementById('overlayFrame');
frame.style.width = w + 'px';
frame.style.height = h + 'px';
frame.src = url;
document.getElementById('overlayModal').classList.add('open');
document.body.style.overflow = 'hidden';
}
function closeOverlay() {
document.getElementById('overlayModal').classList.remove('open');
document.getElementById('overlayFrame').src = '';
document.body.style.overflow = '';
}
window.addEventListener('message', function(e) {
if (e.data === 'close-dialog') closeOverlay();
});
// 单位部门级联选择
const deptMap = {
'cy1': ['心血管科', '内分泌科', '神经内科'],
'cy2': ['骨科', '消化内科', '呼吸科'],
'cy3': ['生产部', '技术部', '安全部'],
'kfyj': ['医学研究部', '数据分析部'],
'jgsh': ['行政部', '人力资源部']
};
function toggleOrg() {
document.getElementById('orgPanel').classList.toggle('open');
document.getElementById('orgTrigger').classList.toggle('open');
}
function selectUnit(elem, unitName, unitCode) {
document.querySelectorAll('#orgUnitCol .org-item').forEach(i => i.classList.remove('active'));
elem.classList.add('active');
var depts = deptMap[unitCode] || [];
var html = '<div class="org-col__title">部门</div>';
html += '<div class="org-item active" data-dept="" onclick="selectDept(this,\'全部部门\',\'\')">全部部门</div>';
depts.forEach(function(d) {
html += '<div class="org-item" data-dept="' + d + '" onclick="selectDept(this,\'' + d + '\',\'' + d + '\')">' + d + '</div>';
});
document.getElementById('orgDeptCol').innerHTML = html;
}
function selectDept(elem, deptName, deptCode) {
document.querySelectorAll('#orgDeptCol .org-item').forEach(i => i.classList.remove('active'));
elem.classList.add('active');
}
document.addEventListener('click', function(e) {
var wrap = document.getElementById('orgWrap');
if (wrap && !wrap.contains(e.target)) {
document.getElementById('orgPanel').classList.remove('open');
document.getElementById('orgTrigger').classList.remove('open');
}
});
</script>
</body>
</html>
@@ -0,0 +1,86 @@
<!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>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;}
:root{--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--text-primary:#333;--text-secondary:#666;--border:#E8E8E8;--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--radius-sm:4px;--radius-md:8px;--shadow-sm:0 1px 4px rgba(0,0,0,0.08);}
.dialog{max-width:560px;margin:0 auto;background:#fff;min-height:100vh;}
.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px;border-bottom:1px solid var(--border);position:sticky;top:0;background:#fff;z-index:10;}
.dialog-title{font-size:var(--font-lg);font-weight:600;}
.dialog-close{background:none;border:none;font-size:20px;cursor:pointer;color:var(--text-secondary);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-sm);}
.dialog-close:hover{background:#F5F5F5;color:var(--text-primary);}
.dialog-body{padding:24px;}
.section{margin-bottom:24px;}
.section:last-child{margin-bottom:0;}
.section__title{font-size:var(--font-base);font-weight:600;margin-bottom:14px;display:flex;align-items:center;gap:8px;}
.section__title::before{content:'';width:3px;height:16px;background:var(--primary);border-radius:2px;}
.info-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:12px 24px;}
.info-item{display:flex;flex-direction:column;gap:4px;}
.info-item__label{font-size:var(--font-xs);color:var(--text-secondary);}
.info-item__value{font-size:var(--font-sm);color:var(--text-primary);}
.info-item--full{grid-column:1/-1;}
.ref-bar{display:flex;align-items:center;gap:8px;margin-top:8px;}
.ref-bar__track{flex:1;height:8px;background:#F0F0F0;border-radius:4px;position:relative;overflow:hidden;}
.ref-bar__fill{position:absolute;left:20%;right:20%;top:0;bottom:0;background:#E6F7FF;border-radius:4px;}
.ref-bar__label{font-size:var(--font-xs);color:var(--text-secondary);white-space:nowrap;}
.desc-text{font-size:var(--font-sm);color:var(--text-secondary);line-height:1.8;}
.tag-list{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px;}
.tag{display:inline-flex;align-items:center;padding:4px 10px;border-radius:12px;font-size:var(--font-xs);}
.tag-blue{background:var(--primary-light);color:var(--primary);}
</style>
</head>
<body>
<div class="dialog">
<div class="dialog-header">
<div class="dialog-title">体检项目明细</div>
</div>
<div class="dialog-body">
<div class="section">
<div class="section__title">基本信息</div>
<div class="info-grid">
<div class="info-item"><span class="info-item__label">项目名称</span><span class="info-item__value">BMI(体质指数)</span></div>
<div class="info-item"><span class="info-item__label">项目编码</span><span class="info-item__value" style="font-family:monospace;">GE003</span></div>
<div class="info-item"><span class="info-item__label">所属分类</span><span class="info-item__value">一般检查</span></div>
<div class="info-item"><span class="info-item__label">检测单位</span><span class="info-item__value">kg/m²</span></div>
</div>
</div>
<div class="section">
<div class="section__title">参考范围</div>
<div class="info-grid">
<div class="info-item"><span class="info-item__label">正常范围</span><span class="info-item__value">18.5 ~ 23.9 kg/m²</span></div>
<div class="info-item"><span class="info-item__label">偏低</span><span class="info-item__value" style="color:var(--primary);">&lt; 18.5</span></div>
<div class="info-item"><span class="info-item__label">超重</span><span class="info-item__value" style="color:var(--warning);">24.0 ~ 27.9</span></div>
<div class="info-item"><span class="info-item__label">肥胖</span><span class="info-item__value" style="color:#FF4D4F;">≥ 28.0</span></div>
</div>
<div class="ref-bar">
<span class="ref-bar__label">偏低</span>
<div class="ref-bar__track"><div class="ref-bar__fill"></div></div>
<span class="ref-bar__label">肥胖</span>
</div>
</div>
<div class="section">
<div class="section__title">临床意义</div>
<div class="desc-text">BMI是国际上常用的衡量人体胖瘦程度以及是否健康的一个标准。BMI值偏高与高血压、糖尿病、心血管疾病等慢性病风险增加密切相关。BMI偏低则可能提示营养不良或其他消耗性疾病。</div>
</div>
<div class="section">
<div class="section__title">关联体检套餐</div>
<div class="tag-list">
<span class="tag tag-blue">基础套餐A</span>
<span class="tag tag-blue">标准套餐B</span>
<span class="tag tag-blue">高端套餐C</span>
<span class="tag tag-blue">入职体检</span>
<span class="tag tag-blue">年度体检</span>
</div>
</div>
<div class="section">
<div class="section__title">注意事项</div>
<div class="desc-text">1. 测量前应脱去外套和鞋子<br>2. 建议在早晨空腹状态下测量<br>3. BMI不适用于运动员、孕妇等特殊人群<br>4. 需结合腰围、体脂率等指标综合评估</div>
</div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,101 @@
<!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>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;}
:root{--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;--text-primary:#333;--text-secondary:#666;--border:#E8E8E8;--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--radius-sm:4px;--radius-md:8px;--shadow-sm:0 1px 4px rgba(0,0,0,0.08);}
.dialog{max-width:640px;margin:0 auto;background:#fff;min-height:100vh;}
.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px;border-bottom:1px solid var(--border);position:sticky;top:0;background:#fff;z-index:10;}
.dialog-title{font-size:var(--font-lg);font-weight:600;}
.dialog-close{background:none;border:none;font-size:20px;cursor:pointer;color:var(--text-secondary);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-sm);}
.dialog-close:hover{background:#F5F5F5;color:var(--text-primary);}
.dialog-body{padding:24px;}
.section{margin-bottom:24px;}
.section__title{font-size:var(--font-base);font-weight:600;margin-bottom:14px;display:flex;align-items:center;gap:8px;}
.section__title::before{content:'';width:3px;height:16px;background:var(--primary);border-radius:2px;}
/* 专家信息头 */
.expert-header{display:flex;gap:16px;align-items:center;padding-bottom:20px;border-bottom:1px solid var(--border);margin-bottom:20px;}
.expert-avatar{width:52px;height:52px;border-radius:50%;background:var(--primary-light);color:var(--primary);display:flex;align-items:center;justify-content:center;font-size:20px;font-weight:600;flex-shrink:0;}
.expert-name{font-size:var(--font-lg);font-weight:600;}
.expert-meta{font-size:var(--font-xs);color:var(--text-secondary);margin-top:4px;}
.tag{display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:var(--font-xs);margin-left:8px;}
.tag-orange{background:#FFF7E6;color:var(--warning);}
.info-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:12px 24px;}
.info-item{display:flex;flex-direction:column;gap:4px;}
.info-item__label{font-size:var(--font-xs);color:var(--text-secondary);}
.info-item__value{font-size:var(--font-sm);color:var(--text-primary);}
/* 结算明细表 */
table{width:100%;border-collapse:collapse;margin-top:12px;}
thead th{background:#FAFAFA;padding:10px 14px;text-align:left;font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);}
tbody td{padding:10px 14px;font-size:var(--font-sm);border-bottom:1px solid var(--border);}
tbody tr:last-child td{border-bottom:none;}
tfoot td{padding:10px 14px;font-size:var(--font-sm);font-weight:600;border-top:2px solid var(--border);background:#FAFAFA;}
.amount-highlight{font-size:var(--font-lg);font-weight:700;color:var(--warning);}
.btn{height:36px;padding:0 20px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;}
.btn-default{background:#fff;color:var(--text-primary);border:1px solid var(--border);width:100%;justify-content:center;}
.btn-default:hover{color:var(--primary);border-color:var(--primary);}
</style>
</head>
<body>
<div class="dialog">
<div class="dialog-header">
<div class="dialog-title">结算明细</div>
</div>
<div class="dialog-body">
<div class="expert-header">
<div class="expert-avatar"></div>
<div>
<div class="expert-name">李医生 <span class="tag tag-orange">待结算</span></div>
<div class="expert-meta">心血管内科 · 主任医师 · 西京医院</div>
</div>
</div>
<div class="section">
<div class="section__title">结算信息</div>
<div class="info-grid">
<div class="info-item"><span class="info-item__label">结算周期</span><span class="info-item__value">2026年4月</span></div>
<div class="info-item"><span class="info-item__label">结算状态</span><span class="info-item__value" style="color:var(--warning);">待结算</span></div>
<div class="info-item"><span class="info-item__label">应结算金额</span><span class="info-item__value amount-highlight">¥ 16,240</span></div>
<div class="info-item"><span class="info-item__label">生成时间</span><span class="info-item__value">2026-04-10 00:00</span></div>
</div>
</div>
<div class="section">
<div class="section__title">咨询明细</div>
<table>
<thead><tr><th>咨询类型</th><th>咨询次数</th><th>单价</th><th>小计</th></tr></thead>
<tbody>
<tr><td>图文咨询</td><td>312 次</td><td>¥ 30</td><td style="font-weight:600;">¥ 9,360</td></tr>
<tr><td>视频咨询</td><td>86 次</td><td>¥ 80</td><td style="font-weight:600;">¥ 6,880</td></tr>
</tbody>
<tfoot><tr><td colspan="3">合计</td><td style="color:var(--warning);font-size:var(--font-base);">¥ 16,240</td></tr></tfoot>
</table>
</div>
<div class="section">
<div class="section__title">月度咨询趋势</div>
<div class="info-grid">
<div class="info-item"><span class="info-item__label">总咨询次数</span><span class="info-item__value">398 次</span></div>
<div class="info-item"><span class="info-item__label">日均咨询</span><span class="info-item__value">39.8 次</span></div>
<div class="info-item"><span class="info-item__label">满意度</span><span class="info-item__value" style="color:var(--success);">4.8 / 5.0</span></div>
<div class="info-item"><span class="info-item__label">24h回复率</span><span class="info-item__value" style="color:var(--success);">98.5%</span></div>
</div>
</div>
<button class="btn btn-default" onclick="window.print()">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M3 5V2h8v3M3 9H1V5h12v4h-2M3 9v3h8V9" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/></svg>
打印结算单
</button>
</div>
</div>
</body>
</html>
@@ -0,0 +1,179 @@
<!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>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;}
:root{--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;--text-primary:#333;--text-secondary:#666;--border:#E8E8E8;--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--radius-sm:4px;--radius-md:8px;--shadow-sm:0 1px 4px rgba(0,0,0,0.08);}
.dialog{max-width:680px;margin:0 auto;background:#fff;min-height:100vh;}
.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px;border-bottom:1px solid var(--border);position:sticky;top:0;background:#fff;z-index:10;}
.dialog-title{font-size:var(--font-lg);font-weight:600;}
.dialog-close{background:none;border:none;font-size:20px;cursor:pointer;color:var(--text-secondary);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-sm);}
.dialog-close:hover{background:#F5F5F5;color:var(--text-primary);}
/* 筛选区 */
.filter-bar{padding:16px 24px;border-bottom:1px solid var(--border);display:flex;gap:12px;flex-wrap:wrap;align-items:center;}
.filter-input{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px 0 36px;font-size:var(--font-sm);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='none'%3E%3Ccircle cx='6' cy='6' r='4' stroke='%23999' stroke-width='1.4'/%3E%3Cpath d='M10 10l2.5 2.5' stroke='%23999' stroke-width='1.4' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat 12px center;flex:1;min-width:180px;}
.filter-input:focus{border-color:var(--primary);}
.filter-select{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);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 10px center;appearance:none;min-width:120px;}
/* 专家列表 */
.expert-list{padding:0 24px;}
.expert-item{display:flex;align-items:center;gap:14px;padding:16px 0;border-bottom:1px solid #F5F5F5;cursor:pointer;transition:background .15s;margin:0 -24px;padding-left:24px;padding-right:24px;}
.expert-item:hover{background:#FAFAFA;}
.expert-item.selected{background:var(--primary-light);}
.expert-avatar{width:44px;height:44px;border-radius:50%;background:var(--primary-light);color:var(--primary);display:flex;align-items:center;justify-content:center;font-size:var(--font-base);font-weight:600;flex-shrink:0;}
.expert-info{flex:1;min-width:0;}
.expert-name{font-size:var(--font-sm);font-weight:500;}
.expert-detail{font-size:var(--font-xs);color:var(--text-secondary);margin-top:3px;}
.expert-tags{display:flex;gap:6px;margin-top:4px;}
.tag{display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:var(--font-xs);}
.tag-green{background:#F6FFED;color:var(--success);}
.tag-gray{background:#F5F5F5;color:var(--text-secondary);}
.tag-blue{background:var(--primary-light);color:var(--primary);}
.expert-stats{text-align:right;flex-shrink:0;}
.expert-stats__num{font-size:var(--font-base);font-weight:600;color:var(--primary);}
.expert-stats__label{font-size:var(--font-xs);color:var(--text-secondary);}
.btn{height:36px;padding:0 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;}
.btn-primary{background:var(--primary);color:#fff;}
.btn-primary:hover{background:#40a9ff;}
.btn-sm{height:30px;padding:0 12px;font-size:var(--font-xs);}
/* 底部操作栏 */
.dialog-footer{position:sticky;bottom:0;background:#fff;border-top:1px solid var(--border);padding:16px 24px;display:flex;align-items:center;justify-content:space-between;}
.selected-info{font-size:var(--font-sm);color:var(--text-secondary);}
.selected-info strong{color:var(--primary);}
</style>
</head>
<body>
<div class="dialog">
<div class="dialog-header">
<div class="dialog-title">选择专家</div>
</div>
<div class="filter-bar">
<input class="filter-input" type="text" placeholder="搜索专家姓名、医院、科室">
<select class="filter-select">
<option>全部科室</option>
<option>内分泌科</option>
<option>心血管内科</option>
<option>神经内科</option>
<option>骨科</option>
<option>消化内科</option>
</select>
<select class="filter-select" style="min-width:100px;">
<option>全部状态</option>
<option>在线</option>
<option>离线</option>
</select>
<select class="filter-select" style="min-width:130px;">
<option>擅长疾病类型</option>
<option>糖尿病</option>
<option>甲状腺</option>
<option>高血压</option>
<option>冠心病</option>
<option>头痛/眩晕</option>
<option>颈椎病/腰椎</option>
<option>胃病/肝胆</option>
</select>
</div>
<div class="expert-list">
<!-- [交互] 点击选中专家,高亮显示 -->
<div class="expert-item selected" onclick="selectExpert(this)">
<div class="expert-avatar"></div>
<div class="expert-info">
<div class="expert-name">王医生 · 主任医师</div>
<div class="expert-detail">北京协和医院 · 内分泌科</div>
<div class="expert-tags">
<span class="tag tag-green">在线</span>
<span class="tag tag-blue">糖尿病</span>
<span class="tag tag-blue">甲状腺</span>
</div>
</div>
<div class="expert-stats">
<div class="expert-stats__num">1,286</div>
<div class="expert-stats__label">咨询次数</div>
</div>
</div>
<div class="expert-item" onclick="selectExpert(this)">
<div class="expert-avatar"></div>
<div class="expert-info">
<div class="expert-name">李医生 · 主任医师</div>
<div class="expert-detail">西京医院 · 心血管内科</div>
<div class="expert-tags">
<span class="tag tag-green">在线</span>
<span class="tag tag-blue">高血压</span>
<span class="tag tag-blue">冠心病</span>
</div>
</div>
<div class="expert-stats">
<div class="expert-stats__num">2,045</div>
<div class="expert-stats__label">咨询次数</div>
</div>
</div>
<div class="expert-item" onclick="selectExpert(this)">
<div class="expert-avatar"></div>
<div class="expert-info">
<div class="expert-name">张医生 · 副主任医师</div>
<div class="expert-detail">唐都医院 · 神经内科</div>
<div class="expert-tags">
<span class="tag tag-green">在线</span>
<span class="tag tag-blue">头痛</span>
<span class="tag tag-blue">眩晕</span>
</div>
</div>
<div class="expert-stats">
<div class="expert-stats__num">876</div>
<div class="expert-stats__label">咨询次数</div>
</div>
</div>
<div class="expert-item" onclick="selectExpert(this)">
<div class="expert-avatar"></div>
<div class="expert-info">
<div class="expert-name">陈医生 · 主治医师</div>
<div class="expert-detail">长庆医院 · 骨科</div>
<div class="expert-tags">
<span class="tag tag-gray">离线</span>
<span class="tag tag-blue">颈椎病</span>
<span class="tag tag-blue">腰椎间盘</span>
</div>
</div>
<div class="expert-stats">
<div class="expert-stats__num">654</div>
<div class="expert-stats__label">咨询次数</div>
</div>
</div>
<div class="expert-item" onclick="selectExpert(this)">
<div class="expert-avatar"></div>
<div class="expert-info">
<div class="expert-name">孙医生 · 副主任医师</div>
<div class="expert-detail">西安交大一附院 · 消化内科</div>
<div class="expert-tags">
<span class="tag tag-green">在线</span>
<span class="tag tag-blue">胃病</span>
<span class="tag tag-blue">肝胆</span>
</div>
</div>
<div class="expert-stats">
<div class="expert-stats__num">1,102</div>
<div class="expert-stats__label">咨询次数</div>
</div>
</div>
</div>
<!-- [交互] 点击确认发送,将选中专家卡片发送到对话框 -->
<div class="dialog-footer">
<div class="selected-info">已选择:<strong id="selectedName">王医生</strong></div>
<button class="btn btn-primary" onclick="parent.postMessage('close-dialog','*')">确认发送</button>
</div>
</div>
<script>
function selectExpert(el) {
document.querySelectorAll('.expert-item').forEach(i => i.classList.remove('selected'));
el.classList.add('selected');
document.getElementById('selectedName').textContent = el.querySelector('.expert-name').textContent.split('·')[0].trim();
}
</script>
</body>
</html>
@@ -0,0 +1,113 @@
<!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>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;}
:root{--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;--text-primary:#333;--text-secondary:#666;--border:#E8E8E8;--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--radius-sm:4px;--radius-md:8px;--shadow-sm:0 1px 4px rgba(0,0,0,0.08);}
.dialog{max-width:600px;margin:0 auto;background:#fff;min-height:100vh;}
.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px;border-bottom:1px solid var(--border);position:sticky;top:0;background:#fff;z-index:10;}
.dialog-title{font-size:var(--font-lg);font-weight:600;}
.dialog-close{background:none;border:none;font-size:20px;cursor:pointer;color:var(--text-secondary);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-sm);}
.dialog-close:hover{background:#F5F5F5;color:var(--text-primary);}
.dialog-body{padding:24px;}
.form-item{margin-bottom:20px;}
.form-item__label{font-size:var(--font-sm);font-weight:500;margin-bottom:8px;display:flex;align-items:center;gap:4px;}
.form-item__label .required{color:var(--danger);}
.form-input{width:100%;height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);outline:none;}
.form-input:focus{border-color:var(--primary);}
.form-select{width:100%;height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);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 10px center;appearance:none;}
.form-textarea{width:100%;border:1px solid var(--border);border-radius:var(--radius-sm);padding:10px 12px;font-size:var(--font-sm);outline:none;resize:vertical;font-family:inherit;line-height:1.6;min-height:120px;}
.form-textarea:focus{border-color:var(--primary);}
.form-hint{font-size:var(--font-xs);color:var(--text-secondary);margin-top:6px;}
.char-count{text-align:right;font-size:var(--font-xs);color:var(--text-secondary);margin-top:4px;}
/* 发送对象选择 */
.target-type{display:flex;gap:12px;margin-bottom:12px;}
.target-type__item{flex:1;padding:12px;border:1px solid var(--border);border-radius:var(--radius-sm);text-align:center;cursor:pointer;font-size:var(--font-sm);transition:all .15s;}
.target-type__item:hover{border-color:var(--primary);color:var(--primary);}
.target-type__item.active{border-color:var(--primary);background:var(--primary-light);color:var(--primary);font-weight:500;}
/* 定时发送 */
.schedule-row{display:flex;align-items:center;gap:12px;}
.switch{position:relative;width:40px;height:22px;background:#D9D9D9;border-radius:11px;cursor:pointer;transition:background .2s;flex-shrink:0;}
.switch.on{background:var(--primary);}
.switch::after{content:'';position:absolute;top:2px;left:2px;width:18px;height:18px;background:#fff;border-radius:50%;transition:left .2s;}
.switch.on::after{left:20px;}
.dialog-footer{padding:16px 24px;border-top:1px solid var(--border);display:flex;justify-content:flex-end;gap:12px;position:sticky;bottom:0;background:#fff;}
.btn{height:36px;padding:0 20px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;}
.btn-primary{background:var(--primary);color:#fff;}.btn-primary:hover{background:#40a9ff;}
.btn-default{background:#fff;color:var(--text-primary);border:1px solid var(--border);}.btn-default:hover{color:var(--primary);border-color:var(--primary);}
</style>
</head>
<body>
<div class="dialog">
<div class="dialog-header">
<div class="dialog-title">新建短信</div>
</div>
<div class="dialog-body">
<div class="form-item">
<div class="form-item__label"><span class="required">*</span> 发送对象</div>
<div class="target-type">
<div class="target-type__item active" onclick="selectTarget(this)">按单位</div>
<div class="target-type__item" onclick="selectTarget(this)">按部门</div>
<div class="target-type__item" onclick="selectTarget(this)">指定人员</div>
<div class="target-type__item" onclick="selectTarget(this)">全部员工</div>
</div>
<select class="form-select">
<option>请选择单位</option>
<option>采油一厂</option>
<option>采油二厂</option>
<option>采油三厂</option>
<option>勘探开发研究院</option>
<option>机关事务服务中心</option>
</select>
</div>
<div class="form-item">
<div class="form-item__label"><span class="required">*</span> 短信签名</div>
<select class="form-select">
<option>【健康长庆】</option>
<option>【长庆油田】</option>
</select>
</div>
<div class="form-item">
<div class="form-item__label"><span class="required">*</span> 短信内容</div>
<textarea class="form-textarea" placeholder="请输入短信内容,单条短信不超过70个字" oninput="updateCount(this)">您的体检报告已出,请登录健康长庆APP查看详情。如有疑问请咨询健康小助手。</textarea>
<div class="char-count"><span id="charCount">38</span> / 70 字</div>
<div class="form-hint">短信内容超过70字将按多条计费</div>
</div>
<div class="form-item">
<div class="form-item__label">定时发送</div>
<div class="schedule-row">
<div class="switch" id="scheduleSwitch" onclick="toggleSwitch(this)"></div>
<input class="form-input" type="datetime-local" style="flex:1;opacity:0.4;" id="scheduleTime" disabled>
</div>
<div class="form-hint">开启后短信将在指定时间自动发送</div>
</div>
</div>
<div class="dialog-footer">
<button class="btn btn-default" onclick="parent.postMessage('close-dialog','*')">取消</button>
<button class="btn btn-primary">确认发送</button>
</div>
</div>
<script>
function selectTarget(el){
document.querySelectorAll('.target-type__item').forEach(i=>i.classList.remove('active'));
el.classList.add('active');
}
function toggleSwitch(el){
el.classList.toggle('on');
var t=document.getElementById('scheduleTime');
t.disabled=!el.classList.contains('on');
t.style.opacity=el.classList.contains('on')?'1':'0.4';
}
function updateCount(el){
document.getElementById('charCount').textContent=el.value.length;
}
</script>
</body>
</html>
@@ -0,0 +1,84 @@
<!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>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;}
:root{--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;--text-primary:#333;--text-secondary:#666;--border:#E8E8E8;--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--radius-sm:4px;--radius-md:8px;--shadow-sm:0 1px 4px rgba(0,0,0,0.08);}
.dialog{max-width:600px;margin:0 auto;background:#fff;min-height:100vh;}
.dialog-header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px;border-bottom:1px solid var(--border);position:sticky;top:0;background:#fff;z-index:10;}
.dialog-title{font-size:var(--font-lg);font-weight:600;}
.dialog-close{background:none;border:none;font-size:20px;cursor:pointer;color:var(--text-secondary);width:28px;height:28px;display:flex;align-items:center;justify-content:center;border-radius:var(--radius-sm);}
.dialog-close:hover{background:#F5F5F5;color:var(--text-primary);}
.dialog-body{padding:24px;}
.section{margin-bottom:24px;}
.section__title{font-size:var(--font-base);font-weight:600;margin-bottom:14px;display:flex;align-items:center;gap:8px;}
.section__title::before{content:'';width:3px;height:16px;background:var(--primary);border-radius:2px;}
.info-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:12px 24px;}
.info-item{display:flex;flex-direction:column;gap:4px;}
.info-item__label{font-size:var(--font-xs);color:var(--text-secondary);}
.info-item__value{font-size:var(--font-sm);color:var(--text-primary);}
.info-item--full{grid-column:1/-1;}
.sms-preview{background:#FAFAFA;border-radius:var(--radius-md);padding:16px;font-size:var(--font-sm);line-height:1.8;color:var(--text-primary);border:1px solid var(--border);}
.stat-row{display:flex;gap:16px;margin-top:12px;}
.stat-block{flex:1;background:#FAFAFA;border-radius:var(--radius-sm);padding:12px;text-align:center;}
.stat-block__value{font-size:var(--font-lg);font-weight:700;}
.stat-block__label{font-size:var(--font-xs);color:var(--text-secondary);margin-top:4px;}
.tag{display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:var(--font-xs);}
.tag-green{background:#F6FFED;color:var(--success);}
/* 失败列表 */
.fail-list{margin-top:12px;}
.fail-item{display:flex;justify-content:space-between;align-items:center;padding:8px 12px;background:#FFF1F0;border-radius:var(--radius-sm);margin-bottom:6px;font-size:var(--font-sm);}
.fail-item__name{color:var(--text-primary);}
.fail-item__reason{color:var(--danger);font-size:var(--font-xs);}
</style>
</head>
<body>
<div class="dialog">
<div class="dialog-header">
<div class="dialog-title">短信发送详情</div>
</div>
<div class="dialog-body">
<div class="section">
<div class="section__title">基本信息</div>
<div class="info-grid">
<div class="info-item"><span class="info-item__label">发送批次</span><span class="info-item__value" style="font-family:monospace;">SMS20260410001</span></div>
<div class="info-item"><span class="info-item__label">发送状态</span><span class="info-item__value"><span class="tag tag-green">已发送</span></span></div>
<div class="info-item"><span class="info-item__label">发送对象</span><span class="info-item__value">采油一厂</span></div>
<div class="info-item"><span class="info-item__label">发送时间</span><span class="info-item__value">2026-04-10 09:00</span></div>
<div class="info-item"><span class="info-item__label">操作人</span><span class="info-item__value">健康小助手</span></div>
<div class="info-item"><span class="info-item__label">短信签名</span><span class="info-item__value">【健康长庆】</span></div>
</div>
</div>
<div class="section">
<div class="section__title">短信内容</div>
<div class="sms-preview">【健康长庆】您的体检报告已出,请登录APP查看详情。如有疑问请咨询健康小助手。</div>
</div>
<div class="section">
<div class="section__title">发送统计</div>
<div class="stat-row">
<div class="stat-block"><div class="stat-block__value" style="color:var(--primary);">326</div><div class="stat-block__label">发送总数</div></div>
<div class="stat-block"><div class="stat-block__value" style="color:var(--success);">320</div><div class="stat-block__label">发送成功</div></div>
<div class="stat-block"><div class="stat-block__value" style="color:var(--danger);">6</div><div class="stat-block__label">发送失败</div></div>
<div class="stat-block"><div class="stat-block__value">98.2%</div><div class="stat-block__label">成功率</div></div>
</div>
</div>
<div class="section">
<div class="section__title">失败记录(6条)</div>
<div class="fail-list">
<div class="fail-item"><span class="fail-item__name">周某某(138****1234</span><span class="fail-item__reason">号码已停机</span></div>
<div class="fail-item"><span class="fail-item__name">吴某某(139****5678</span><span class="fail-item__reason">号码不存在</span></div>
<div class="fail-item"><span class="fail-item__name">郑某某(136****9012</span><span class="fail-item__reason">运营商拦截</span></div>
<div class="fail-item"><span class="fail-item__name">孙某某(137****3456</span><span class="fail-item__reason">号码已停机</span></div>
<div class="fail-item"><span class="fail-item__name">钱某某(135****7890</span><span class="fail-item__reason">发送超时</span></div>
<div class="fail-item"><span class="fail-item__name">冯某某(158****2345</span><span class="fail-item__reason">号码不存在</span></div>
</div>
</div>
</div>
</div>
</body>
</html>
@@ -0,0 +1,205 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>专家咨询·小助手 - 短信发送 | 健康长庆原型</title>
<style>
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;min-width:1280px;}
:root{--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;--text-primary:#333;--text-secondary:#666;--border:#E8E8E8;--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--font-xl:20px;--radius-sm:4px;--radius-md:8px;--shadow-sm:0 1px 4px rgba(0,0,0,0.08);}
.top-bar{display:flex;align-items:center;height:56px;background:#001529;padding:0 24px;position:fixed;top:0;left:0;right:0;z-index:100;}
.top-bar__logo{display:flex;align-items:center;gap:8px;color:#fff;font-size:var(--font-lg);font-weight:600;width:240px;flex-shrink:0;white-space:nowrap;}
.top-bar__logo svg{width:28px;height:28px;}
.top-bar__nav{display:flex;align-items:center;gap:4px;flex:1;}
.top-bar__nav a{color:rgba(255,255,255,0.65);text-decoration:none;padding:6px 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);transition:all .2s;}
.top-bar__nav a:hover{color:#fff;background:rgba(255,255,255,0.08);}
.top-bar__nav a.active{color:#fff;background:var(--primary);}
.top-bar__right{display:flex;align-items:center;gap:16px;font-size:var(--font-sm);margin-left:auto;}
.btn-back{color:rgba(255,255,255,0.65);cursor:pointer;display:flex;align-items:center;gap:4px;text-decoration:none;}.btn-back:hover{color:#fff;}
.avatar{width:32px;height:32px;border-radius:50%;background:var(--success);display:flex;align-items:center;justify-content:center;color:#fff;font-size:var(--font-sm);}
.main{margin-top:56px;padding:24px;}
.stat-cards{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;margin-bottom:16px;}
.stat-card{background:#fff;border-radius:var(--radius-md);padding:20px 24px;box-shadow:var(--shadow-sm);}
.stat-card__label{font-size:var(--font-sm);color:var(--text-secondary);}
.stat-card__value{font-size:24px;font-weight:700;margin-top:8px;}
.stat-card__sub{font-size:var(--font-xs);color:var(--text-secondary);margin-top:4px;}
.filter-bar{background:#fff;border-radius:var(--radius-md);padding:20px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:flex;align-items:center;gap:16px;flex-wrap:wrap;}
.filter-item{display:flex;align-items:center;gap:8px;}
.filter-item label{font-size:var(--font-sm);color:var(--text-secondary);white-space:nowrap;}
.filter-input{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);outline:none;background:#fff;min-width:180px;}
.filter-input:focus{border-color:var(--primary);}
.filter-select{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);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 10px center;appearance:none;min-width:120px;}
.btn{height:36px;padding:0 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;}
.btn-primary{background:var(--primary);color:#fff;}.btn-primary:hover{background:#40a9ff;}
.btn-default{background:#fff;color:var(--text-primary);border:1px solid var(--border);}.btn-default:hover{color:var(--primary);border-color:var(--primary);}
.btn-success{background:var(--success);color:#fff;}.btn-success:hover{background:#73d13d;}
.table-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);overflow:hidden;}
.table-card__header{display:flex;align-items:center;justify-content:space-between;padding:16px 24px;border-bottom:1px solid var(--border);}
.table-card__title{font-size:var(--font-base);font-weight:600;}
.table-card__content{overflow-x:auto;}
table{width:100%;border-collapse:collapse;}
thead th{background:#FAFAFA;padding:12px 16px;text-align:left;font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);white-space:nowrap;}
tbody td{padding:14px 16px;font-size:var(--font-sm);border-bottom:1px solid var(--border);white-space:nowrap;}
tbody tr:last-child td{border-bottom:none;}
tbody tr:hover{background:#F8FBFF;}
.tag{display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:var(--font-xs);}
.tag-green{background:#F6FFED;color:var(--success);}
.tag-blue{background:var(--primary-light);color:var(--primary);}
.tag-orange{background:#FFF7E6;color:var(--warning);}
.tag-red{background:#FFF1F0;color:var(--danger);}
.link{color:var(--primary);cursor:pointer;font-size:var(--font-sm);}.link:hover{color:#40a9ff;}
.pagination{display:flex;align-items:center;justify-content:flex-end;padding:16px 24px;gap:8px;border-top:1px solid var(--border);}
.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);}
/* 模态弹窗(iframe覆盖层) */
.overlay-modal{display:none;position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.45);z-index:1000;align-items:center;justify-content:center;}
.overlay-modal.open{display:flex;}
.overlay-modal__box{background:#fff;border-radius:var(--radius-md);overflow:hidden;box-shadow:0 4px 16px rgba(0,0,0,0.15);position:relative;max-height:90vh;display:flex;flex-direction:column;}
.overlay-modal__close{position:absolute;top:12px;right:12px;width:32px;height:32px;border-radius:50%;background:rgba(0,0,0,0.04);border:none;font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;color:#999;z-index:10;transition:all .15s;}
.overlay-modal__close:hover{background:rgba(0,0,0,0.08);color:#333;}
.overlay-modal iframe{border:none;display:block;}
</style>
</head>
<body>
<div class="top-bar">
<div class="top-bar__logo"><svg viewBox="0 0 28 28" fill="none"><rect width="28" height="28" rx="6" fill="#52C41A"/><path d="M9 14.5l3 3 7-7" stroke="#fff" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/></svg>专家咨询–小助手</div>
<nav class="top-bar__nav">
<a href="current-consult.html">当前咨询</a>
<a href="chat-message.html">对话消息</a>
<a href="history-consult.html">历史咨询</a>
<a href="checkup-standard.html">体检标准化</a>
<a href="sms-send.html" class="active">短信发送</a>
<a href="consult-settle.html">咨询结算</a>
</nav>
<div class="top-bar__right">
<a class="btn-back" href="../../index.html"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><path d="M10 3L5 8l5 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>返回首页</a>
<div class="avatar"></div><span style="color:rgba(255,255,255,0.65);">健康小助手 ▾</span>
</div>
</div>
<main class="main">
<div class="stat-cards">
<div class="stat-card"><div class="stat-card__label">本月发送总量</div><div class="stat-card__value" style="color:var(--primary);">1,286</div><div class="stat-card__sub">2026年4月</div></div>
<div class="stat-card"><div class="stat-card__label">发送成功</div><div class="stat-card__value" style="color:var(--success);">1,245</div><div class="stat-card__sub">成功率 96.8%</div></div>
<div class="stat-card"><div class="stat-card__label">发送失败</div><div class="stat-card__value" style="color:var(--danger);">41</div><div class="stat-card__sub">需关注</div></div>
<div class="stat-card"><div class="stat-card__label">待发送</div><div class="stat-card__value" style="color:var(--warning);">12</div><div class="stat-card__sub">定时任务</div></div>
</div>
<div class="filter-bar">
<div class="filter-item"><label>发送状态</label>
<select class="filter-select"><option>全部状态</option><option>已发送</option><option>发送失败</option><option>待发送</option></select>
</div>
<div class="filter-item"><label>发送时间</label>
<input class="filter-input" type="date" style="min-width:140px;">
<span style="color:var(--text-secondary);font-size:var(--font-sm);"></span>
<input class="filter-input" type="date" style="min-width:140px;">
</div>
<button class="btn btn-primary"><svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="6" cy="6" r="4" stroke="currentColor" stroke-width="1.4"/><path d="M10 10l2.5 2.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>查询</button>
<button class="btn btn-default">重置</button>
<!-- [交互] 点击打开新建短信弹窗 -->
<button class="btn btn-success" style="margin-left:auto;" onclick="openOverlay('send-dialog.html',640,680)">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M7 2v10M2 7h10" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
新建短信
</button>
</div>
<div class="table-card">
<div class="table-card__header">
<div class="table-card__title">短信发送记录</div>
<div style="font-size:var(--font-sm);color:var(--text-secondary);">共 256 条</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></tr></thead>
<tbody>
<tr>
<td style="font-family:monospace;color:var(--text-secondary);">SMS20260410001</td>
<td style="max-width:240px;overflow:hidden;text-overflow:ellipsis;">【健康长庆】您的体检报告已出,请登录APP查看详情。</td>
<td>采油一厂</td><td>326</td>
<td><span style="color:var(--success);">320</span> / <span style="color:var(--danger);">6</span></td>
<td><span class="tag tag-green">已发送</span></td>
<td>2026-04-10 09:00</td>
<td><span class="link" onclick="openOverlay('sms-detail-dialog.html',640,600)">查看详情</span></td>
</tr>
<tr>
<td style="font-family:monospace;color:var(--text-secondary);">SMS20260409002</td>
<td style="max-width:240px;overflow:hidden;text-overflow:ellipsis;">【健康长庆】温馨提醒:您预约的专家咨询将于明日10:00开始。</td>
<td>指定人员(15人)</td><td>15</td>
<td><span style="color:var(--success);">15</span> / <span style="color:var(--danger);">0</span></td>
<td><span class="tag tag-green">已发送</span></td>
<td>2026-04-09 16:30</td>
<td><span class="link" onclick="openOverlay('sms-detail-dialog.html',640,600)">查看详情</span></td>
</tr>
<tr>
<td style="font-family:monospace;color:var(--text-secondary);">SMS20260409003</td>
<td style="max-width:240px;overflow:hidden;text-overflow:ellipsis;">【健康长庆】春季健康讲座通知:4月15日下午2点,主题"职场压力管理"。</td>
<td>全部员工</td><td>2,860</td>
<td><span style="color:var(--success);">2,831</span> / <span style="color:var(--danger);">29</span></td>
<td><span class="tag tag-green">已发送</span></td>
<td>2026-04-09 10:00</td>
<td><span class="link" onclick="openOverlay('sms-detail-dialog.html',640,600)">查看详情</span></td>
</tr>
<tr>
<td style="font-family:monospace;color:var(--text-secondary);">SMS20260411004</td>
<td style="max-width:240px;overflow:hidden;text-overflow:ellipsis;">【健康长庆】您的健康评估报告已更新,请及时查看。</td>
<td>采油二厂</td><td>280</td>
<td>— / —</td>
<td><span class="tag tag-orange">待发送</span></td>
<td>2026-04-11 08:00(定时)</td>
<td><span class="link" onclick="openOverlay('sms-detail-dialog.html',640,600)">查看详情</span></td>
</tr>
<tr>
<td style="font-family:monospace;color:var(--text-secondary);">SMS20260408005</td>
<td style="max-width:240px;overflow:hidden;text-overflow:ellipsis;">【健康长庆】体检预约提醒:请于4月12日前完成年度体检预约。</td>
<td>勘探开发研究院</td><td>156</td>
<td><span style="color:var(--success);">150</span> / <span style="color:var(--danger);">6</span></td>
<td><span class="tag tag-green">已发送</span></td>
<td>2026-04-08 14:00</td>
<td><span class="link" onclick="openOverlay('sms-detail-dialog.html',640,600)">查看详情</span></td>
</tr>
</tbody>
</table>
</div>
<div class="pagination">
<span>共 256 条</span>
<button class="page-btn"></button>
<button class="page-btn active">1</button>
<button class="page-btn">2</button>
<button class="page-btn">3</button>
<span>...</span>
<button class="page-btn">26</button>
<button class="page-btn"></button>
<select class="filter-select" style="min-width:70px;height:32px;"><option>10条</option><option>20条</option></select>
</div>
</div>
</main>
<!-- 模态弹窗容器 -->
<div class="overlay-modal" id="overlayModal" onclick="if(event.target===this)closeOverlay()">
<div class="overlay-modal__box" id="overlayBox">
<button class="overlay-modal__close" onclick="closeOverlay()"></button>
<iframe id="overlayFrame" src=""></iframe>
</div>
</div>
<script>
function openOverlay(url, w, h) {
var box = document.getElementById('overlayBox');
box.style.width = w + 'px';
var frame = document.getElementById('overlayFrame');
frame.style.width = w + 'px';
frame.style.height = h + 'px';
frame.src = url;
document.getElementById('overlayModal').classList.add('open');
document.body.style.overflow = 'hidden';
}
function closeOverlay() {
document.getElementById('overlayModal').classList.remove('open');
document.getElementById('overlayFrame').src = '';
document.body.style.overflow = '';
}
window.addEventListener('message', function(e) {
if (e.data === 'close-dialog') closeOverlay();
});
</script>
</body>
</html>