fix:完善PRD文档
This commit is contained in:
@@ -2,16 +2,16 @@
|
||||
|
||||
## 模块概述
|
||||
|
||||
小助手角色是后台管理系统中面向健康咨询小助手的工作台,用于实时处理员工咨询、管理历史记录、内部即时通讯、专家管理与排班、体检标准查阅、通知短信发送、常用语管理及专家结算。
|
||||
后台管理系统中面向健康咨询小助手的工作台,用于实时处理员工咨询、管理历史记录、内部即时通讯、专家管理与排班、体检标准查阅、通知短信发送、常用语管理及专家结算。
|
||||
|
||||
### 页面导航结构
|
||||
|
||||
```
|
||||
小助手工作台
|
||||
├── 当前咨询(IM对话)
|
||||
├── 当前咨询
|
||||
│ ├── 咨询人档案弹窗
|
||||
│ └── 选择专家弹窗
|
||||
├── 对话消息(内部IM)
|
||||
├── 对话消息
|
||||
│ └── 通讯录弹窗
|
||||
├── 咨询记录(列表)
|
||||
│ └── 对话详情弹窗
|
||||
@@ -136,7 +136,7 @@ stateDiagram-v2
|
||||
- 操作按钮:「咨询人档案」「结束咨询」(红色)
|
||||
|
||||
**消息类型:**
|
||||
- 系统消息(居中灰色标签)
|
||||
- 专家消息(左侧白色气泡)
|
||||
- 员工消息(左侧白色气泡)
|
||||
- 小助手消息(右侧绿色气泡)
|
||||
- 咨询信息卡片:咨询人头像、基本信息、咨询标题、描述、持续时间、附件图片
|
||||
@@ -152,13 +152,14 @@ stateDiagram-v2
|
||||
- 对话列表按最新消息时间倒序排列
|
||||
- 未读消息显示红色角标
|
||||
- 仅咨询状态为"咨询中"的对话出现在此列表
|
||||
- 已结束(已完成、已超时)的咨询不在此列表中显示
|
||||
|
||||
**交互说明:**
|
||||
- 点击左侧对话项 → 右侧切换为该员工的聊天内容
|
||||
- 点击「咨询人档案」→ 打开咨询人档案弹窗(680×720)
|
||||
- 点击「咨询人档案」→ 打开当前咨询人档案弹窗(680×720)
|
||||
- 点击「发送专家」→ 打开选择专家弹窗(720×600)
|
||||
- 选中专家确认后 → 专家卡片以消息形式发送到对话中
|
||||
- 点击「结束咨询」→ 结束当前咨询会话
|
||||
- 点击「结束咨询」→ 结束本次咨询会话
|
||||
|
||||
---
|
||||
|
||||
@@ -166,18 +167,19 @@ stateDiagram-v2
|
||||
|
||||

|
||||
|
||||
**功能说明:** 展示当前咨询员工的个人信息和健康档案,帮助小助手了解员工背景。以 iframe 弹窗形式打开。
|
||||
**功能说明:** 当咨询会话类型是员工咨询专家时,需要展示当前咨询员工的个人信息和健康档案,帮助小助手了解员工背景。以 iframe 弹窗形式打开,主体信息分为员工信息/咨询人信息/咨询人档案三部分。
|
||||
|
||||
**员工信息(两列网格):** 姓名、员工编号、性别、年龄、单位、部门
|
||||
|
||||
**咨询人信息区(Tab 切换):** 支持多个咨询人(本人/配偶/子女等),默认隐藏 Tab 栏(仅一个咨询人时)
|
||||
**当前咨询人信息区:**
|
||||
- 基本信息:咨询人姓名、性别、出生日期、与本人关系
|
||||
- 生活习惯:是否抽烟、是否饮酒、饮食喜好、睡眠质量
|
||||
- 健康档案:既往病史(标签)、过敏史(标签)、家族病史(标签)、体检报告(缩略图卡片)、检查报告(缩略图卡片)
|
||||
- 身体情况:身高、体重、过敏史...
|
||||
|
||||
**本次咨询档案:** 档案名称、问题描述、持续时间、检查资料、是否前往就医(是则显示医院、科室、疾病)、期望帮助
|
||||
|
||||
**业务规则:**
|
||||
- 健康指标来源于最近一次体检数据
|
||||
- 指标按正常/偏高/偏低三色标识
|
||||
- 当咨询会话类型是员工咨询专家时才有健康档案按钮,若员工未完善档案信息(咨询人信息、咨询档案)则仅显示员工信息
|
||||
|
||||
---
|
||||
|
||||
@@ -194,7 +196,7 @@ stateDiagram-v2
|
||||
**交互说明:**
|
||||
- 单选模式,点击专家行选中高亮
|
||||
- 底部显示已选专家信息
|
||||
- 点击「确认选择」→ 将专家卡片发送到对话框,关闭弹窗
|
||||
- 点击「确认选择」→ 将专家卡片发送到对话框,自动关闭弹窗
|
||||
|
||||
---
|
||||
|
||||
@@ -204,7 +206,7 @@ stateDiagram-v2
|
||||
|
||||

|
||||
|
||||
**功能说明:** IM 风格左右分栏布局,用于小助手与内部人员(咨询专家、操作人员、专业人员、驻场人员、健康管理员)之间的即时通讯。
|
||||
**功能说明:** IM 风格左右分栏布局,用于小助手与内部人员(咨询专家、操作人员、专业人员、驻场人员、健康管理员)之间的点对点即时通讯。
|
||||
|
||||
**左侧 — 消息列表区:**
|
||||
- 搜索框:按联系人姓名搜索
|
||||
@@ -257,7 +259,7 @@ stateDiagram-v2
|
||||
| 健康管理员 | 单位、部门 |
|
||||
|
||||
**业务规则:**
|
||||
- 单次只能选择一位联系人
|
||||
- 单次只能选择一位联系人,暂不支持手动创建群聊模式
|
||||
- 已存在于消息列表中的联系人不会重复添加
|
||||
|
||||
**交互说明:**
|
||||
@@ -273,7 +275,7 @@ stateDiagram-v2
|
||||
|
||||

|
||||
|
||||
**功能说明:** 查看所有咨询记录,分为「咨询专家」和「咨询小助手」两个 Tab。
|
||||
**功能说明:** 小助手视角查看所有咨询记录,分为「咨询专家」和「咨询小助手」两个 Tab。
|
||||
|
||||
**Tab — 咨询专家:**
|
||||
|
||||
@@ -300,13 +302,13 @@ stateDiagram-v2
|
||||
表格列:序号、咨询单号、姓名、员工编号、所属单位、所属部门、咨询小助手、咨询状态、发起咨询时间、首次回复时间、咨询完成时间、咨询时长、操作
|
||||
|
||||
**业务规则:**
|
||||
- 咨询状态随咨询类型联动:图文咨询状态为"待回复/进行中/已完成";视频咨询状态为"待确认/待开始/已完成/已取消/已拒绝"
|
||||
- 咨询专家列表中咨询状态随咨询类型联动:图文咨询状态为"待回复/进行中/已完成";视频咨询状态为"待确认/待开始/已完成/已取消/已拒绝"
|
||||
- 序号、咨询单号、姓名固定在表格左侧,操作列固定在右侧
|
||||
|
||||
**交互说明:**
|
||||
- 点击「更多条件」展开/收起高级筛选区
|
||||
- 点击「查看对话」→ 打开对话详情弹窗(720×680)
|
||||
- 支持导出列表数据、查看导出任务
|
||||
- 支持异步导出列表数据、查看导出任务
|
||||
|
||||
---
|
||||
|
||||
@@ -319,7 +321,7 @@ stateDiagram-v2
|
||||
**咨询信息摘要(三列网格):** 咨询单号、员工姓名(含工号)、所属单位、发起时间、咨询时长、咨询状态(标签)
|
||||
|
||||
**对话内容:**
|
||||
- 系统消息(居中灰色标签)
|
||||
- 专家消息(左侧灰色气泡)
|
||||
- 员工消息(左侧灰色气泡)
|
||||
- 小助手消息(右侧蓝色浅底气泡)
|
||||
- 转接专家通知(黄色背景卡片,显示转接目标专家信息)
|
||||
@@ -367,28 +369,28 @@ stateDiagram-v2
|
||||
|
||||
**表单字段 — 基本信息:**
|
||||
|
||||
| 字段名 | 类型 | 必填 | 规则 |
|
||||
|--------|------|------|------|
|
||||
| 头像 | 图片上传 | 否 | 支持 jpg/png |
|
||||
| 账号 | 文本输入 | 是 | — |
|
||||
| 字段名 | 类型 | 必填 | 规则 |
|
||||
|--------|------|------|--------------------------|
|
||||
| 头像 | 图片上传 | 否 | 支持 jpg/png |
|
||||
| 账号 | 文本输入 | 是 | — |
|
||||
| 密码 | 密码输入 | 是 | 不少于12位,必须包含大小写字母、数字、特殊符号 |
|
||||
| 姓名 | 文本输入 | 是 | — |
|
||||
| 性别 | 单选 | 是 | 男/女 |
|
||||
| 身份证号 | 文本输入 | 否 | 18位 |
|
||||
| 手机号 | 文本输入 | 否 | 11位手机号 |
|
||||
| 医院 | 下拉选择 | 是 | 预设医院列表 |
|
||||
| 科室 | 下拉选择 | 是 | 心脏内科/内分泌科/神经内科/骨科/消化内科/呼吸内科 |
|
||||
| 职称 | 下拉选择 | 是 | 主任医师/副主任医师/主治医师/住院医师 |
|
||||
| 职务 | 下拉选择 | 否 | 科室主任/副主任/无 |
|
||||
| 专家类型 | 单选 | 是 | 收费专家/免费专家/其他专家 |
|
||||
| 专家状态 | 单选 | 是 | 有效/无效 |
|
||||
| 专家编号 | 文本输入 | 否 | — |
|
||||
| 擅长疾病 | 文本输入 | 否 | 逗号分隔 |
|
||||
| 注册日期 | 日期选择 | 否 | — |
|
||||
| 出库日期 | 日期选择 | 否 | — |
|
||||
| 是否推荐 | 单选 | 否 | 是/否,默认否 |
|
||||
| 排序 | 数字输入 | 否 | — |
|
||||
| 邮箱 | 文本输入 | 否 | — |
|
||||
| 姓名 | 文本输入 | 是 | — |
|
||||
| 性别 | 单选 | 是 | 男/女 |
|
||||
| 身份证号 | 文本输入 | 否 | 18位 |
|
||||
| 手机号 | 文本输入 | 否 | 11位手机号 |
|
||||
| 医院 | 下拉选择 | 是 | 预设医院列表 |
|
||||
| 科室 | 下拉选择 | 是 | 医院下的科室列表,选医院后联动 |
|
||||
| 职称 | 下拉选择 | 是 | 主任医师/副主任医师/主治医师/住院医师 |
|
||||
| 职务 | 下拉选择 | 否 | 科室主任/副主任/无 |
|
||||
| 专家类型 | 单选 | 是 | 收费专家/免费专家/其他专家 |
|
||||
| 专家状态 | 单选 | 是 | 有效/无效 |
|
||||
| 专家编号 | 文本输入 | 否 | — |
|
||||
| 擅长疾病 | 文本输入 | 否 | 选医院和科室后联动显示科室下疾病 |
|
||||
| 注册日期 | 日期选择 | 否 | — |
|
||||
| 出库日期 | 日期选择 | 否 | — |
|
||||
| 是否推荐 | 单选 | 否 | 是/否,默认否 |
|
||||
| 排序 | 数字输入 | 否 | — |
|
||||
| 邮箱 | 文本输入 | 否 | — |
|
||||
|
||||
**表单字段 — 扩展信息:**
|
||||
|
||||
@@ -409,7 +411,7 @@ stateDiagram-v2
|
||||
- 编辑模式回填已有数据,可修改
|
||||
|
||||
**交互说明:**
|
||||
- 底部按钮:取消(返回专家管理列表)、保存
|
||||
- 底部按钮:取消(返回专家管理列表)、保存返回并刷新专家列表
|
||||
|
||||
---
|
||||
|
||||
@@ -417,7 +419,7 @@ stateDiagram-v2
|
||||
|
||||

|
||||
|
||||
**功能说明:** 配置某位专家的每周排班和视频咨询开关。以 iframe 弹窗形式嵌入。
|
||||
**功能说明:** 配置某位专家排班和视频咨询开关。以 iframe 弹窗形式嵌入。
|
||||
|
||||
**专家信息卡片(只读):** 头像(姓氏首字)、姓名、职称标签、专家编号、医院、科室、收费类型
|
||||
|
||||
@@ -434,7 +436,8 @@ stateDiagram-v2
|
||||
- 接诊人数数字输入框(52px 宽,休诊时禁用)
|
||||
|
||||
**业务规则:**
|
||||
- 工作日(周一至周五)默认开诊,上午每时段 5 人,下午每时段 4 人
|
||||
- 排班设置根据自然周循环重复使用。默认自动跳过法定节假日
|
||||
- 工作日(周一至周五)默认开诊,上午每时段 n 人,下午每时段 n 人
|
||||
- 周末(周六、周日)默认休诊,人数为 0
|
||||
- 休诊时人数输入框禁用(灰色背景),开诊时可编辑
|
||||
- 从休诊切换为开诊时,若人数为 0 则自动填充为 5
|
||||
@@ -490,7 +493,7 @@ stateDiagram-v2
|
||||
|
||||

|
||||
|
||||
**功能说明:** 左侧体检分类树 + 右侧项目列表,供小助手查阅体检项目明细以回答员工相关问题。
|
||||
**功能说明:** 节选自健康体检业务中的体检标准化项目查询业务,左侧体检分类树 + 右侧项目列表,供小助手查阅体检项目明细以回答员工相关问题。
|
||||
|
||||
**左侧 — 分类树:**
|
||||
- 搜索框:搜索大类/小类名称
|
||||
@@ -514,28 +517,13 @@ stateDiagram-v2
|
||||
|
||||
---
|
||||
|
||||
### 15. 体检项目明细弹窗(item-detail-dialog.html)
|
||||
|
||||

|
||||
|
||||
**功能说明:** 展示单个体检项目的详细信息,包括参考范围、临床意义、关联套餐和注意事项。以新窗口弹窗形式打开。
|
||||
|
||||
**展示区域:**
|
||||
- 基本信息:项目名称、项目编码(等宽字体)、所属分类、检测单位
|
||||
- 参考范围:正常范围、偏低(蓝色)、超重(橙色)、肥胖(红色),辅以可视化条形图
|
||||
- 临床意义:文字描述
|
||||
- 关联体检套餐:标签列表(基础套餐 A/标准套餐 B/高端套餐 C/入职体检/年度体检)
|
||||
- 注意事项:编号列表
|
||||
|
||||
---
|
||||
|
||||
## 六、短信发送
|
||||
|
||||
### 16. 短信发送记录列表(sms-send.html)
|
||||
|
||||

|
||||
|
||||
**功能说明:** 展示短信发送历史记录,支持新建短信。
|
||||
**功能说明:** 同系统管理-消息通知-短息管理业务中功能,展示短信发送历史记录,支持新建短信。
|
||||
|
||||
**筛选条件:** 消息标题(文本输入)、发送状态(下拉:请选择/已发布/发送中/发送失败)
|
||||
|
||||
@@ -549,43 +537,6 @@ stateDiagram-v2
|
||||
|
||||
---
|
||||
|
||||
### 17. 新建短信弹窗(send-dialog.html)
|
||||
|
||||

|
||||
|
||||
**功能说明:** 创建并发送通知短信,支持选择发送对象和定时发送。以 iframe 弹窗形式打开。
|
||||
|
||||
**表单字段表:**
|
||||
|
||||
| 字段名 | 类型 | 必填 | 规则 |
|
||||
|--------|------|------|------|
|
||||
| 发送对象 | 选择(4种模式) | 是 | 按单位/按部门/指定人员/全部员工,选择后下方联动对应选择器 |
|
||||
| 短信签名 | 下拉选择 | 是 | 预设签名列表 |
|
||||
| 短信内容 | 多行文本 | 是 | 不超过 70 字,实时字数统计,超 70 字按多条计费提示 |
|
||||
| 定时发送 | 开关 + 日期时间 | 否 | 开启后必填时间,关闭时时间选择器禁用 |
|
||||
|
||||
**交互说明:**
|
||||
- 点击对象类型切换 → 下方选择器联动变化
|
||||
- 点击「确认发送」→ 发送短信,通过 postMessage 关闭弹窗
|
||||
|
||||
---
|
||||
|
||||
### 18. 短信发送详情弹窗(sms-detail-dialog.html)
|
||||
|
||||

|
||||
|
||||
**功能说明:** 展示某批次短信的发送结果,包括基本信息、短信内容预览、发送统计和失败记录。以新窗口弹窗形式打开。
|
||||
|
||||
**基本信息:** 发送批次(等宽字体)、发送状态(标签)、发送对象、发送时间、操作人、短信签名
|
||||
|
||||
**短信内容:** 灰色预览卡片
|
||||
|
||||
**发送统计(4 个统计块):** 发送总数(蓝色)、发送成功(绿色)、发送失败(红色)、成功率
|
||||
|
||||
**失败记录列表:** 姓名(脱敏手机号)+ 失败原因(号码已停机/号码不存在/运营商拦截/发送超时),红色背景行
|
||||
|
||||
---
|
||||
|
||||
## 七、常用语
|
||||
|
||||
### 19. 常用语管理(config-phrase.html)
|
||||
|
||||
@@ -50,11 +50,9 @@
|
||||
tbody td{padding:14px 16px;font-size:var(--font-sm);border-bottom:1px solid var(--border);white-space:nowrap;}
|
||||
.col-fixed{position:sticky;z-index:2;background:#fff;}
|
||||
thead .col-fixed{background:#FAFAFA;z-index:3;}
|
||||
.col-fixed-1{left:0;min-width:60px;width:60px;}
|
||||
.col-fixed-2{left:60px;}
|
||||
.col-fixed-3{left:160px;}
|
||||
.col-fixed-name{left:0;min-width:200px;}
|
||||
.col-fixed-end{right:0;min-width:120px;box-shadow:-2px 0 4px rgba(0,0,0,0.04);}
|
||||
.col-fixed-3::after{content:'';position:absolute;top:0;right:-4px;bottom:0;width:4px;background:linear-gradient(to right,rgba(0,0,0,0.04),transparent);pointer-events:none;}
|
||||
.col-fixed-name::after{content:'';position:absolute;top:0;right:-4px;bottom:0;width:4px;background:linear-gradient(to right,rgba(0,0,0,0.04),transparent);pointer-events:none;}
|
||||
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);}
|
||||
@@ -72,6 +70,14 @@
|
||||
.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);}
|
||||
.expert-count{display:inline-flex;align-items:center;gap:4px;font-size:var(--font-sm);color:var(--primary);font-weight:500;}
|
||||
/* 树状表格 */
|
||||
.tree-toggle{width:20px;height:20px;border:1px solid var(--border);background:#FAFAFA;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;color:var(--text-secondary);border-radius:var(--radius-sm);flex-shrink:0;transition:all .15s;font-size:14px;line-height:1;font-weight:600;font-family:monospace;}
|
||||
.tree-toggle:hover{background:var(--primary-light);color:var(--primary);border-color:var(--primary);}
|
||||
.tree-name{display:inline-flex;align-items:center;gap:6px;}
|
||||
.tree-indent-1{padding-left:26px;}
|
||||
tr.tree-child{transition:all .2s;}
|
||||
tr.tree-hidden{display:none;}
|
||||
.dept-desc{max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-secondary);font-size:var(--font-xs);}
|
||||
/* 抽屉弹窗 */
|
||||
.drawer-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0);z-index:999;transition:background .3s;pointer-events:none;}
|
||||
.drawer-overlay.open{background:rgba(0,0,0,0.45);pointer-events:auto;}
|
||||
@@ -161,15 +167,14 @@
|
||||
<input class="form-input" type="text" placeholder="请输入科室名称">
|
||||
</div>
|
||||
<div class="form-item">
|
||||
<div class="form-label">科室分类</div>
|
||||
<select class="form-select">
|
||||
<option value="">请选择科室分类</option>
|
||||
<option>内科</option>
|
||||
<option>外科</option>
|
||||
<option>妇产科</option>
|
||||
<option>儿科</option>
|
||||
<option>五官科</option>
|
||||
<option>其他</option>
|
||||
<div class="form-label">上级科室</div>
|
||||
<select class="form-select" id="parentDeptSelect">
|
||||
<option value="">无(作为一级科室)</option>
|
||||
<option value="1">内科</option>
|
||||
<option value="2">外科</option>
|
||||
<option value="3">妇产科</option>
|
||||
<option value="4">五官科</option>
|
||||
<option value="5">儿科</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-item">
|
||||
@@ -204,17 +209,6 @@
|
||||
<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>
|
||||
<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>
|
||||
查询
|
||||
@@ -242,9 +236,8 @@
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="col-fixed col-fixed-1">序号</th>
|
||||
<th class="col-fixed col-fixed-2">科室名称</th>
|
||||
<th class="col-fixed col-fixed-3">科室分类</th>
|
||||
<th class="col-fixed col-fixed-name">科室名称</th>
|
||||
<th>科室介绍</th>
|
||||
<th>关联专家数</th>
|
||||
<th>置顶</th>
|
||||
<th>排序</th>
|
||||
@@ -252,78 +245,131 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="col-fixed col-fixed-1">1</td>
|
||||
<td class="col-fixed col-fixed-2" style="font-weight:500;">心血管内科</td>
|
||||
<td class="col-fixed col-fixed-3">内科</td>
|
||||
<td><span class="expert-count">12 位专家</span></td>
|
||||
<td><div class="switch on" onclick="this.classList.toggle('on')" title="点击切换置顶状态"></div></td>
|
||||
<!-- 一级:内科 -->
|
||||
<tr data-id="1" data-level="0">
|
||||
<td class="col-fixed col-fixed-name" style="font-weight:500;"><div class="tree-name"><button class="tree-toggle collapsed" onclick="toggleTree(this)" data-parent="1">+</button>内科</div></td>
|
||||
<td><div class="dept-desc">内科系统各亚专科的综合科室</div></td>
|
||||
<td><span class="expert-count">34 位专家</span></td>
|
||||
<td><div class="switch on" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>1</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-fixed col-fixed-1">2</td>
|
||||
<td class="col-fixed col-fixed-2" style="font-weight:500;">神经内科</td>
|
||||
<td class="col-fixed col-fixed-3">内科</td>
|
||||
<tr data-id="1-1" data-parent-id="1" data-level="1" class="tree-child tree-hidden">
|
||||
<td class="col-fixed col-fixed-name"><div class="tree-name tree-indent-1">心血管内科</div></td>
|
||||
<td><div class="dept-desc">诊治心脏及血管相关疾病</div></td>
|
||||
<td><span class="expert-count">12 位专家</span></td>
|
||||
<td><div class="switch on" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>1</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
<tr data-id="1-2" data-parent-id="1" data-level="1" class="tree-child tree-hidden">
|
||||
<td class="col-fixed col-fixed-name"><div class="tree-name tree-indent-1">神经内科</div></td>
|
||||
<td><div class="dept-desc">诊治脑与神经系统疾病</div></td>
|
||||
<td><span class="expert-count">8 位专家</span></td>
|
||||
<td><div class="switch on" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>2</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-fixed col-fixed-1">3</td>
|
||||
<td class="col-fixed col-fixed-2" style="font-weight:500;">骨科</td>
|
||||
<td class="col-fixed col-fixed-3">外科</td>
|
||||
<td><span class="expert-count">6 位专家</span></td>
|
||||
<td><div class="switch" onclick="this.classList.toggle('on')"></div></td>
|
||||
<tr data-id="1-3" data-parent-id="1" data-level="1" class="tree-child tree-hidden">
|
||||
<td class="col-fixed col-fixed-name"><div class="tree-name tree-indent-1">消化内科</div></td>
|
||||
<td><div class="dept-desc">诊治消化系统相关疾病</div></td>
|
||||
<td><span class="expert-count">9 位专家</span></td>
|
||||
<td><div class="switch on" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>3</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-fixed col-fixed-1">4</td>
|
||||
<td class="col-fixed col-fixed-2" style="font-weight:500;">消化内科</td>
|
||||
<td class="col-fixed col-fixed-3">内科</td>
|
||||
<td><span class="expert-count">9 位专家</span></td>
|
||||
<td><div class="switch on" onclick="this.classList.toggle('on')"></div></td>
|
||||
<tr data-id="1-4" data-parent-id="1" data-level="1" class="tree-child tree-hidden">
|
||||
<td class="col-fixed col-fixed-name"><div class="tree-name tree-indent-1">内分泌科</div></td>
|
||||
<td><div class="dept-desc">诊治内分泌及代谢性疾病</div></td>
|
||||
<td><span class="expert-count">5 位专家</span></td>
|
||||
<td><div class="switch" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>4</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-fixed col-fixed-1">5</td>
|
||||
<td class="col-fixed col-fixed-2" style="font-weight:500;">内分泌科</td>
|
||||
<td class="col-fixed col-fixed-3">内科</td>
|
||||
<!-- 一级:外科 -->
|
||||
<tr data-id="2" data-level="0">
|
||||
<td class="col-fixed col-fixed-name" style="font-weight:500;"><div class="tree-name"><button class="tree-toggle collapsed" onclick="toggleTree(this)" data-parent="2">+</button>外科</div></td>
|
||||
<td><div class="dept-desc">外科系统各亚专科的综合科室</div></td>
|
||||
<td><span class="expert-count">9 位专家</span></td>
|
||||
<td><div class="switch on" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>2</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
<tr data-id="2-1" data-parent-id="2" data-level="1" class="tree-child tree-hidden">
|
||||
<td class="col-fixed col-fixed-name"><div class="tree-name tree-indent-1">骨科</div></td>
|
||||
<td><div class="dept-desc">诊治骨骼、关节及运动系统疾病</div></td>
|
||||
<td><span class="expert-count">6 位专家</span></td>
|
||||
<td><div class="switch" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>1</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
<tr data-id="2-2" data-parent-id="2" data-level="1" class="tree-child tree-hidden">
|
||||
<td class="col-fixed col-fixed-name"><div class="tree-name tree-indent-1">皮肤科</div></td>
|
||||
<td><div class="dept-desc">诊治皮肤及皮下组织疾病</div></td>
|
||||
<td><span class="expert-count">3 位专家</span></td>
|
||||
<td><div class="switch on" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>2</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
<!-- 一级:妇产科 -->
|
||||
<tr data-id="3" data-level="0">
|
||||
<td class="col-fixed col-fixed-name" style="font-weight:500;"><div class="tree-name"><button class="tree-toggle collapsed" onclick="toggleTree(this)" data-parent="3">+</button>妇产科</div></td>
|
||||
<td><div class="dept-desc">妇科与产科综合诊疗科室</div></td>
|
||||
<td><span class="expert-count">7 位专家</span></td>
|
||||
<td><div class="switch on" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>3</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
<tr data-id="3-1" data-parent-id="3" data-level="1" class="tree-child tree-hidden">
|
||||
<td class="col-fixed col-fixed-name"><div class="tree-name tree-indent-1">妇科</div></td>
|
||||
<td><div class="dept-desc">诊治女性生殖系统疾病</div></td>
|
||||
<td><span class="expert-count">4 位专家</span></td>
|
||||
<td><div class="switch on" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>1</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
<tr data-id="3-2" data-parent-id="3" data-level="1" class="tree-child tree-hidden">
|
||||
<td class="col-fixed col-fixed-name"><div class="tree-name tree-indent-1">产科</div></td>
|
||||
<td><div class="dept-desc">孕产期保健及分娩诊疗</div></td>
|
||||
<td><span class="expert-count">3 位专家</span></td>
|
||||
<td><div class="switch" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>2</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
<!-- 一级:五官科 -->
|
||||
<tr data-id="4" data-level="0">
|
||||
<td class="col-fixed col-fixed-name" style="font-weight:500;"><div class="tree-name"><button class="tree-toggle collapsed" onclick="toggleTree(this)" data-parent="4">+</button>五官科</div></td>
|
||||
<td><div class="dept-desc">眼、耳、鼻、喉综合诊疗</div></td>
|
||||
<td><span class="expert-count">7 位专家</span></td>
|
||||
<td><div class="switch" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>4</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
<tr data-id="4-1" data-parent-id="4" data-level="1" class="tree-child tree-hidden">
|
||||
<td class="col-fixed col-fixed-name"><div class="tree-name tree-indent-1">眼科</div></td>
|
||||
<td><div class="dept-desc">诊治眼部及视觉系统疾病</div></td>
|
||||
<td><span class="expert-count">4 位专家</span></td>
|
||||
<td><div class="switch" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>1</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
<tr data-id="4-2" data-parent-id="4" data-level="1" class="tree-child tree-hidden">
|
||||
<td class="col-fixed col-fixed-name"><div class="tree-name tree-indent-1">耳鼻喉科</div></td>
|
||||
<td><div class="dept-desc">诊治耳鼻咽喉相关疾病</div></td>
|
||||
<td><span class="expert-count">3 位专家</span></td>
|
||||
<td><div class="switch on" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>2</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
<!-- 一级:儿科(无子科室,叶子节点) -->
|
||||
<tr data-id="5" data-level="0">
|
||||
<td class="col-fixed col-fixed-name" style="font-weight:500;"><div class="tree-name" style="padding-left:26px;">儿科</div></td>
|
||||
<td><div class="dept-desc">诊治儿童各类常见疾病</div></td>
|
||||
<td><span class="expert-count">5 位专家</span></td>
|
||||
<td><div class="switch" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>5</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-fixed col-fixed-1">6</td>
|
||||
<td class="col-fixed col-fixed-2" style="font-weight:500;">眼科</td>
|
||||
<td class="col-fixed col-fixed-3">五官科</td>
|
||||
<td><span class="expert-count">4 位专家</span></td>
|
||||
<td><div class="switch" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>6</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-fixed col-fixed-1">7</td>
|
||||
<td class="col-fixed col-fixed-2" style="font-weight:500;">妇科</td>
|
||||
<td class="col-fixed col-fixed-3">妇产科</td>
|
||||
<td><span class="expert-count">7 位专家</span></td>
|
||||
<td><div class="switch on" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>7</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="col-fixed col-fixed-1">8</td>
|
||||
<td class="col-fixed col-fixed-2" style="font-weight:500;">皮肤科</td>
|
||||
<td class="col-fixed col-fixed-3">外科</td>
|
||||
<td><span class="expert-count">3 位专家</span></td>
|
||||
<td><div class="switch on" onclick="this.classList.toggle('on')"></div></td>
|
||||
<td>8</td>
|
||||
<td class="col-fixed col-fixed-end"><div style="display:flex;gap:8px;"><span class="link" onclick="openDrawer('edit',this)">编辑</span><span class="link-danger">删除</span></div></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -341,6 +387,18 @@
|
||||
</main>
|
||||
|
||||
<script>
|
||||
/* 树状展开/收起 */
|
||||
function toggleTree(btn){
|
||||
var parentId=btn.getAttribute('data-parent');
|
||||
var collapsed=btn.classList.toggle('collapsed');
|
||||
btn.textContent=collapsed?'+':'−';
|
||||
var children=document.querySelectorAll('tr[data-parent-id="'+parentId+'"]');
|
||||
children.forEach(function(tr){
|
||||
if(collapsed){tr.classList.add('tree-hidden');}
|
||||
else{tr.classList.remove('tree-hidden');}
|
||||
});
|
||||
}
|
||||
|
||||
function openDrawer(mode,triggerEl){
|
||||
const drawer=document.getElementById('dept-drawer');
|
||||
const overlay=document.getElementById('dept-drawer-overlay');
|
||||
@@ -348,23 +406,25 @@ function openDrawer(mode,triggerEl){
|
||||
drawer.classList.add('open');
|
||||
overlay.classList.add('open');
|
||||
var nameInput=drawer.querySelector('.form-input[type="text"]');
|
||||
var catSelect=drawer.querySelector('.form-select');
|
||||
var parentSelect=document.getElementById('parentDeptSelect');
|
||||
var textarea=drawer.querySelector('.form-textarea');
|
||||
var sortInput=drawer.querySelector('.num-input__val');
|
||||
if(mode==='edit'&&triggerEl){
|
||||
title.textContent='编辑科室';
|
||||
var tr=triggerEl.closest('tr');
|
||||
var cells=tr.querySelectorAll('td');
|
||||
nameInput.value=cells[1].textContent.trim();
|
||||
var cat=cells[2].textContent.trim();
|
||||
for(var i=0;i<catSelect.options.length;i++){
|
||||
if(catSelect.options[i].text===cat){catSelect.selectedIndex=i;break;}
|
||||
}
|
||||
sortInput.value=cells[5].textContent.trim();
|
||||
/* 科室名称在第1列的 .tree-name 文本 */
|
||||
var nameEl=cells[0].querySelector('.tree-name');
|
||||
nameInput.value=nameEl?nameEl.textContent.trim():cells[0].textContent.trim();
|
||||
/* 上级科室:根据 data-parent-id 回填 */
|
||||
var pid=tr.getAttribute('data-parent-id')||'';
|
||||
parentSelect.value=pid;
|
||||
/* 排序 */
|
||||
sortInput.value=cells[4].textContent.trim();
|
||||
}else{
|
||||
title.textContent='新增科室';
|
||||
nameInput.value='';
|
||||
catSelect.selectedIndex=0;
|
||||
parentSelect.value='';
|
||||
if(textarea)textarea.value='';
|
||||
sortInput.value='1';
|
||||
}
|
||||
|
||||
@@ -457,34 +457,40 @@
|
||||
|
||||

|
||||
|
||||
**功能说明:** 管理咨询平台的科室字典,支持新增、编辑、删除。
|
||||
**功能说明:** 管理咨询平台的科室字典,科室具有层级关系,以树状列表展示,支持新增、编辑、删除。
|
||||
|
||||
**筛选条件:** 科室名称、科室分类(全部/内科/外科/妇产科/儿科/五官科....)
|
||||
**筛选条件:** 科室名称
|
||||
|
||||
**表格列:** 序号、科室名称、科室分类、关联专家数("X位专家")、置顶(开关)、排序、操作(编辑/删除)
|
||||
**表格列:** 科室名称(树状层级展示,带 +/− 展开收起按钮)、科室介绍(单行截断)、关联专家数("X位专家")、置顶(开关)、排序、操作(编辑/删除)
|
||||
|
||||
**业务规则:**
|
||||
- 科室支持层级嵌套,一级科室(如内科、外科)下可包含二级子科室(如心血管内科、神经内科)
|
||||
- 列表默认收起,仅展示一级科室;点击 `+` 展开子科室,点击 `−` 收起
|
||||
- 无子科室的一级科室不显示展开/收起按钮
|
||||
|
||||
**交互说明:**
|
||||
- 点击"新增科室"打开右侧抽屉表单
|
||||
- 抽屉表单:科室名称、科室分类(下拉)、科室简介(文本域)、置顶(开关)、排序(默认9999)
|
||||
- 科室信息支持层级嵌套,新增的科室不选分类则认为是一级科室分类
|
||||
- 抽屉表单:科室名称(必填)、上级科室(下拉,选"无"则为一级科室)、科室简介(文本域)、置顶(开关)、排序(数字步进器,默认1)
|
||||
- 点击"编辑"打开编辑抽屉,自动回填科室名称、上级科室、排序等信息
|
||||
- 切换置顶开关即时生效
|
||||
|
||||
---
|
||||
|
||||
### 23. 科室配置弹窗(config-department-dialog.html)
|
||||
### 23. 科室配置弹窗(config-department.html 内嵌抽屉)
|
||||
|
||||

|
||||
|
||||
**功能说明:** 新增或编辑科室信息的表单弹窗。
|
||||
**功能说明:** 新增或编辑科室信息的右侧抽屉表单。
|
||||
|
||||
**表单字段表:**
|
||||
|
||||
| 字段名 | 类型 | 必填 | 规则 |
|
||||
|--------|------|------|------------|
|
||||
| 科室名称 | 文本输入 | 是 | — |
|
||||
| 科室分类 | 下拉选择 | 是 | 不选则是一级科室分类 |
|
||||
| 列表排序序号 | 数字步进器 | 否 | — |
|
||||
| 移动端显示 | 开关 | 否 | 默认开启 |
|
||||
| 列表置顶 | 开关 | 否 | 默认关闭 |
|
||||
| 上级科室 | 下拉选择 | 否 | 选"无"则为一级科室 |
|
||||
| 科室简介 | 多行文本 | 否 | — |
|
||||
| 置顶 | 开关 | 否 | 默认关闭 |
|
||||
| 排序 | 数字步进器 | 否 | 默认1 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 57 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 71 KiB |
Reference in New Issue
Block a user