feat: 补充应急就医对话消息原型并更新文档截图

为操作人员和专业人员补齐对话消息入口与页面,统一应急链路顶部导航并修复通讯录重复添加问题。同时更新应急模块PRD、截图资源与相关原型细节,清理本地截图辅助脚本。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
冯普
2026-04-29 13:57:17 +08:00
co-authored by Claude Opus 4.6
parent b8382c862f
commit 48fe9abbb1
28 changed files with 1139 additions and 509 deletions
@@ -394,6 +394,7 @@ tbody tr:hover{background:#F8FBFF;}
document.querySelector('.top-bar__logo').lastChild.textContent='\u00a0应急就医–操作人员';
document.querySelector('.top-bar__nav').innerHTML=
'<a href="../operator/emergency-active.html">正在应急</a>'+
'<a href="../operator/chat-message.html">对话消息</a>'+
'<a href="center-work-order.html?role=operator">应急工单</a>'+
'<a href="center-call-record.html?role=operator" class="active">通话记录</a>'+
'<a href="center-serious-illness.html?role=operator">大病就医</a>'+
@@ -234,6 +234,7 @@
document.querySelector('.top-bar__logo').lastChild.textContent='\u00a0应急就医–操作人员';
document.querySelector('.top-bar__nav').innerHTML=
'<a href="../operator/emergency-active.html">正在应急</a>'+
'<a href="../operator/chat-message.html">对话消息</a>'+
'<a href="center-work-order.html?role=operator">应急工单</a>'+
'<a href="center-call-record.html?role=operator">通话记录</a>'+
'<a href="center-serious-illness.html?role=operator">大病就医</a>'+
@@ -54,6 +54,8 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
.emp-card__item{display:flex;align-items:center;gap:6px;font-size:var(--font-sm);}
.emp-card__label{color:var(--text-secondary);}
.emp-card__value{color:var(--text-primary);font-weight:500;}
.person-tel{margin-top:8px;font-size:var(--font-sm);color:var(--text-secondary);display:none;}
.person-tel a{color:var(--primary);text-decoration:none;}
/* 提交 */
.form-footer{margin-top:40px;text-align:center;}
.btn-submit{width:240px;height:44px;background:var(--primary);color:#fff;border:none;border-radius:var(--radius-sm);font-size:var(--font-base);font-weight:500;cursor:pointer;transition:background .15s;}
@@ -70,9 +72,9 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
</div>
<div class="form-wrap">
<!-- 就医员工信息 -->
<!-- 员工就医诉求 -->
<div class="form-section">
<div class="form-section__title">就医员工信息</div>
<div class="form-section__title">员工就医诉求</div>
<div class="form-row">
<div class="form-group">
<label class="form-label"><span class="required">*</span>员工类型:</label>
@@ -131,11 +133,6 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
</div>
</div>
</div>
</div>
<!-- 预约信息 -->
<div class="form-section">
<div class="form-section__title">预约信息</div>
<div class="form-row">
<div class="form-group">
<label class="form-label"><span class="required">*</span>预约医院:</label>
@@ -196,8 +193,33 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
</div>
</div>
<!-- 就医派单 -->
<div class="form-section">
<div class="form-section__title">就医派单</div>
<div class="form-row">
<div class="form-group">
<label class="form-label"><span class="required">*</span>驻场人员:</label>
<div class="form-control-wrap">
<div class="select-search" id="personSelect">
<input class="select-search__input" id="personInput" placeholder="姓名/医院搜索" autocomplete="off" onclick="togglePersonDrop()" oninput="filterPersons()">
<div class="select-search__drop" id="personDrop"></div>
</div>
<div class="person-tel" id="personTelInfo">联系电话:<a id="personTel" href=""></a></div>
</div>
</div>
</div>
<div class="form-row">
<div class="form-group">
<label class="form-label">派单说明:</label>
<div class="form-control-wrap form-control-wrap--wide">
<textarea class="form-textarea" id="dispatchNote" placeholder="请输入派单说明"></textarea>
</div>
</div>
</div>
</div>
<div class="form-footer">
<button class="btn-submit" onclick="alert('【交互说明】提交新增大病就医,返回列表')">确定</button>
<button class="btn-submit" onclick="submitDirectDispatch()">确定并派单</button>
</div>
</div>
@@ -243,7 +265,6 @@ function pickEmp(idx){
document.getElementById('ecIdCard').textContent=_selectedEmp.idCard;
document.getElementById('empCard').classList.add('show');
}
document.addEventListener('click',function(e){if(!document.getElementById('empSelect').contains(e.target))document.getElementById('empDrop').classList.remove('open');if(!document.getElementById('hospSelect').contains(e.target))document.getElementById('hospDrop').classList.remove('open');});
/* 医院搜索 */
var _hosps=[
@@ -274,6 +295,69 @@ function pickHosp(idx){
document.getElementById('hospInput').value=_selectedHosp.name;
document.getElementById('hospDrop').classList.remove('open');
}
/* 驻场人员搜索 */
var _persons=[
{name:'王旭',hospital:'长庆油田职工医院',tel:'138-9201-3001'},
{name:'刘鑫',hospital:'长庆油田职工医院',tel:'138-9201-3002'},
{name:'陈浩',hospital:'采油一厂卫生所',tel:'138-9201-3003'},
{name:'赵旭',hospital:'西安交通大学第一附属医院',tel:'138-9201-3004'},
{name:'孙俪',hospital:'采油一厂卫生所',tel:'138-9201-3005'},
{name:'周西',hospital:'陕西省人民医院',tel:'138-9201-3006'},
{name:'吴晓',hospital:'长庆油田职工医院',tel:'138-9201-3007'},
{name:'郑立',hospital:'西安交通大学第一附属医院',tel:'138-9201-3008'}
];
var _selectedPerson=null;
function renderPersonDrop(kw){
var drop=document.getElementById('personDrop');kw=(kw||'').toLowerCase();var html='',c=0;
_persons.forEach(function(p,i){
if(kw&&p.name.toLowerCase().indexOf(kw)<0&&p.hospital.toLowerCase().indexOf(kw)<0)return;
var sel=(_selectedPerson&&_selectedPerson.name===p.name)?' selected':'';
html+='<div class="select-search__option'+sel+'" onclick="pickPerson('+i+')"><div class="select-search__name">'+p.name+'</div><div class="select-search__sub">'+p.hospital+'</div></div>';c++;
});
if(!c)html='<div class="select-search__empty">无匹配驻场人员</div>';
drop.innerHTML=html;
}
function togglePersonDrop(){var d=document.getElementById('personDrop');if(d.classList.contains('open')){d.classList.remove('open');return;}renderPersonDrop(document.getElementById('personInput').value);d.classList.add('open');}
function filterPersons(){renderPersonDrop(document.getElementById('personInput').value);document.getElementById('personDrop').classList.add('open');}
function pickPerson(idx){
_selectedPerson=_persons[idx];
document.getElementById('personInput').value=_selectedPerson.name+' · '+_selectedPerson.hospital;
document.getElementById('personDrop').classList.remove('open');
document.getElementById('personTelInfo').style.display='block';
var tel=document.getElementById('personTel');
tel.textContent=_selectedPerson.tel;
tel.href='tel:'+_selectedPerson.tel.replace(/-/g,'');
}
function submitDirectDispatch(){
if(document.querySelector('input[name="empType"]:checked').value==='oil'&&!_selectedEmp){
var empInput=document.getElementById('empInput');
empInput.style.borderColor='var(--danger)';
empInput.focus();
return;
}
if(!_selectedHosp){
var hospInput=document.getElementById('hospInput');
hospInput.style.borderColor='var(--danger)';
hospInput.focus();
return;
}
if(!_selectedPerson){
var personInput=document.getElementById('personInput');
personInput.style.borderColor='var(--danger)';
personInput.focus();
return;
}
alert('【交互说明】已创建大病就医申请并完成派单,返回大病就医列表');
location.href='center-serious-illness.html?role=operator';
}
document.addEventListener('click',function(e){
if(!document.getElementById('empSelect').contains(e.target))document.getElementById('empDrop').classList.remove('open');
if(!document.getElementById('hospSelect').contains(e.target))document.getElementById('hospDrop').classList.remove('open');
if(!document.getElementById('personSelect').contains(e.target))document.getElementById('personDrop').classList.remove('open');
});
</script>
</body>
@@ -297,6 +297,7 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
document.querySelector('.top-bar__logo').lastChild.textContent='\u00a0应急就医–操作人员';
document.querySelector('.top-bar__nav').innerHTML=
'<a href="../operator/emergency-active.html">正在应急</a>'+
'<a href="../operator/chat-message.html">对话消息</a>'+
'<a href="center-work-order.html?role=operator">应急工单</a>'+
'<a href="center-call-record.html?role=operator">通话记录</a>'+
'<a href="center-serious-illness.html?role=operator" class="active">大病就医</a>'+
@@ -383,6 +384,10 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
var visible=g.split(' ').indexOf(status)>=0;
groups[i].style.display=visible?'':'none';
}
/* --- 待确认操作按钮仅操作人员可见 --- */
var pendingActions=document.getElementById('pendingActions');
if(pendingActions&&role!=='operator') pendingActions.style.display='none';
})();
/* === 驳回弹窗 === */
@@ -423,6 +423,7 @@
document.querySelector('.top-bar__logo').lastChild.textContent='\u00a0应急就医–操作人员';
document.querySelector('.top-bar__nav').innerHTML=
'<a href="../operator/emergency-active.html">正在应急</a>'+
'<a href="../operator/chat-message.html">对话消息</a>'+
'<a href="center-work-order.html?role=operator">应急工单</a>'+
'<a href="center-call-record.html?role=operator">通话记录</a>'+
'<a href="center-serious-illness.html?role=operator" class="active">大病就医</a>'+
@@ -687,6 +687,7 @@ function addSummary(){
document.querySelector('.top-bar__logo').lastChild.textContent='\u00a0应急就医–专业人员';
document.querySelector('.top-bar__nav').innerHTML=
'<a href="../professional/professional.html">正在应急</a>'+
'<a href="../professional/chat-message.html">对话消息</a>'+
'<a href="center-work-order.html?role=professional" class="active">应急工单</a>';
document.querySelector('.avatar').textContent='专';
document.querySelector('.top-bar__right span:last-child').textContent='专业人员 ▾';
@@ -701,6 +702,7 @@ function addSummary(){
document.querySelector('.top-bar__logo').lastChild.textContent='\u00a0应急就医–操作人员';
document.querySelector('.top-bar__nav').innerHTML=
'<a href="../operator/emergency-active.html">正在应急</a>'+
'<a href="../operator/chat-message.html">对话消息</a>'+
'<a href="center-work-order.html?role=operator" class="active">应急工单</a>'+
'<a href="center-call-record.html?role=operator">通话记录</a>'+
'<a href="center-serious-illness.html?role=operator">大病就医</a>'+
@@ -399,6 +399,7 @@ tbody tr:hover{background:#F8FBFF;}
/* 顶部导航 */
document.querySelector('.top-bar__nav').innerHTML=
'<a href="../professional/professional.html">正在应急</a>'+
'<a href="../professional/chat-message.html">对话消息</a>'+
'<a href="center-work-order.html?role=professional" class="active">应急工单</a>';
/* 右侧角色 */
document.querySelector('.avatar').textContent='专';
@@ -420,6 +421,7 @@ tbody tr:hover{background:#F8FBFF;}
/* 顶部导航 */
document.querySelector('.top-bar__nav').innerHTML=
'<a href="../operator/emergency-active.html">正在应急</a>'+
'<a href="../operator/chat-message.html">对话消息</a>'+
'<a href="center-work-order.html?role=operator" class="active">应急工单</a>'+
'<a href="center-call-record.html?role=operator">通话记录</a>'+
'<a href="center-serious-illness.html?role=operator">大病就医</a>'+
@@ -1,5 +1,48 @@
# 应急就医模块变更记录
## [2026-04-29] feat: 补充对话消息原型并更新应急模块文档截图
补齐操作人员与专业人员视角的“对话消息”一级菜单和会话页面,统一应急链路顶部导航入口,同步更新大病就医、资源管理相关原型页面以及 PRD、截图产物,并清理本地截图辅助脚本。
**涉及内容:**
- 新增 `operator/chat-message.html``professional/chat-message.html`,补充操作人员端、专业人员端“对话消息”原型页面,支持通讯录弹窗、会话切换与重复联系人拦截
- 调整操作人员端、专业人员端及其关联管理页顶部导航,将“对话消息”固定为一级入口并保持在“正在应急”后展示
- 更新 `admin/center-serious-illness-add.html``admin/resource-hospital.html``admin/resource-medical-point.html` 等页面原型细节
- 同步刷新 `admin/doc/PRD.md``operator/doc/PRD.md``professional/doc/PRD.md` 与相关截图资源
- 删除本地截图辅助脚本 `gen_detail.py``gen_screenshots.py``screenshot.js`
**涉及文件:**
- `index.html`
- `gen_detail.py`
- `gen_screenshots.py`
- `screenshot.js`
- `admin/center-call-record.html`
- `admin/center-schedule.html`
- `admin/center-serious-illness-add.html`
- `admin/center-serious-illness-detail.html`
- `admin/center-serious-illness.html`
- `admin/center-work-order-detail.html`
- `admin/center-work-order.html`
- `admin/resource-hospital.html`
- `admin/resource-medical-point.html`
- `admin/doc/PRD.md`
- `admin/doc/screenshots/center-basic-info-detail.jpg`
- `admin/doc/screenshots/center-serious-illness-add.jpg`
- `admin/doc/screenshots/center-simulation-deploy.jpg`
- `admin/doc/screenshots/center-work-order-detail.jpg`
- `admin/doc/screenshots/resource-hospital.jpg`
- `admin/doc/screenshots/resource-medical-point.jpg`
- `operator/chat-message.html`
- `operator/emergency-active.html`
- `operator/doc/PRD.md`
- `operator/doc/screenshots/center-serious-illness-add.jpg`
- `professional/chat-message.html`
- `professional/professional.html`
- `professional/doc/PRD.md`
- `doc/CHANGELOG.md`
## [2026-04-24] feat: 完善应急就医管理原型交互与资源页联动
补齐应急就医模块多页面原型交互,新增异常事件菜单页,统一档案、应急管理与应急资源之间的页面跳转、详情态与删除确认体验。
+207 -263
View File
@@ -2,7 +2,7 @@
## 模块概述
应急就医管理端(管理员视角)为系统管理员提供应急就医业务的全流程管理能力,涵盖个人/单位/应急中心维度的档案数据统计、医院/医疗点/AED设备/救护车/急救包/急救医生/紧急联系人等应急资源管理、应急中心基本信息与工单管理/通话记录/重症就医/排班/数据大屏/模拟急救等应急管理功能,以及异常事件监控与脏数据检测。
应急就医管理端(管理员视角)为系统管理员提供应急就医业务的全流程管理能力,涵盖个人/单位/应急中心维度的档案数据统计、医院/医疗点/AED设备/救护车/急救包/急救医生/紧急联系人等应急资源管理、应急中心基本信息与工单管理/通话记录/大病就医/排班/数据大屏/模拟急救等应急管理功能,以及异常事件监控与脏数据检测。
### 页面导航结构
@@ -34,7 +34,7 @@
│ ├── 应急工单 → 新增工单 / 工单详情
│ ├── 坐席管理 ⇄ 新增/编辑坐席弹窗
│ ├── 通话记录
│ ├── 重症就医 → 新增重症就医 / 重症就医详情
│ ├── 大病就医 → 新增大病就医 / 大病就医详情
│ ├── 数据大屏
│ ├── 排班管理
│ └── 模拟急救
@@ -52,14 +52,14 @@ stateDiagram-v2
进行中 --> 已完成 : 工单结束
进行中 --> 已取消 : 取消工单
```
### 重症就医状态流转
### 大病就医状态流转
```mermaid
stateDiagram-v2
[*] --> 待确认 : 员工/管理员发起预约
待确认 --> 已确认 : 管理员审核通过并派单
待确认 --> 已驳回 : 管理员驳回
已确认 --> 已完成 : 驻场人员完成就医
[*] --> 待确认 : 员工发起预约
待确认 --> 已确认 : 操作人员审核通过并派单
待确认 --> 已取消 : 操作人员取消
已确认 --> 已完成 : 驻场人员完成就医挂号
已确认 --> 已取消 : 取消预约
```
@@ -117,9 +117,9 @@ stateDiagram-v2
| 36 | | 工单详情 | center-work-order-detail.html | 页面 |
| 37 | 坐席管理 | 坐席管理列表 | center-group.html | 页面 |
| 38 | 通话记录 | 通话记录列表 | center-call-record.html | 页面 |
| 39 | 重症就医 | 重症就医列表 | center-serious-illness.html | 页面 |
| 40 | | 新增重症就医 | center-serious-illness-add.html | 页面 |
| 41 | | 重症就医详情 | center-serious-illness-detail.html | 页面 |
| 39 | 大病就医 | 大病就医列表 | center-serious-illness.html | 页面 |
| 40 | | 新增大病就医 | center-serious-illness-add.html | 页面 |
| 41 | | 大病就医详情 | center-serious-illness-detail.html | 页面 |
| 42 | 数据大屏 | 数据大屏配置 | center-data-screen.html | 页面 |
| 43 | 排班管理 | 排班管理 | center-schedule.html | 页面 |
| 44 | 模拟急救 | 模拟急救 | center-simulation.html | 页面 |
@@ -152,7 +152,7 @@ stateDiagram-v2
**业务规则:**
- 数据按员工维度聚合,一个员工对应一条记录
- 各类求助次数列支持点击排序
- 分页支持 10/20/50 条每页切换
- 分页支持 10/20/50/100 条每页切换
**交互说明:**
- 点击"详细数据"跳转到个人应急数据详情
@@ -196,7 +196,7 @@ stateDiagram-v2
- 序号和操作列固定在表格两侧
**交互说明:**
- 点击"详细过程"跳转到重症就医详情页,携带 `status``from=archive` 参数
- 点击"详细过程"跳转到大病就医详情页,携带 `status``from=archive` 参数
- 支持导出列表数据、查看导出任务
---
@@ -205,22 +205,23 @@ stateDiagram-v2
![页面截图](screenshots/archive-unit.jpg)
**功能说明:** 按组织维度汇总展示各单位/部门的应急数据,支持"二级单位"和"三级单位"两个 Tab 维度切换。
**功能说明:** 按组织架构汇总展示各单位/部门的应急数据,支持"二级单位"和"三级单位"两个 Tab 维度切换。
**Tab — 二级单位:**
- 筛选:年份(下拉)、单位名称(下拉,全部单位/公司机关/采油一厂/采油二厂/采气一厂/第一采油厂/输油处
- 筛选:年份(下拉)、单位名称(下拉,支持多选
- 表格列(双行表头):序号、单位、总人数 | 拨打120(次数↕/人数↕)、应急视频(次数↕/人数↕)、应急电话(次数↕/人数↕)、线下应急(次数↕/人数↕)、大病就医预约(次数↕/人数↕)
- 首行为计行(灰色背景加粗)
- 首行为计行(灰色背景加粗)
**Tab — 三级单位:**
- 筛选:年份(下拉)、所属单位(下拉)、部门名称(下拉)
- 筛选:年份(下拉)、所属单位(下拉)、部门名称(下拉,支持多选
- 表格列(双行表头):序号、所属单位、部门名称、总人数 | 应急视频(次数↕/人数↕)、拨打120(次数↕/人数↕)、应急电话(次数↕/人数↕)、线下应急(次数↕/人数↕)、大病就医预约(次数↕/人数↕)
- 首行为计行
- 首行为计行
**业务规则:**
- 次数和人数列均为可点击链接,点击跳转到对应的详情页
- 应急求助类(拨打120/应急视频/应急电话/线下应急)点击跳转单位报表详情
- 大病就医预约列点击跳转大病就医预约详情
- 单位报表数据支持按多个单位或者部门筛选
**交互说明:**
- Tab 切换二级单位/三级单位
@@ -247,7 +248,7 @@ stateDiagram-v2
- 面包屑路径:单位报表数据 / 单位名称 / 求助方式
**交互说明:**
- 次数面板点击"详细过程"跳转工单详情,携带 `from=archive-unit` 参数
- 次数面板点击"详细过程"跳转工单详情
- 支持导出列表数据
---
@@ -267,7 +268,7 @@ stateDiagram-v2
- 表格列:序号、员工姓名、员工编号、所属部门、预约次数、最近预约医院、最近预约科室、最近预约时间、最近工单状态
**交互说明:**
- 次数面板点击"详细过程"跳转重症就医详情,携带 `status``from=archive-unit` 参数
- 次数面板点击"详细过程"跳转大病就医详情,携带 `status``from=archive-unit` 参数
- 支持导出列表数据、查看导出任务
---
@@ -295,48 +296,44 @@ stateDiagram-v2
**功能说明:** 管理应急就医可选的医院列表,支持新增、编辑、删除和启用/禁用。
**筛选条件:** 医院名称(文本输入)、医院等级(下拉,全部等级/三级甲等/三级乙等/三级丙等/二级甲等/二级乙等/二级丙等/一级/其他)、医院类型(下拉,全部类型/合作医院/油田医院)
**筛选条件:** 医院名称(文本输入)、医院等级(下拉,)、医院类型(下拉,全部类型/合作医院/油田医院)
**表格列:** 序号、医院名称、医院类型(油田医院/合作医院)、等级、地址、联系电话、医院简介、应急专长、状态(开关)、操作(编辑/删除)
**表格列:** 序号、医院名称、医院类型(油田医院/合作医院)、等级、地址、联系电话、医院简介、应急专长、操作(编辑/删除)
**业务规则:**
- 医院类型分为"油田医院"和"合作医院"两类
- 状态开关控制移动端是否显示
- 状态配置控制移动端是否显示
**交互说明:**
- 点击"新增医院"打开右侧抽屉表单
- 抽屉表单:选择医院(搜索下拉,选择后自动回填等级和地址信息卡片)、医院类型(单选,油田医院/合作医院)、应急专长(文本域)、状态/移动端是否显示(开关)
- 点击"编辑"打开编辑抽屉
- 点击"删除"弹出确认弹窗
- 切换状态开关即时生效
- 支持导出列表数据
**表单字段表(新增/编辑医院抽屉):**
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|------|
| 选择医院 | 搜索下拉 | 是 | 输入关键词搜索,选择后回填等级和地址 |
| 医院类型 | 单选 | 是 | 油田医院/合作医院 |
| 应急专长 | 多行文本 | 是 | — |
| 状态 | 开关 | 否 | 默认开启,控制移动端是否显示 |
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|------------------|
| 选择医院 | 搜索下拉 | 是 | 选取系统管理医院管理下配置的医院 |
| 医院类型 | 单选 | 是 | 油田医院/合作医院 |
| 应急专长 | 多行文本 | 是 | — |
| 状态 | 开关 | 否 | 默认开启,控制移动端是否显示 |
---
### 9. 医疗点信息(resource-medical-point.html
![页面截图](screenshots/resource-medical-point.jpg)
**功能说明:** 管理各单位下属医疗点的基础信息,包括所属医院、关联应急中心、负责人等
**功能说明:** 展示医疗点模块医疗点列表,列表需要新增关联应急中心的显示
**筛选条件:** 医疗点名称(文本输入)、所属单位(下拉,全部/公司机关/采油一厂/采油二厂)、所属医院(下拉,全部/宝石花医院/西京医院/长庆油田医院)、应急中心(下拉,全部/西安应急中心/庆阳应急中心/榆林应急中心
**筛选条件:** 医疗点名称(文本输入)、所属单位(下拉)、所属医院(下拉)、应急中心(下拉
**表格列:** 序号、医疗点名称、所属单位、所属医院、关联应急中心、地址、负责人、联系电话、医护人员数量、状态(开关)、操作(查看详情/编辑/删除
**表格列:** 序号、医疗点名称、所属单位、所属医院、关联应急中心、地址、负责人、联系电话、医护人员数量、操作(查看详情)
**交互说明:**
- 点击"查看详情"打开右侧抽屉加载医疗点详情页
- 点击"新增医疗点"打开新增表单
- 点击"删除"弹出确认弹窗
- 支持导出列表数据
- 支持异步导出列表数据
---
### 10. 医疗点详情(resource-medical-point-detail.html
@@ -359,13 +356,14 @@ stateDiagram-v2
**筛选条件:** 设备编号(文本输入)、单位部门(下拉,全部单位/长庆油田总部/第一采油厂/第二采油厂/第三采油厂)
**表格列:** 序号、设备编号、设备厂家、设备型号、所属单位、所属部门、设备类型、入库日期、管理部门、管理人、管理人电话、厂家电话、操作(编辑/删除)
**表格列:** 序号、设备编号、设备厂家、设备型号、所属单位、所属部门、设备类型、入库日期、管理部门、管理人、管理人电话、厂家电话、操作(详情/编辑/删除)
**交互说明:**
- 点击"新增"跳转新增AED设备页面
- 点击"编辑"跳转编辑页面
- 点击"详情"跳转详情页面
- 点击"删除"弹出确认弹窗
- 支持批量导入、导出列表数据
- 支持异步批量导入、导出功能,导入会提供导入模板
---
@@ -377,30 +375,30 @@ stateDiagram-v2
**表单字段表:**
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|------|
| 设备编号 | 文本输入 | 是 | 格式如 AED-2025-006 |
| 是否对接 | 单选 | 是 | 是/否,选"是"显示厂家型号下拉,选"否"显示手动输入 |
| 设备厂家 | 下拉/文本 | 是 | 对接时下拉(迈瑞/飞利浦/卓尔/日本光电/其他),非对接时文本输入 |
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|--------------------------------------------------------------|
| 设备编号 | 文本输入 | 是 | 格式如 AED-2025-006 |
| 是否对接 | 单选 | 是 | 是/否,选"是"显示厂家型号下拉,选"否"显示手动输入 |
| 设备厂家 | 下拉/文本 | 是 | 对接时下拉(迈瑞/飞利浦/卓尔/日本光电/其他),非对接时文本输入 |
| 设备型号 | 下拉/文本 | 是 | 对接时下拉(BeneHeart C1A/C2/HeartStart FRx/HS1/AED Plus),非对接时文本输入 |
| 所属单位 | 下拉 | 是 | 长庆油田总部/第一采油厂/第二采油厂/第三采油厂 |
| 所属部门 | 下拉 | 是 | 安全环保部/综合管理部/生产运行部/人力资源部 |
| 设备类型 | 单选 | 是 | — |
| 入库日期 | 日期选择 | 是 | — |
| 出厂日期 | 日期选择 | 否 | — |
| 电量 | 数字输入 | 是 | — |
| 电极片是否完好 | 单选 | 是 | 是/否 |
| 电池有效期 | 日期选择 | 是 | — |
| 电极片有效期 | 日期选择 | 是 | — |
| 摄像头序列号 | 文本输入 | 否 | |
| 摄像头验证码 | 文本输入 | 否 | |
| 操作图片 | 图片上传 | 否 | — |
| 操作视频 | 视频上传 | 否 | — |
| 免责声明 | 文本域 | 否 | — |
| 管理部门 | 下拉 | 是 | — |
| 管理人 | 文本输入 | 是 | — |
| 管理人电话 | 文本输入 | 是 | 电话格式校验 |
| 厂家电话 | 文本输入 | 是 | 电话格式校验 |
| 所属单位 | 下拉 | 是 | 长庆油田总部/第一采油厂/第二采油厂/第三采油厂 |
| 所属部门 | 下拉 | 是 | 安全环保部/综合管理部/生产运行部/人力资源部 |
| 设备类型 | 单选 | 是 | — |
| 入库日期 | 日期选择 | 是 | — |
| 出厂日期 | 日期选择 | 否 | — |
| 电量 | 数字输入 | 是 | — |
| 电极片是否完好 | 单选 | 是 | 是/否 |
| 电池有效期 | 日期选择 | 是 | — |
| 电极片有效期 | 日期选择 | 是 | — |
| 摄像头序列号 | 文本输入 | 否 | 用于查看AED摄像头监控画面 |
| 摄像头验证码 | 文本输入 | 否 | 用于查看AED摄像头监控画面 |
| 操作图片 | 图片上传 | 否 | — |
| 操作视频 | 视频上传 | 否 | — |
| 免责声明 | 文本域 | 否 | — |
| 管理部门 | 下拉 | 是 | — |
| 管理人 | 文本输入 | 是 | — |
| 管理人电话 | 文本输入 | 是 | 电话格式校验 |
| 厂家电话 | 文本输入 | 是 | 电话格式校验 |
**交互说明:**
- "是否对接"切换时联动厂家/型号字段的输入方式
@@ -408,7 +406,6 @@ stateDiagram-v2
- 提交成功后返回列表页
---
### 13. AED布点管理(resource-aed-deploy.html
![页面截图](screenshots/resource-aed-deploy.jpg)
@@ -417,10 +414,11 @@ stateDiagram-v2
**筛选条件:** 设备编号(文本输入)、单位部门(下拉,全部单位/长庆油田总部/第一采油厂/第二采油厂/第三采油厂)、设备状态(下拉,全部/正常/异常/维修中)
**表格列:** 序号、设备编号、设备厂家、设备型号、所属单位、所属部门、布放地址、布放图片、设备状态(正常绿色/异常红色/维修中橙色)、设备电量、状态更新日期、摄像头监控、责任人、责任人电话、操作(编辑/删除)
**表格列:** 序号、设备编号、设备厂家、设备型号、所属单位、所属部门、布放地址(地图选点+手动补全)、布放图片、设备状态(正常绿色/异常红色/维修中橙色)、设备电量、状态更新日期、摄像头监控、责任人、责任人电话、操作(详情/编辑/删除)
**交互说明:**
- 点击"新增布点"跳转新增页面
- 布点位置支持手动在地图上选点,选点完成后可手动补全具体位置信息
- 支持批量导入、导出列表数据、查看导出任务
---
@@ -433,14 +431,14 @@ stateDiagram-v2
**表单字段表:**
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|------|
| 设备编号 | 搜索下拉 | 是 | 从设备台账中选择 |
| 布放地址 | 文本输入 | 是 | — |
| 详细地址 | 文本输入 | 是 | |
| 责任人 | 文本输入 | 是 | — |
| 责任人电话 | 文本输入 | 是 | 电话格式校验 |
| 布放图片 | 图片上传 | 否 | — |
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|----------------------|
| 设备编号 | 搜索下拉 | 是 | 从设备台账中选择 |
| 布放地址 | 地图选点 | 是 | — |
| 详细地址 | 文本输入 | 是 | 先回显地图选点的位置信息再补全具体的位置 |
| 责任人 | 文本输入 | 是 | — |
| 责任人电话 | 文本输入 | 是 | 电话格式校验 |
| 布放图片 | 图片上传 | 否 | — |
---
@@ -452,7 +450,8 @@ stateDiagram-v2
**交互说明:**
- 地图上以标记点展示设备位置
- 只读查看,不支持编辑操作
- 上方区域展示设备状态的统计数字
- 点击具体标点信息卡片展示AED概要信息
---
@@ -464,11 +463,11 @@ stateDiagram-v2
**筛选条件:** 姓名(文本输入)、单位部门(下拉,全部单位/长庆油田总部/第一采油厂/第二采油厂/第三采油厂)、证书状态(下拉,全部/有效/即将过期/已过期)
**表格列:** 序号、姓名、员工编号、所属单位、所属部门、联系电话、证书编号、证书类型、发证机构、取证日期、有效期至、证书状态(有效绿色/即将过期橙色/已过期红色)、操作(编辑/删除)
**表格列:** 序号、姓名、员工编号、所属单位、所属部门、联系电话、证书编号、证书类型、发证机构、取证日期、有效期至、证书状态(有效绿色/即将过期橙色/已过期红色)、操作(详情/编辑/删除)
**交互说明:**
- 点击"新增取证人员"跳转新增页面
- 支持导出列表数据
- 支持导出列表数据(同步导出)
---
### 17. 新增/编辑取证人员(resource-aed-certifier-add.html
@@ -479,16 +478,15 @@ stateDiagram-v2
**表单字段表:**
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|------|
| 姓名 | 文本输入 | 是 | — |
| 员工编号 | 文本输入 | 是 | — |
| 联系电话 | 文本输入 | 是 | 电话格式校验 |
| 证书编号 | 文本输入 | 是 | — |
| 证书类型 | 下拉 | 是 | 红十字救护员/AHA急救证书/EFR急救证书/其他 |
| 发证机构 | 下拉 | 是 | 中国红十字会/美国心脏协会(AHA)/其他 |
| 取证日期 | 日期选择 | 是 | — |
| 有效期至 | 日期选择 | 是 | 必须晚于取证日期 |
| 字段名 | 类型 | 必填 | 规则 |
|------|------|------|---------------------------|
| 选择员工 | 搜索框 | 是 | 查询员工信息,回显选中的查询结果 |
| 证书编号 | 文本输入 | 是 | — |
| 证书类型 | 下拉 | 是 | 红十字救护员/AHA急救证书/EFR急救证书/其他 |
| 发证机构 | 下拉 | 是 | 中国红十字会/美国心脏协会(AHA)/其他 |
| 取证日期 | 日期选择 | 是 | — |
| 有效期至 | 日期选择 | 是 | 必须晚于取证日期 |
| 证书照片 | 文件上传 | 是 | 证件照 |
---
@@ -498,9 +496,9 @@ stateDiagram-v2
**功能说明:** 管理AED设备的维护保养历史记录。
**筛选条件:** 设备编号(文本输入)、单位部门(下拉,全部单位/长庆油田总部/第一采油厂/第二采油厂/第三采油厂)、所属部门(下拉,全部部门/安全环保部/生产运行部/综合管理部
**筛选条件:** 设备编号(文本输入)、单位部门(下拉筛选
**表格列:** 序号、设备编号、设备厂家、设备型号、所属单位、所属部门、布放地址、维护内容、维护人、维护日期、操作(编辑/删除)
**表格列:** 序号、设备编号、设备厂家、设备型号、所属单位、所属部门、布放地址、维护内容、维护人、维护日期、操作(查看/编辑/删除)
**交互说明:**
- 点击"新增维护记录"跳转新增页面
@@ -516,12 +514,12 @@ stateDiagram-v2
**表单字段表:**
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|------|
| 设备编号 | 搜索下拉 | 是 | 从布点设备中选择 |
| 维护内容 | 多行文本 | 是 | — |
| 维护人 | 文本输入 | 是 | — |
| 维护日期 | 日期选择 | 是 | — |
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|-----------|
| 设备编号 | 搜索下拉 | 是 | 从AED设备中选择 |
| 维护内容 | 多行文本 | 是 | — |
| 维护人 | 文本输入 | 是 | — |
| 维护日期 | 日期选择 | 是 | — |
---
@@ -531,12 +529,13 @@ stateDiagram-v2
**功能说明:** 管理AED培训和演练活动记录,包含活动资料和效果评估。
**筛选条件:** 设备编号(文本输入)、单位部门(下拉,全部单位/长庆油田总部/第一采油厂/第二采油厂/第三采油厂)、所属部门(下拉,全部部门/安全环保部/生产运行部/综合管理部
**筛选条件:** 设备编号(文本输入)、单位部门(下拉筛选
**表格列:** 设备编号、所属单位、所属部门、布放地址、活动标题、活动日期、负责人、参加人数、签到表、现场照片、现场视频、活动资料、活动效果、操作(编辑/删除)
**表格列:** 设备编号、所属单位、所属部门、布放地址、活动标题、活动日期、负责人、参加人数、签到表、现场照片、现场视频、活动资料、活动效果、操作(详情/编辑/删除)
**交互说明:**
- 点击"新增培演记录"跳转新增页面
- 签到表 现场照片 现场视频 活动资料若上传了资料需要显示图片缩略图、播放按钮、下载按钮,若没有上传对应资料显示‘-’
- 支持导出列表数据
---
@@ -549,18 +548,18 @@ stateDiagram-v2
**表单字段表:**
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|------|
| 设备编号 | 搜索下拉 | 是 | 从布点设备中选择 |
| 活动标题 | 文本输入 | 是 | — |
| 活动日期 | 日期选择 | 是 | — |
| 负责人 | 文本输入 | 是 | — |
| 参加人数 | 数字输入 | 是 | — |
| 活动效果 | 下拉 | 否 | 优/良/中/差 |
| 签到表 | 文件上传 | 否 | — |
| 现场照片 | 图片上传 | 否 | — |
| 现场视频 | 视频上传 | 否 | — |
| 活动资料 | 文件上传 | 否 | — |
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|-----------|
| 设备编号 | 搜索下拉 | 是 | 从AED设备中选择 |
| 活动标题 | 文本输入 | 是 | — |
| 活动日期 | 日期选择 | 是 | — |
| 负责人 | 文本输入 | 是 | — |
| 参加人数 | 数字输入 | 是 | — |
| 活动效果 | 下拉 | 否 | 优/良/中/差 |
| 签到表 | 文件上传 | 否 | — |
| 现场照片 | 图片上传 | 否 | — |
| 现场视频 | 视频上传 | 否 | — |
| 活动资料 | 文件上传 | 否 | — |
---
@@ -570,9 +569,9 @@ stateDiagram-v2
**功能说明:** 记录AED设备的实际使用情况,包括被救治人症状和救治结果。
**筛选条件:** 设备编号(文本输入)、单位部门(下拉,全部单位/长庆油田总部/第一采油厂/第二采油厂/第三采油厂)、所属部门(下拉,全部部门/安全环保部/生产运行部/综合管理部
**筛选条件:** 设备编号(文本输入)、单位部门(下拉筛选
**表格列:** 序号、设备编号、所属单位、所属部门、布放地址、使用日期、被救治人、症状(呼吸)、症状(意识)、使用人、使用过程说明、应用结果、操作(编辑/删除)
**表格列:** 序号、设备编号、所属单位、所属部门、布放地址、使用日期、被救治人、症状(呼吸)、症状(意识)、使用人、使用过程说明、应用结果、操作(详情/编辑/删除)
**交互说明:**
- 点击"新增应用记录"跳转新增页面
@@ -605,15 +604,15 @@ stateDiagram-v2
![页面截图](screenshots/resource-ambulance.jpg)
**功能说明:** 管理救护车车辆信息,包括车型、救护类型、覆盖区域和GPS安装状态。
**功能说明:** 展示医疗点模块中救护车车辆信息,包括车型、救护类型、覆盖区域和GPS安装状态。
**筛选条件:** 车牌号(文本输入)、所属单位(下拉,长庆油田总部/第一采油厂/第二采油厂/第三采油厂)、所属医疗点(下拉,长庆油田总部医疗点/第一采油厂南梁健康管理服务中心/第二采油厂南梁健康管理服务中心)、救护类型(下拉,转运型/监护型/急救型)
**筛选条件:** 车牌号(文本输入)、所属单位(下拉)、所属医疗点(下拉)、救护类型(下拉,转运型/监护型/急救型)
**表格列:** 序号、车牌号、救护类型、车型、所属医疗点、所属单位、驾驶员姓名、驾驶员联系电话、覆盖区域、覆盖人数、是否安装GPS、操作(查看详情/编辑/删除
**表格列:** 序号、车牌号、救护类型、车型、所属医疗点、所属单位、驾驶员姓名、驾驶员联系电话、覆盖区域、覆盖人数、是否安装GPS、操作(查看详情)
**交互说明:**
- 点击"查看详情"打开右侧抽屉加载救护车详情页
- 支持新增、编辑、删除和导出
- 支持异步导出救护车数据
---
@@ -635,9 +634,9 @@ stateDiagram-v2
**功能说明:** 管理急救包的布放信息和内配用品清单。
**筛选条件:** 急救包编号(文本输入)、所属单位(下拉,全部单位/长庆油田总部/第一采油厂/第二采油厂/第三采油厂)、管理部门(下拉,全部部门/长庆油田总部/第一采油厂/第二采油厂/第三采油厂
**筛选条件:** 急救包编号(文本输入)、所属单位(下拉)、管理部门(下拉
**表格列:** 序号、急救包编号、所属单位、布放地址、布放日期、内配用品(链接)、管理部门、管理人、管理人电话、操作(编辑/删除)
**表格列:** 序号、急救包编号、所属单位、布放地址、布放日期、内配用品(链接)、管理部门、管理人、管理人电话、操作(详情/编辑/删除)
**业务规则:**
- 点击"内配用品"链接弹出内配用品清单弹窗
@@ -656,11 +655,11 @@ stateDiagram-v2
**表单字段表:**
| 字段名 | 类型 | 必填 | 规则 |
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|------|
| 急救包编号 | 文本输入 | 是 | — |
| 所属单位 | 下拉 | 是 | 长庆油田总部/第一采油厂/第二采油厂/第三采油厂 |
| 布放地址 | 文本输入 | 是 | — |
| 所属单位 | 下拉 | 是 | 长庆油田总部/第一采油厂/第二采油厂/第三采油厂 |
| 布放地址 | 地图选点 | 是 | — |
| 布放日期 | 日期选择 | 是 | — |
| 管理部门 | 文本输入 | 是 | — |
| 管理人 | 文本输入 | 是 | — |
@@ -675,9 +674,9 @@ stateDiagram-v2
**功能说明:** 管理急救医生档案,包括职称、科室、专长和签约状态。
**筛选条件:** 姓名(文本输入)、所在医院(下拉,全部医院/长庆油田职工医院/西安市第一医院/庆阳市人民医院/定边县医院)、是否签约入库(下拉,全部/是/否)
**筛选条件:** 姓名(文本输入)、所在医院(下拉)、是否签约入库(下拉,全部/是/否)
**表格列:** 序号、姓名、图片、性别、年龄、职称、科室、所在医院、急救专长、联系电话、是否签约入库、操作(编辑/删除)
**表格列:** 序号、姓名、图片、性别、年龄、职称、科室、所在医院、急救专长、联系电话、是否签约入库、操作(详情/编辑/删除)
**交互说明:**
- 点击"新增"跳转新增急救医生页面
@@ -694,19 +693,19 @@ stateDiagram-v2
**表单字段表:**
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|------|
| 姓名 | 文本输入 | 是 | — |
| 图片 | 图片上传 | 否 | — |
| 性别 | 单选 | 是 | 男/女 |
| 年龄 | 数字输入 | 否 | — |
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|----------------------|
| 姓名 | 文本输入 | 是 | — |
| 图片 | 图片上传 | 否 | — |
| 性别 | 单选 | 是 | 男/女 |
| 年龄 | 数字输入 | 否 | — |
| 职称 | 下拉 | 是 | 主任医师/副主任医师/主治医师/住院医师 |
| 科室 | 文本输入 | 是 | — |
| 所在医院 | 下拉 | 是 | 长庆油田职工医院/西安市第一医院/庆阳市人民医院/定边县医院 |
| 急救专长 | 多行文本 | 否 | — |
| 联系电话 | 文本输入 | 是 | 电话格式校验 |
| 是否签约入库 | 单选 | 是 | 是/否 |
| 签约有效期 | 日期选择 | 否 | 签约入库为"是"时显示 |
| 科室 | 文本输入 | 是 | — |
| 所在医院 | 下拉 | 是 | 从系统管理中医院列表选取 |
| 急救专长 | 多行文本 | 否 | — |
| 联系电话 | 文本输入 | 是 | 电话格式校验 |
| 是否签约入库 | 单选 | 是 | 是/否 |
| 签约有效期 | 日期选择 | 否 | 签约入库为"是"时显示 |
---
@@ -716,12 +715,17 @@ stateDiagram-v2
**功能说明:** 查看和维护员工的单位紧急联系人和亲友紧急联系人信息。
**筛选条件:** 姓名(文本输入)、员工编号(文本输入)、单位部门(下拉,全部/长庆油田总部/第一采油厂/第二采油厂/第三采油厂
**筛选条件:** 姓名(文本输入)、员工编号(文本输入)、单位部门(下拉)
**表格列:** 序号、姓名、员工编号、性别、年龄、单位、部门、单位紧急联系人、亲友紧急联系人、操作(编辑)
**业务规则:**
- 列表显示全部员工信息(按管理部门做数据权限控制)
- 单位紧急联系人默认是本单位的健康管理员(随组织架构维护),更换单位联系人需要从员工所在单位的其他成员中选择,单位联系人只能有一个
- 亲友紧急联系人支持手动添加,上限为3个
**交互说明:**
- 点击"编辑"打开同页编辑弹窗,可修改联系人信息
- 点击"编辑"打开同页编辑弹窗,可修改单位紧急联系人信息和亲友紧急联系人
- 亲友联系人支持多行动态增删
---
@@ -732,20 +736,24 @@ stateDiagram-v2
![页面截图](screenshots/center-basic-info.jpg)
**功能说明:** 管理应急中心基础信息、账号配置和默认中心设置。
**功能说明:** 管理应急中心基础信息、关联医疗点和默认中心设置。
**筛选条件:** 中心名称(文本输入)、管理单位(下拉,全部/长庆油田公司/采油一厂/采油二厂)、开启状态(下拉,全部/已开启/已关闭)
**筛选条件:** 中心名称(文本输入)、管理单位(下拉筛选)、开启状态(下拉,全部/已开启/已关闭)
**表格列:** 序号、应急中心名称、大屏标题、简称、管理单位、中心电话、云坐席电话、值班电话、详细地址、负责人、负责人电话、账号信息(链接)、开启状态(开关)、是否默认中心(开关)、操作(详情/编辑/删除)
**表格列:** 序号、应急中心名称、大屏标题、简称、管理单位、中心电话、云坐席电话、值班电话、详细地址、负责人、负责人电话、账号信息(操作人员、专业人员、管理员、大屏账号链接人员列表)、开启状态(开关)、是否默认中心(开关)、操作(详情/编辑/删除)
**业务规则:**
- 默认中心全局唯一,切换时弹出确认弹窗
- 默认中心全局唯一,作为整个应急就医系统中业务兜底的存在,需要更换默认应急中心时弹出确认弹窗
- 账号信息弹窗展示四类账号:操作人员、专业人员、管理员、大屏账号
- 应急中心作为应急业务开展的最小组织单元,后续的应急工单和云坐席等配置均围绕应急中心开展
- 应急中心管理员只能查看当前应急中心的信息
**交互说明:**
- 点击"新增应急中心"跳转新增页面
- 点击"编辑"跳转搞编辑页面
- 点击"详情"打开右侧抽屉加载应急中心详情
- 点击"账号信息"弹出账号列表弹窗,表格列:操作人员/专业人员/管理员/大屏账号
- 点击"关联医疗点"跳转到医疗点关联关系选择界面
- 切换"是否默认中心"弹出确认弹窗
- 支持导出列表数据
@@ -759,24 +767,24 @@ stateDiagram-v2
**表单字段表:**
| 字段名 | 区域 | 类型 | 必填 | 规则 |
|--------|------|------|------|------|
| 中心名称 | 基本信息 | 文本输入 | 是 | — |
| 大屏标题 | 基本信息 | 文本输入 | 否 | |
| 简称 | 基本信息 | 文本输入 | 是 | |
| 管理单位 | 基本信息 | 下拉 | 是 | 长庆油田公司/采油一厂/采油二厂/采油三厂/采气一厂 |
| 大屏路由 | 基本信息 | 文本输入 | 否 | |
| 详细地址 | 基本信息 | 地图选点+文本 | 是 | 含地图选点和文本输入 |
| 中心电话 | 服务信息 | 文本输入 | 是 | 电话格式校验 |
| 云坐席电话 | 服务信息 | 文本输入 | 否 | |
| 值班电话 | 服务信息 | 动态行文本 | 是 | 至少一条,支持增删 |
| 上班时间 | 服务信息 | 动态时段 | 否 | 起止时间格式校验 |
| 服务范围 | 服务信息 | 穿梭框多选 | 是 | 从可选单位列表中选择 |
| 负责人 | 服务信息 | 文本输入 | 否 | — |
| 负责电话 | 服务信息 | 文本输入 | 否 | 电话格式校验 |
| 建成日期 | 服务信息 | 日期选择 | 否 | — |
| 投用日期 | 服务信息 | 日期选择 | 否 | — |
| 配备金额 | 服务信息 | 数字输入 | 否 | — |
| 字段名 | 区域 | 类型 | 必填 | 规则 |
|--------|------|------|------|-----------------------------|
| 中心名称 | 基本信息 | 文本输入 | 是 | — |
| 大屏标题 | 基本信息 | 文本输入 | 否 | 配置各个应急中心应急大屏标题名称 |
| 简称 | 基本信息 | 文本输入 | 是 | 用于应急大屏标题 |
| 管理单位 | 基本信息 | 下拉 | 是 | 长庆油田公司/采油一厂/采油二厂/采油三厂/采气一厂 |
| 大屏路由 | 基本信息 | 文本输入 | 否 | 应急大屏访问地址 |
| 详细地址 | 基本信息 | 地图选点+文本 | 是 | 含地图选点和文本输入 |
| 中心电话 | 服务信息 | 文本输入 | 是 | 值班室电话 |
| 云坐席电话 | 服务信息 | 文本输入 | 否 | 应急中心转接的云坐席呼入 |
| 值班电话 | 服务信息 | 动态行文本 | 是 | 至少配置一个,支持增删 |
| 上班时间 | 服务信息 | 动态时段 | 否 | 起止时间格式校验 |
| 服务范围 | 服务信息 | 穿梭框多选 | 是 | 从可选单位列表中选择,各中心覆盖的服务范围不能出现重复 |
| 负责人 | 服务信息 | 文本输入 | 否 | — |
| 负责电话 | 服务信息 | 文本输入 | 否 | 电话格式校验 |
| 建成日期 | 服务信息 | 日期选择 | 否 | — |
| 投用日期 | 服务信息 | 日期选择 | 否 | — |
| 配备金额 | 服务信息 | 数字输入 | 否 | — |
---
@@ -795,86 +803,38 @@ stateDiagram-v2
![页面截图](screenshots/center-work-order.jpg)
**功能说明:** 统一管理所有应急工单,支持多维度筛选和角色视角切换
**功能说明:** 管理员查看所有应急工单,支持多维度筛选。
**筛选条件:** 年份选择(下拉,2026/2025/2024)、工单编号(文本输入)、求助员工(文本输入)、员工编号(文本输入)、单位部门(下拉,公司机关/采油一厂/采油二厂)、应急中心(下拉)、工单状态(下拉,全部/进行中/已完成)、求助方式(下拉,全部/应急视频/应急电话/拨打120/线下应急)、时间范围(日期范围选择器)
**表格列:** 序号、应急工单编号、求助员工、员工编号、所属单位、所属部门、求助方式、求助时间、应急中心、专业人员、操作人员、驻场人员、工单状态(进行中蓝色/已完成绿色)、操作(详细过程)
**业务规则:**
- 支持按角色参数切换视图(管理员/操作人员)
- 操作人员视角显示"新增应急工单"按钮
- 管理员只能查看应急功能,不能操作应急工单
- 应急中心管理员只能看到当前应急中心的应急工单
**交互说明:**
- 点击"详细过程"跳转工单详情页
- 点击"新增应急工单"跳转新增工单页面
- 支持导出列表数据、查看导出任务
---
### 35. 新增应急工单(center-work-order-add.html
![页面截图](screenshots/center-work-order-add.jpg)
**功能说明:** 创建线下应急或通话补单工单,包含基本信息、处置过程和转运信息三个区域。
**表单字段表:**
| 字段名 | 区域 | 类型 | 必填 | 规则 |
|--------|------|------|------|------|
| 求助员工 | 基本信息 | 搜索选择 | 是 | 从员工列表中搜索选择 |
| 求助方式 | 基本信息 | 下拉/参数带入 | 是 | 线下应急/应急电话等 |
| 求助时间 | 基本信息 | 日期时间 | 是 | — |
| 操作人员 | 基本信息 | 下拉 | 是 | 张操作/李操作/王操作 |
| 专业人员 | 处置过程 | 下拉 | 否 | 李医生/陈医生/赵医生 |
| 完成时间 | 处置过程 | 日期时间 | 否 | — |
| 救助意见 | 处置过程 | 多行文本 | 否 | — |
| 救助结果 | 处置过程 | 多行文本 | 否 | — |
| 相关照片 | 处置过程 | 图片上传 | 否 | — |
| 补充小结 | 处置过程 | 动态行文本 | 否 | 支持增删,序号自动重排 |
| 派单时间 | 驻场信息 | 日期时间 | 否 | — |
| 派单说明 | 驻场信息 | 多行文本 | 否 | — |
| 驻场人员 | 驻场信息 | 下拉 | 否 | 王旭/刘鑫/陈浩/赵旭 |
| 结束时间 | 驻场信息 | 日期时间 | 否 | — |
| 驻场说明 | 驻场信息 | 多行文本 | 否 | — |
| 选择救护车 | 转运信息 | 搜索选择 | 否 | 选择后自动回填驾驶员信息 |
| 随行人 | 转运信息 | 文本输入 | 否 | — |
| 随行人电话 | 转运信息 | 文本输入 | 否 | 电话格式校验 |
| 目的地 | 转运信息 | 文本输入 | 否 | — |
| 备注信息 | 转运信息 | 多行文本 | 否 | — |
**交互说明:**
- `from=call` 参数时自动回填员工信息并固定求助方式
- 选择救护车后自动带出驾驶员信息
- 提交成功后返回应急工单列表
---
### 36. 工单详情(center-work-order-detail.html
### 35. 工单详情center-work-order-detail.html
![页面截图](screenshots/center-work-order-detail.jpg)
**功能说明:** 查看工单处置全过程,包含基本信息、处置过程、驻场信息和转运信息四个区域。根据当前登录角色控制可操作范围
**功能说明:** 查看工单处置全过程,包含基本信息、处置过程、驻场信息和转运信息四个区域。管理员只能查看不能对工单进行操作
**角色权限:**
- 管理员(默认):仅查看,所有编辑按钮、补充小结按钮、结束应急按钮均隐藏
- 操作人员(`?role=operator`):可编辑救护车支援信息、救助结果、相关照片、补充小结;救助意见字段只读
- 专业人员(`?role=professional`):仅可编辑救助意见;救助结果、相关照片字段只读,救护车支援信息和补充小结不可操作
**业务规则:**
- 非管理员角色在工单状态为"处理中"时,基本信息卡片右上角显示"结束应急"按钮
- 不可编辑的字段以只读样式展示(灰底、禁用输入),而非隐藏
- 结束应急需二次确认
**交互说明:**
- 点击"结束应急"弹出确认弹窗
- 支持查看地图弹窗(展示求助位置)
- 编辑后保存回写当前工单
- 面包屑返回应急工单列表
---
### 37. 坐席管理(center-group.html
### 36. 坐席管理(center-group.html
![页面截图](screenshots/center-group.jpg)
@@ -886,116 +846,96 @@ stateDiagram-v2
**交互说明:**
- 点击"新增坐席"打开同页弹窗
- 点击"编辑"打开编辑页面
- 点击"删除"打开删除的二次弹窗
- 弹窗表单字段:坐席工号(文本输入,必填)、所属应急中心(下拉,必填,长庆油田应急中心/西安基地应急中心)
---
### 38. 通话记录(center-call-record.html
### 37. 通话记录(center-call-record.html
![页面截图](screenshots/center-call-record.jpg)
**功能说明:** 查看呼叫中心全量通话记录,支持关联工单和补建工单
**功能说明:** 查看呼叫中心全量通话记录,支持关联工单查看和新建工单(只有操作人员才能新建工单)
**筛选条件:** 年份选择(下拉,2026/2025/2024)、员工姓名(文本输入)、员工编号(文本输入)、单位部门(下拉)、应急中心(下拉)、坐席工号(文本输入)、接入电话(文本输入)、接听状态(下拉,全部/已接听/未接听)、拨打时间(日期范围)
**表格列:** 序号、通话编号、员工姓名、员工编号、单位部门、呼叫中心、坐席工号、接入电话、拨打时间、接听状态(已接听绿色/未接听红色)、接听时间、结束时间、通话时长、操作
**业务规则:**
- 已接听记录操作列显示"查看应急工单"(跳转工单详情
- 未接听记录操作列显示"新建应急工单"(跳转新增工单并带参)
- 操作人员通过主观判断本次通话是否要转换一条应急工单,若需要转换为应急工单可点击‘新建应急工单’,一条通话记录只能转换为一条应急工单,已经新建应急工单的支持在列表查看工单详情
- 通话状态、通话时长需要和云坐席平台做数据对接
**交互说明:**
- 点击"查看应急工单"跳转工单详情
- 点击"新建应急工单"跳转新增工单页面,自动回填员工信息和求助方式
- 点击"新建应急工单"跳转新增工单页面,自动回填员工信息和求助方式(应急电话)
- 支持导出列表数据、查看导出任务
---
### 39. 重症就医(center-serious-illness.html
### 38. 大病就医(center-serious-illness.html
![页面截图](screenshots/center-serious-illness.jpg)
**功能说明:** 管理大病就医预约申请列表,支持审核和派单操作
**功能说明:** 管理员查看大病就医记录信息
**筛选条件:** 年份选择(下拉,2026/2025/2024)、就医员工(文本输入)、员工编号(文本输入)、员工单位部门(下拉,公司机关/采油一厂/采油二厂/采气一厂/第一采油厂)、预约状态(下拉,待确认/已确认/已完成/已取消)
**筛选条件:** 年份选择(下拉,2026/2025/2024)、就医员工(文本输入)、员工编号(文本输入)、员工单位部门(下拉)、预约状态(下拉,待确认/已确认/已完成/已取消)
**表格列:** 序号、就医员工、员工编号、员工单位、员工部门、预约医院、挂号类别、预约科室、预约医生、期望预约时间、驻场人员、预约状态(待确认橙色/已确认蓝色/已完成绿色/已取消灰色)、创建时间、完成时间、操作(详细过程)
**业务规则:**
- 应急中心管理员只能看到当前应急中心的大病就医记录
**交互说明:**
- 点击"详细过程"跳转重症就医详情
- 操作人员视角显示"新增大病就医"按钮
- 点击"详细过程"跳转大病就医详情
- 操作人员视角显示"新增大病就医"按钮,管理员无此权限
- 支持导出列表数据、查看导出任务
---
### 40. 新增重症就医(center-serious-illness-add.html
![页面截图](screenshots/center-serious-illness-add.jpg)
**功能说明:** 新建大病就医预约,支持油田员工和非油田员工两种来源。
**表单字段表:**
| 字段名 | 类型 | 必填 | 规则 |
|--------|------|------|------|
| 员工类型 | 单选 | 是 | 油田员工/非油田员工,切换后联动下方字段 |
| 就医员工 | 搜索选择 | 是 | 油田员工时显示,从员工列表搜索选择 |
| 姓名 | 文本输入 | 是 | 非油田员工时显示 |
| 身份证号 | 文本输入 | 是 | 非油田员工时显示,身份证格式校验 |
| 手机号 | 文本输入 | 是 | 非油田员工时显示,手机号格式校验 |
| 身份信息 | 展示区域 | — | 选择员工后自动回填展示 |
| 预约医院 | 搜索下拉 | 是 | 从医院列表中选择 |
| 就诊卡号 | 文本输入 | 否 | — |
| 挂号类别 | 单选 | 是 | 专家号/急诊号/普通号 |
| 期望预约时间 | 日期时间 | 是 | — |
| 预约科室 | 下拉 | 否 | 与医院联动 |
| 预约医生 | 下拉 | 否 | 与科室联动 |
| 病情描述 | 多行文本 | 否 | — |
**交互说明:**
- 切换"员工类型"联动显示不同的员工信息录入方式
- 选择油田员工后自动回填身份信息区域
- 提交成功后返回重症就医列表
---
### 41. 重症就医详情(center-serious-illness-detail.html
### 40. 大病就医详情(center-serious-illness-detail.html
![页面截图](screenshots/center-serious-illness-detail.jpg)
**功能说明:** 展示大病就医预约的完整详情,包含预约信息、审核处置和驻场服务三个区域。支持驳回和派单操作。
**业务规则:**
- 待确认状态下显示"驳回"和"立即派单"按钮
- 操作人员视角下待确认状态下显示"驳回"和"立即派单"按钮,管理员无此权限
- 已确认状态下显示驻场人员信息
- 已完成状态下显示完整流程记录
- 已取消显示取消原因和取消操作人信息
- 各状态下详情页展示的内容不同,详见原型图
**交互说明:**
- 点击"驳回"弹出驳回弹窗,需填写驳回原因(必填)
- 点击"立即派单"弹出派单弹窗,选择驻场人员并填写派单说明
- 操作完成后页面刷新为对应结果态
- 面包屑返回重症就医列表
- 面包屑返回大病就医列表
---
### 42. 数据大屏配置(center-data-screen.html
### 41. 数据大屏配置(center-data-screen.html
![页面截图](screenshots/center-data-screen.jpg)
**功能说明:** 配置应急中心数据大屏的展示模块和指标数据。
**功能说明:** 配置应急中心数据大屏的展示模块和指标数据。
**业务规则:**
- 按应急中心切换配置面板
- 各模块支持独立开关,关闭后对应配置区域不可编辑
- 各模块支持独立开关,关闭后大屏使用真实业务数据,开启后大屏使用配置的数据替换真实业务数据
- 支持动态新增医疗点并拖拽排序
- 超级管理员能查看并设置所有应急大屏的假数据
- 应急中心管理员只能看到和设置当前应急中心大屏的假数据
**交互说明:**
- 切换应急中心加载对应配置
- 模块开关控制配置区域的可编辑状态
- 保存后作为大屏展示数据源
- 保存并开启后作为大屏展示数据源
---
### 43. 排班管理(center-schedule.html
### 42. 排班管理(center-schedule.html
![页面截图](screenshots/center-schedule.jpg)
@@ -1005,7 +945,9 @@ stateDiagram-v2
**业务规则:**
- 按周展示排班表,支持前后周切换
- 编辑态可批量调整人员并保存
- 编辑态可批量调整人员并保存,专业人员和操作人员均可多选
- 超级管理员能查看并设置所有应急中心的排班
- 应急中心管理员只能看到和设置当前应急中心的排班
**交互说明:**
- 点击排班单元格弹出同页人员选择弹层
@@ -1014,28 +956,30 @@ stateDiagram-v2
---
### 44. 模拟急救(center-simulation.html
### 43. 模拟急救(center-simulation.html
![页面截图](screenshots/center-simulation.jpg)
![页面截图](screenshots/center-simulation-deploy.jpg)
**功能说明:** 模拟急救联动流程,用于演示和测试应急处置链路。
**筛选条件:** 姓名(文本输入)、员工编号(文本输入)、单位部门(下拉,全部/公司机关/采油一厂/采油二厂/采气一厂/长庆油田总医院
**筛选条件:** 姓名(文本输入)、员工编号(文本输入)、单位部门(下拉)
**表格列:** 序号、姓名、员工编号、性别、年龄、单位、部门、应急求助次数、移动端模拟急救次数、操作(模拟急救)
**业务规则:**
- 展示所有员工(并不是只展示存在数据的员工)
- 模拟急救弹窗中可选择病种场景:心梗、猝死、脑出血/脑梗
**交互说明:**
- 点击"模拟急救"打开同页弹窗
- 选择病种后触发模拟导航链路
- 点击"模拟急救"打开同页弹窗(左侧展示地图资源和三种疾病标签,右侧展示员工信息和模拟结果)
- 选择病种点击模拟急救地图展示附近最近的应急资源,同时在右侧下发急救提示书和应急资源列表,点击导航在地图上规划路径
---
## 四、异常事件
### 45. 异常结果(exception-result.html
### 44. 异常结果(exception-result.html
![页面截图](screenshots/exception-result.jpg)
@@ -1051,7 +995,7 @@ stateDiagram-v2
---
### 46. 异常数据(exception-dirty.html
### 45. 系统脏数据(exception-dirty.html
![页面截图](screenshots/exception-dirty.jpg)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 648 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 60 KiB

@@ -242,7 +242,6 @@
<th>联系电话</th>
<th>医院简介</th>
<th>应急专长</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
@@ -256,7 +255,6 @@
<td>029-85323112</td>
<td>综合性三甲教学医院,西北地区医疗中心</td>
<td>心脑血管急救、创伤外科</td>
<td><div class="switch on" onclick="this.classList.toggle('on')"></div></td>
<td><div class="action-btns"><span class="link" onclick="openDrawer()">编辑</span><span class="link-danger" onclick="openConfirm(this,'确认删除该医院信息?')">删除</span></div></td>
</tr>
<tr>
@@ -268,7 +266,6 @@
<td>029-86518000</td>
<td>长庆油田直属职工医疗保障机构</td>
<td>职业病防治、常规急救</td>
<td><div class="switch on" onclick="this.classList.toggle('on')"></div></td>
<td><div class="action-btns"><span class="link" onclick="openDrawer()">编辑</span><span class="link-danger" onclick="openConfirm(this,'确认删除该医院信息?')">删除</span></div></td>
</tr>
<tr>
@@ -280,7 +277,6 @@
<td>029-85251331</td>
<td>省属大型综合三甲医院</td>
<td>急诊重症、中毒救治</td>
<td><div class="switch on" onclick="this.classList.toggle('on')"></div></td>
<td><div class="action-btns"><span class="link" onclick="openDrawer()">编辑</span><span class="link-danger" onclick="openConfirm(this,'确认删除该医院信息?')">删除</span></div></td>
</tr>
<tr>
@@ -293,7 +289,6 @@
<td>0934-8612116</td>
<td>庆阳地区综合性二甲医院</td>
<td>基层急救、骨伤科</td>
<td><div class="switch on" onclick="this.classList.toggle('on')"></div></td>
<td><div class="action-btns"><span class="link" onclick="openDrawer()">编辑</span><span class="link-danger" onclick="openConfirm(this,'确认删除该医院信息?')">删除</span></div></td>
</tr>
<tr>
@@ -306,7 +301,6 @@
<td>0911-2881111</td>
<td>延安区域重点综合医院</td>
<td>野外急救、高原病救治</td>
<td><div class="switch" onclick="this.classList.toggle('on')"></div></td>
<td><div class="action-btns"><span class="link" onclick="openDrawer()">编辑</span><span class="link-danger" onclick="openConfirm(this,'确认删除该医院信息?')">删除</span></div></td>
</tr>
</tbody>
@@ -155,13 +155,13 @@
</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></tr></thead>
<thead><tr><th>序号</th><th>医疗点名称</th><th>所属单位</th><th>所属医院</th><th>关联应急中心</th><th>地址</th><th>负责人</th><th>联系电话</th><th>医护人员数量</th><th>操作</th></tr></thead>
<tbody>
<tr><td>1</td><td style="font-weight:500;">公司机关医疗点</td><td>公司机关</td><td>宝石花医院</td><td>西安应急中心</td><td>西安市未央区长庆大厦1楼</td><td>王医生</td><td>029-86518001</td><td>3</td><td><div class="switch on" onclick="this.classList.toggle('on')"></div></td><td><div class="action-btns"><span class="link" onclick="openDrawer()">详情</span></div></td></tr>
<tr><td>2</td><td style="font-weight:500;">采油一厂医疗点</td><td>采油一厂</td><td>宝石花医院</td><td>庆阳应急中心</td><td>庆阳市西峰区采油一厂办公楼</td><td>李医生</td><td>0934-8612001</td><td>5</td><td><div class="switch on" onclick="this.classList.toggle('on')"></div></td><td><div class="action-btns"><span class="link" onclick="openDrawer()">详情</span></div></td></tr>
<tr><td>3</td><td style="font-weight:500;">采油二厂医疗点</td><td>采油二厂</td><td>宝石花医院</td><td>庆阳应急中心</td><td>庆阳市庆城县采油二厂基地</td><td>张医生</td><td>0934-3221001</td><td>4</td><td><div class="switch on" onclick="this.classList.toggle('on')"></div></td><td><div class="action-btns"><span class="link" onclick="openDrawer()">详情</span></div></td></tr>
<tr><td>4</td><td style="font-weight:500;">采气一厂医疗点</td><td>采气一厂</td><td>宝石花医院</td><td>榆林应急中心</td><td>榆林市靖边县采气一厂</td><td>赵护士</td><td>0912-4837001</td><td>2</td><td><div class="switch" onclick="this.classList.toggle('on')"></div></td><td><div class="action-btns"><span class="link" onclick="openDrawer()">详情</span></div></td></tr>
<tr><td>5</td><td style="font-weight:500;">输油处医疗点</td><td>输油处</td><td>宝石花医院</td><td>西安应急中心</td><td>西安市灞桥区输油处办公区</td><td>刘医生</td><td>029-83518001</td><td>2</td><td><div class="switch on" onclick="this.classList.toggle('on')"></div></td><td><div class="action-btns"><span class="link" onclick="openDrawer()">详情</span></div></td></tr>
<tr><td>1</td><td style="font-weight:500;">公司机关医疗点</td><td>公司机关</td><td>宝石花医院</td><td>西安应急中心</td><td>西安市未央区长庆大厦1楼</td><td>王医生</td><td>029-86518001</td><td>3</td><td><div class="action-btns"><span class="link" onclick="openDrawer()">详情</span></div></td></tr>
<tr><td>2</td><td style="font-weight:500;">采油一厂医疗点</td><td>采油一厂</td><td>宝石花医院</td><td>庆阳应急中心</td><td>庆阳市西峰区采油一厂办公楼</td><td>李医生</td><td>0934-8612001</td><td>5</td><td><div class="action-btns"><span class="link" onclick="openDrawer()">详情</span></div></td></tr>
<tr><td>3</td><td style="font-weight:500;">采油二厂医疗点</td><td>采油二厂</td><td>宝石花医院</td><td>庆阳应急中心</td><td>庆阳市庆城县采油二厂基地</td><td>张医生</td><td>0934-3221001</td><td>4</td><td><div class="action-btns"><span class="link" onclick="openDrawer()">详情</span></div></td></tr>
<tr><td>4</td><td style="font-weight:500;">采气一厂医疗点</td><td>采气一厂</td><td>宝石花医院</td><td>榆林应急中心</td><td>榆林市靖边县采气一厂</td><td>赵护士</td><td>0912-4837001</td><td>2</td><td><div class="action-btns"><span class="link" onclick="openDrawer()">详情</span></div></td></tr>
<tr><td>5</td><td style="font-weight:500;">输油处医疗点</td><td>输油处</td><td>宝石花医院</td><td>西安应急中心</td><td>西安市灞桥区输油处办公区</td><td>刘医生</td><td>029-83518001</td><td>2</td><td><div class="action-btns"><span class="link" onclick="openDrawer()">详情</span></div></td></tr>
</tbody>
</table>
</div>
@@ -0,0 +1,329 @@
<!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(--primary);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-refresh{width:36px;height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-secondary);flex-shrink:0;transition:all .2s;}
.btn-refresh:hover{color:var(--primary);border-color:var(--primary);}
.btn-refresh svg{width:16px;height:16px;transition:transform .4s ease;}
.btn-refresh.spinning svg{transform:rotate(360deg);}
.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--onsite{background:#F9F0FF;color:#722ED1;}
.msg-avatar--professional{background:#FFF7E6;color:var(--warning);}
.msg-avatar--operator{background:var(--primary-light);color:var(--primary);}
.msg-avatar--assistant{background:#F6FFED;color:var(--success);}
.msg-avatar--expert{background:#F6FFED;color:var(--success);}
.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--onsite{background:#F9F0FF;color:#722ED1;}
.role-tag--professional{background:#FFF7E6;color:var(--warning);}
.role-tag--operator{background:var(--primary-light);color:var(--primary);}
.role-tag--assistant{background:#F6FFED;color:var(--success);}
.role-tag--expert{background:#F6FFED;color:var(--success);}
.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;}
.bubble__avatar.other{background:#F9F0FF;color:#722ED1;}
.bubble__avatar.me{background:var(--primary-light);color:var(--primary);}
.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(--primary);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;}
.btn-contacts{width:36px;height:36px;border-radius:var(--radius-sm);cursor:pointer;border:1px solid var(--primary);background:#fff;color:var(--primary);display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;transition:all .2s;}
.btn-contacts:hover{background:var(--primary);color:#fff;}
.btn-contacts svg{width:16px;height:16px;}
/* 弹窗 */
.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="#1890FF"/><path d="M14 6v7l5 3" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><circle cx="14" cy="14" r="8" stroke="#fff" stroke-width="2" fill="none"/></svg>
应急就医–操作人员
</div>
<nav class="top-bar__nav">
<a href="emergency-active.html">正在应急</a>
<a href="chat-message.html" class="active">对话消息</a>
<a href="work-order.html">应急工单</a>
<a href="call-record.html">通话记录</a>
<a href="serious-illness.html">大病就医</a>
<a href="duty-group.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" title="通讯录" onclick="openOverlay('../../health-consult/assistant/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>
<button class="btn-refresh" title="刷新" onclick="refreshMsgList(this)">
<svg viewBox="0 0 16 16" fill="none"><path d="M13.5 8a5.5 5.5 0 1 1-1.3-3.6" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/><path d="M13.5 2.5v3h-3" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="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--onsite"></div>
<div class="msg-info">
<div class="msg-info__top"><span class="msg-info__name">赵刚</span><span class="msg-info__time">14:35</span></div>
<div class="msg-info__mid"><span class="role-tag role-tag--onsite">驻场人员</span></div>
<div class="msg-info__preview">采油二厂现场已到位,患者意识清醒</div>
</div>
<div class="msg-badge">2</div>
</div>
<div class="msg-item" onclick="selectMsg(this,1)">
<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">14:20</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,2)">
<div class="msg-avatar msg-avatar--assistant"></div>
<div class="msg-info">
<div class="msg-info__top"><span class="msg-info__name">健康小助手</span><span class="msg-info__time">14:00</span></div>
<div class="msg-info__mid"><span class="role-tag role-tag--assistant">咨询小助手</span></div>
<div class="msg-info__preview">患者李明的体检报告已同步,请查收</div>
</div>
</div>
<div class="msg-item" onclick="selectMsg(this,3)">
<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">13:50</span></div>
<div class="msg-info__mid"><span class="role-tag role-tag--expert">咨询专家</span></div>
<div class="msg-info__preview">建议患者到院后优先做心电图检查</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">昨天</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--onsite" id="chatRole">驻场人员</span>
<span class="chat-header__detail" id="chatDetail">采油二厂 · 应急保障组</span>
</div>
<div class="chat-body" id="chatBody">
<div class="system-msg">应急事件 #2026041001 · 2026-04-10 14:00</div>
<div class="bubble">
<div class="bubble__avatar other"></div>
<div class="bubble__content">
<div class="bubble__name">赵刚</div>
<div class="bubble__text">报告,采油二厂有一名员工突发胸痛,已拨打120,请协调资源</div>
<div class="bubble__time">14:02</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">14:05</div>
</div>
</div>
<div class="bubble">
<div class="bubble__avatar other"></div>
<div class="bubble__content">
<div class="bubble__name">赵刚</div>
<div class="bubble__text">患者男性,45岁,胸痛持续约10分钟,意识清醒,面色苍白,已让他平卧休息</div>
<div class="bubble__time">14:10</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">已通知专业人员林护士和长庆总医院急诊科,120车组预计15分钟到达,请保持现场观察并随时汇报</div>
<div class="bubble__time">14:15</div>
</div>
</div>
<div class="bubble">
<div class="bubble__avatar other"></div>
<div class="bubble__content">
<div class="bubble__name">赵刚</div>
<div class="bubble__text">采油二厂现场已到位,患者意识清醒,120车组刚到,正在上车</div>
<div class="bubble__time">14:35</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 = '';
}
/* 刷新消息列表 */
function refreshMsgList(btn) {
btn.classList.add('spinning');
setTimeout(function(){ btn.classList.remove('spinning'); }, 500);
}
/* 消息列表数据 */
var msgData = [
{name:'赵刚',role:'驻场人员',roleClass:'onsite',char:'赵',detail:'采油二厂 · 应急保障组'},
{name:'林护士',role:'专业人员',roleClass:'professional',char:'林',detail:'主管护师 · 急救专业组'},
{name:'健康小助手',role:'咨询小助手',roleClass:'assistant',char:'助',detail:'健康管理平台'},
{name:'陈医生',role:'咨询专家',roleClass:'expert',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 = {'驻场人员':'onsite','专业人员':'professional','操作人员':'operator','咨询小助手':'assistant','咨询专家':'expert','健康管理员':'admin'};
var rc = roleClassMap[c.role] || 'operator';
var normalizedName = (c.name || '').trim();
var ch = normalizedName.charAt(0);
var existsInData = msgData.some(function(item){
return item.name === normalizedName;
});
var existsInDom = false;
document.querySelectorAll('.msg-item .msg-info__name').forEach(function(n){
if ((n.textContent || '').trim() === normalizedName) existsInDom = true;
});
if (existsInData || existsInDom) { closeOverlay(); return; }
var idx = msgData.length;
msgData.push({name:normalizedName, 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>
@@ -2,7 +2,7 @@
> **所属端**:Web 管理端(操作人员视角)
> **模块路径**`web-admin/emergency-dispatch/operator/`
> **最后更新**2026-04-28
> **最后更新**2026-04-29
---
@@ -10,7 +10,7 @@
操作人员端用于承接员工端发起的应急求助,负责实时沟通、资源调度、驻场派单、救护车支援、救助过程留痕与工单闭环,并与专业人员(提供医学救助意见)和管理端(工单台账 / 排班 / 统计)协同完成处置。
该目录下共 5 个页面:其中 1 个为操作人员核心处置页面(`emergency-active.html`),4 个为角色路由页(自动跳转至管理端通用页面并携带 `role=operator` 参数)。
该目录下共 6 个页面:其中 1 个为操作人员核心处置页面(`emergency-active.html`),4 个为角色路由页(自动跳转至管理端通用页面并携带 `role=operator` 参数),1 个为新增应急工单功能页面(复用管理端页面能力进行说明)
---
@@ -25,6 +25,7 @@
│ ├── 救助信息(补充小结 + 救助结果)
│ └── 结束应急(确认弹窗 → 已结束结果态)
├── 应急工单(路由页)→ 管理端应急工单页(operator 权限视图)
│ └── 新增应急工单(手动新增 / 通话记录转工单)
├── 通话记录(路由页)→ 管理端通话记录页(operator 权限视图)
├── 大病就医(路由页)→ 管理端大病就医页(operator 权限视图)
└── 值班小组(路由页)→ 管理端排班配置页(operator 权限视图)
@@ -59,6 +60,7 @@ stateDiagram-v2
| 1-6 | 正在应急 | 救助信息 | emergency-active.html | 弹窗 |
| 1-7 | 正在应急 | 结束应急确认 | emergency-active.html | 弹窗 |
| 2 | 应急工单 | 应急工单(路由页) | work-order.html | 路由页 |
| 2-1 | 应急工单 | 新增应急工单 | center-work-order-add.html | 功能页 |
| 3 | 通话记录 | 通话记录(路由页) | call-record.html | 路由页 |
| 4 | 大病就医 | 大病就医(路由页) | serious-illness.html | 路由页 |
| 5 | 值班小组 | 值班小组(路由页) | duty-group.html | 路由页 |
@@ -131,6 +133,7 @@ stateDiagram-v2
- 患者位置信息来源于员工端求助时上报的 GPS 坐标,实时展示。
- 各类资源按距离由近到远排序展示。
- 联系电话支持点击直接拨号。
- 支持点到点之间的路径规划。
**交互说明:**
- 点击右侧资源卡片,地图上对应标记点高亮;点击地图标记点,右侧对应资源卡片高亮并滚动至可见区域。
@@ -310,6 +313,76 @@ stateDiagram-v2
**交互说明:**
- 页面加载即自动跳转,无需用户操作。
- 点击"新增应急工单"进入新增应急工单功能页。
---
### 2-1. 新增应急工单(center-work-order-add.html
![页面截图](../admin/doc/screenshots/center-work-order-add.jpg)
**功能说明:**
操作人员新建应急工单的录入页面,用于补录线下应急事件,或将通话记录快速转换为应急工单。页面按"基本信息"、"派单信息"、"救护车支援"三段式组织表单内容,支持在录入工单基础信息的同时补充驻场与转运安排。
**入口说明:**
- 手动新增入口:从应急工单列表点击"新增应急工单"进入,页面显示工单类型为"线下应急工单",求助方式默认为"线下应急"。
- 通话转工单入口:从通话记录列表点击"新建应急工单"进入,页面显示工单类型为"应急电话工单",并自动回填员工姓名、员工编号、单位、部门等信息,求助方式默认为"应急电话"。
**页面结构:**
- 顶部只读信息区:展示工单类型、所属应急中心。
- 基本信息:录入求助员工、求助方式、求助时间、操作人员、专业人员、完成时间、救助意见、救助结果、相关照片、补充小结。
- 派单信息:录入派单时间、派单说明、驻场人员、结束时间、驻场说明。
- 救护车支援:选择救护车并补充随行人、联系电话、目的地、备注信息,驾驶人相关信息自动展示。
- 页面底部:"确定"提交按钮。
**表单字段表:**
| 字段名 | 所属区域 | 类型 | 必填 | 规则 |
|--------|----------|------|------|------|
| 工单类型 | 顶部只读信息区 | 只读文本 | — | 根据入口自动显示为"线下应急工单"或"应急电话工单" |
| 应急中心 | 顶部只读信息区 | 只读文本 | — | 显示当前操作人员所属应急中心 |
| 求助员工 | 基本信息 | 搜索选择 / 只读回填 | 是 | 手动新增时支持按姓名/编号搜索;通话转工单时自动回填并禁用编辑 |
| 员工信息卡片 | 基本信息 | 展示区域 | — | 选择员工后展示姓名、编号、单位、部门 |
| 求助方式 | 基本信息 | 只读文本 | 是 | 根据入口自动回填,手动新增为"线下应急",通话转工单为"应急电话" |
| 求助时间 | 基本信息 | 日期 + 时间 | 是 | 分开选择日期与时间 |
| 操作人员 | 基本信息 | 下拉选择 | 是 | 从操作人员列表中选择 |
| 专业人员 | 基本信息 | 下拉选择 | 否 | 从专业人员列表中选择 |
| 完成时间 | 基本信息 | 日期 + 时间 | 否 | 用于补录已完成工单 |
| 救助意见 | 基本信息 | 多行文本 | 否 | 记录专业指导或现场判断 |
| 救助结果 | 基本信息 | 多行文本 | 否 | 记录本次处置结果 |
| 相关照片 | 基本信息 | 图片上传 | 否 | 最多 6 张,展示已上传数量 |
| 补充小结 | 基本信息 | 动态文本列表 | 否 | 支持新增、删除多条小结 |
| 派单时间 | 派单信息 | 日期 + 时间 | 否 | 记录向驻场人员派单时间 |
| 派单说明 | 派单信息 | 多行文本 | 否 | 填写派单要求与备注 |
| 驻场人员 | 派单信息 | 下拉选择 | 否 | 从驻场人员列表中选择 |
| 结束时间 | 派单信息 | 日期 + 时间 | 否 | 记录驻场任务结束时间 |
| 驻场说明 | 派单信息 | 多行文本 | 否 | 记录驻场处理补充说明 |
| 选择救护车 | 救护车支援 | 搜索选择 | 否 | 支持按车牌号/医疗点/机构搜索 |
| 所属医疗点 | 救护车支援 | 只读展示 | — | 选择救护车后自动带出 |
| 所属机构 | 救护车支援 | 只读展示 | — | 选择救护车后自动带出 |
| 驾驶人 | 救护车支援 | 只读展示 | — | 选择救护车后自动带出 |
| 驾驶人电话 | 救护车支援 | 只读展示 | — | 选择救护车后自动带出,支持点击拨号 |
| 随行人 | 救护车支援 | 文本输入 | 否 | 手工填写 |
| 随行人电话 | 救护车支援 | 文本输入 | 否 | 手工填写 |
| 目的地 | 救护车支援 | 文本输入 | 否 | 填写转运目标地点 |
| 备注信息 | 救护车支援 | 多行文本 | 否 | 补充说明转运安排 |
**业务规则:**
- 新增应急工单仅操作人员可创建,管理员视角不展示该入口。
- 页面根据入口自动切换工单类型与求助方式,不允许手动修改。
- 通话转工单场景下,员工信息由来源通话记录自动回填,避免重复录入。
- 相关照片最多上传 6 张;达到上限后上传入口禁用。
- 补充小结支持维护多条,至少保留 1 个输入项用于录入。
- 选择救护车后,所属医疗点、所属机构、驾驶人、驾驶人电话自动联动展示。
- 表单提交后生成新的应急工单记录,并返回应急工单列表。
**交互说明:**
- 手动新增时,点击求助员工输入框打开搜索下拉,支持按姓名或员工编号筛选。
- 选择员工后,页面展示员工信息卡片。
- 点击"+ 新增小结"可追加补充小结输入项,点击删除按钮可移除对应小结。
- 点击救护车选择框后打开搜索下拉,选中车辆后展示驾驶人信息卡片。
- 从通话记录进入时,员工信息自动回填且不可编辑。
- 点击"确定"提交新增应急工单,成功后返回工单列表。
---
@@ -329,6 +402,8 @@ stateDiagram-v2
**交互说明:**
- 页面加载即自动跳转,无需用户操作。
- 点击‘新建应急工单’跳转至新增应急工单流程。
- 点击‘查看应急工单’跳转至应急工单详情页。
---
@@ -350,6 +425,45 @@ stateDiagram-v2
---
### 4_1. 新增大病就医(center-serious-illness-add.html
![页面截图](screenshots/center-serious-illness-add.jpg)
**功能说明:** 新建大病就医预约单,页面分为"员工就医诉求"和"就医派单"两部分,支持操作人员在录入员工诉求后直接完成驻场派单。
**页面结构:**
- 员工就医诉求:录入员工来源、就医人信息、预约医院、挂号类别、期望预约时间、预约科室、预约医生、病情描述等内容
- 就医派单:选择驻场人员并填写派单说明,提交后直接生成预约并完成派单
**表单字段表:**
| 字段名 | 所属区域 | 类型 | 必填 | 规则 |
|--------|----------|------|------|------|
| 员工类型 | 员工就医诉求 | 单选 | 是 | 油田员工/非油田员工,切换后联动下方字段 |
| 就医员工 | 员工就医诉求 | 搜索选择 | 是 | 油田员工时显示,从员工列表搜索选择 |
| 姓名 | 员工就医诉求 | 文本输入 | 是 | 非油田员工时显示 |
| 身份证号 | 员工就医诉求 | 文本输入 | 是 | 非油田员工时显示,身份证格式校验 |
| 手机号 | 员工就医诉求 | 文本输入 | 是 | 非油田员工时显示,手机号格式校验 |
| 身份信息 | 员工就医诉求 | 文本输入 | 否 | 非油田员工时可手工填写,如员工家属、外协人员 |
| 员工信息卡片 | 员工就医诉求 | 展示区域 | — | 选择油田员工后自动回填单位、部门、联系电话、身份证号 |
| 预约医院 | 员工就医诉求 | 搜索下拉 | 是 | 从医院列表中选择 |
| 就诊卡号 | 员工就医诉求 | 文本输入 | 否 | — |
| 挂号类别 | 员工就医诉求 | 单选 | 是 | 专家号/急诊号/普通号 |
| 期望预约时间 | 员工就医诉求 | 日期时间 | 是 | — |
| 预约科室 | 员工就医诉求 | 文本输入 | 否 | 手工录入 |
| 预约医生 | 员工就医诉求 | 文本输入 | 否 | 手工录入 |
| 病情描述 | 员工就医诉求 | 多行文本 | 否 | — |
| 驻场人员 | 就医派单 | 搜索选择 | 是 | 按姓名/医院搜索,选择后展示联系电话 |
| 派单说明 | 就医派单 | 多行文本 | 否 | 记录本次派单备注 |
**交互说明:**
- 切换"员工类型"联动显示不同的员工信息录入方式
- 选择油田员工后自动回填员工信息卡片
- 驻场人员支持搜索选择,选中后展示联系电话
- 点击"确定并派单"后创建大病就医申请并直接返回大病就医列表,该条大病就医记录为‘已确认’状态
---
### 5. 值班小组(duty-group.html
![页面截图](screenshots/duty-group.jpg)
Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

@@ -273,6 +273,7 @@
</div>
<nav class="top-bar__nav">
<a href="emergency-active.html" class="active">正在应急</a>
<a href="chat-message.html">对话消息</a>
<a href="work-order.html">应急工单</a>
<a href="call-record.html">通话记录</a>
<a href="serious-illness.html">大病就医</a>
@@ -0,0 +1,326 @@
<!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(--primary);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-refresh{width:36px;height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;color:var(--text-secondary);flex-shrink:0;transition:all .2s;}
.btn-refresh:hover{color:var(--primary);border-color:var(--primary);}
.btn-refresh svg{width:16px;height:16px;transition:transform .4s ease;}
.btn-refresh.spinning svg{transform:rotate(360deg);}
.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--operator{background:var(--primary-light);color:var(--primary);}
.msg-avatar--onsite{background:#F9F0FF;color:#722ED1;}
.msg-avatar--professional{background:#FFF7E6;color:var(--warning);}
.msg-avatar--assistant{background:#F6FFED;color:var(--success);}
.msg-avatar--expert{background:#F6FFED;color:var(--success);}
.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--operator{background:var(--primary-light);color:var(--primary);}
.role-tag--onsite{background:#F9F0FF;color:#722ED1;}
.role-tag--professional{background:#FFF7E6;color:var(--warning);}
.role-tag--assistant{background:#F6FFED;color:var(--success);}
.role-tag--expert{background:#F6FFED;color:var(--success);}
.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;}
.bubble__avatar.other{background:var(--primary-light);color:var(--primary);}
.bubble__avatar.me{background:#FFF7E6;color:var(--warning);}
.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(--warning);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;}
.btn-contacts{width:36px;height:36px;border-radius:var(--radius-sm);cursor:pointer;border:1px solid var(--primary);background:#fff;color:var(--primary);display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;transition:all .2s;}
.btn-contacts:hover{background:var(--primary);color:#fff;}
.btn-contacts svg{width:16px;height:16px;}
/* 弹窗 */
.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="#1890FF"/><path d="M14 6v7l5 3" stroke="#fff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><circle cx="14" cy="14" r="8" stroke="#fff" stroke-width="2" fill="none"/></svg>
应急就医–专业人员
</div>
<nav class="top-bar__nav">
<a href="professional.html">正在应急</a>
<a href="chat-message.html" class="active">对话消息</a>
<a href="../admin/center-work-order.html?role=professional">应急工单</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" title="通讯录" onclick="openOverlay('../../health-consult/assistant/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>
<button class="btn-refresh" title="刷新" onclick="refreshMsgList(this)">
<svg viewBox="0 0 16 16" fill="none"><path d="M13.5 8a5.5 5.5 0 1 1-1.3-3.6" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/><path d="M13.5 2.5v3h-3" stroke="currentColor" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="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--operator"></div>
<div class="msg-info">
<div class="msg-info__top"><span class="msg-info__name">周丽</span><span class="msg-info__time">15:50</span></div>
<div class="msg-info__mid"><span class="role-tag role-tag--operator">操作人员</span></div>
<div class="msg-info__preview">患者已上车,预计20分钟到院</div>
</div>
<div class="msg-badge">1</div>
</div>
<div class="msg-item" onclick="selectMsg(this,1)">
<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">15:30</span></div>
<div class="msg-info__mid"><span class="role-tag role-tag--onsite">驻场人员</span></div>
<div class="msg-info__preview">现场急救包已使用,患者体征稳定</div>
</div>
</div>
<div class="msg-item" onclick="selectMsg(this,2)">
<div class="msg-avatar msg-avatar--assistant"></div>
<div class="msg-info">
<div class="msg-info__top"><span class="msg-info__name">健康小助手</span><span class="msg-info__time">15:00</span></div>
<div class="msg-info__mid"><span class="role-tag role-tag--assistant">咨询小助手</span></div>
<div class="msg-info__preview">患者王强的既往病史已同步,请查收</div>
</div>
</div>
<div class="msg-item" onclick="selectMsg(this,3)">
<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">14:40</span></div>
<div class="msg-info__mid"><span class="role-tag role-tag--expert">咨询专家</span></div>
<div class="msg-info__preview">心电图结果建议做冠脉造影进一步确认</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">昨天</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--operator" id="chatRole">操作人员</span>
<span class="chat-header__detail" id="chatDetail">应急救援中心 · 调度组</span>
</div>
<div class="chat-body" id="chatBody">
<div class="system-msg">应急事件 #2026041002 · 2026-04-10 15:30</div>
<div class="bubble">
<div class="bubble__avatar other"></div>
<div class="bubble__content">
<div class="bubble__name">周丽</div>
<div class="bubble__text">林护士,有一位员工突发胸痛,120已派车,请准备接诊评估</div>
<div class="bubble__time">15:32</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">15:35</div>
</div>
</div>
<div class="bubble">
<div class="bubble__avatar other"></div>
<div class="bubble__content">
<div class="bubble__name">周丽</div>
<div class="bubble__text">患者王强,男,52岁,胸痛伴出汗,血压150/95,心率98次/分</div>
<div class="bubble__time">15:38</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">建议立即含服硝酸甘油,保持平卧位。到院后优先做12导联心电图和心肌酶谱检查,我已通知急诊科准备</div>
<div class="bubble__time">15:42</div>
</div>
</div>
<div class="bubble">
<div class="bubble__avatar other"></div>
<div class="bubble__content">
<div class="bubble__name">周丽</div>
<div class="bubble__text">患者已上车,预计20分钟到院,驻场人员反馈体征暂时稳定</div>
<div class="bubble__time">15:50</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 = '';
}
/* 刷新消息列表 */
function refreshMsgList(btn) {
btn.classList.add('spinning');
setTimeout(function(){ btn.classList.remove('spinning'); }, 500);
}
/* 消息列表数据 */
var msgData = [
{name:'周丽',role:'操作人员',roleClass:'operator',char:'周',detail:'应急救援中心 · 调度组'},
{name:'赵刚',role:'驻场人员',roleClass:'onsite',char:'赵',detail:'采油二厂 · 应急保障组'},
{name:'健康小助手',role:'咨询小助手',roleClass:'assistant',char:'助',detail:'健康管理平台'},
{name:'陈医生',role:'咨询专家',roleClass:'expert',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 = {'驻场人员':'onsite','专业人员':'professional','操作人员':'operator','咨询小助手':'assistant','咨询专家':'expert','健康管理员':'admin'};
var rc = roleClassMap[c.role] || 'operator';
var normalizedName = (c.name || '').trim();
var ch = normalizedName.charAt(0);
var existsInData = msgData.some(function(item){
return item.name === normalizedName;
});
var existsInDom = false;
document.querySelectorAll('.msg-item .msg-info__name').forEach(function(n){
if ((n.textContent || '').trim() === normalizedName) existsInDom = true;
});
if (existsInData || existsInDom) { closeOverlay(); return; }
var idx = msgData.length;
msgData.push({name:normalizedName, 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>
@@ -72,7 +72,7 @@ sequenceDiagram
![页面截图](screenshots/professional.jpg)
**功能说明:**
- 专业人员核心工作台,采用”左侧联系人列表320px+ 中间对话区 + 右侧值班面板320px)”三栏布局。
- 专业人员核心工作台,采用”左侧联系人列表+ 中间对话区 + 右侧值班面板)”三栏布局。
- 支持与求助员工实时文字沟通、查看员工定位与周边医疗资源、输出专业救助意见、结束应急处置。
- 专业人员不承担驻场派单与救护车调度职责,核心操作为”救助意见”与”结束应急”。
@@ -235,6 +235,7 @@
</div>
<nav class="top-bar__nav">
<a href="professional.html" class="active">正在应急</a>
<a href="chat-message.html">对话消息</a>
<a href="../admin/center-work-order.html?role=professional">应急工单</a>
</nav>
<div class="top-bar__right">