19 KiB
19 KiB
统一工作台设计规格
日期: 2026-05-01 | 状态: 草案 | 作者: brainstorming session
目录
- 背景与目标 — 为什么要做、要解决什么问题
- 设计决策 — 方案选择过程和最终决策
- 页面布局 — 医生视角和主任视角的详细布局
- 待办数据模型 — ActionItem 统一结构和类型定义
- 交互设计 — 弹窗/抽屉混合、筛选、排序、操作按钮
- 角色感知 — 医生 vs 主任的渲染差异
- 后端 API — ActionInboxService 聚合查询接口
- 与现有模块的关系 — 复用 erp-health / erp-ai 已有能力
- 实施分步 — Phase 划分和依赖关系
- 验证标准 — 完成标准
1. 背景与目标
1.1 问题
HMS 平台功能完成度已达 83%,后端 AI 能力成熟(4 个 SSE 分析端点、建议系统、自动趋势分析、本地规则引擎),但审计揭示了一个核心矛盾:后端能力远超前端覆盖。
具体表现:
- AI 分析"有脑无手" — 后端 4 个 SSE 端点就绪,AI 建议可自动创建,但前端无统一入口展示和处理
- 告警"有声无窗" — 后端告警引擎完整,Web 端无集中展示
- 待办分散 — AI 建议、告警、随访、数据异常分布在不同页面,医生需要逐一查看
- 主任视角缺失 — 科室主任无法快速掌握团队工作负载和科室风险概况
1.2 目标
设计一个统一工作台,作为医生和科室主任的默认首页,实现:
- 一眼看到所有待办 — AI 建议、危急告警、随访、数据异常集中展示
- 一键操作 — 每条待办可直接处理(审批/联系/安排),不强制跳转
- AI 洞察直达 — 右侧面板实时展示最新 AI 分析洞察
- 主任管理视角 — 团队工作负载、超时升级、科室风险分布一目了然
- 设计一致性 — 医生和主任使用相同的页面结构,通过角色感知差异化
1.3 范围
- 包含:Web 端首页工作台重构、后端 ActionInboxService 聚合 API
- 不包含:小程序端改造(独立迭代)、BPMN 工作流编排(AI 行动闭环 Phase 2+)
2. 设计决策
2.1 方案选择过程
通过高保真 HTML 原型对比了三种工作台形态:
| 方案 | 描述 | 优势 | 劣势 |
|---|---|---|---|
| A · 首页即工作台 | 登录后默认首页,取代现有 Dashboard | 零点击触达待办,信息密度高 | 首页功能增多 |
| B · 独立工作台 | 侧边栏入口,三栏布局(筛选+列表+详情) | 筛选能力强,详情展示充分 | 需要额外导航,脱离首页语境 |
| C · 嵌入式体验 | 顶栏气泡+侧边迷你面板+浮动 AI 助手 | 信息无处不在,上下文关联强 | 实现复杂度高,分散注意力 |
最终选择:方案A — 首页即工作台
理由:
- 医生最核心的需求是"快速知道今天要做什么",方案A 零点击满足
- 信息密度适中(左侧待办 + 右侧 AI 洞察),不会过载
- 与现有 Home.tsx 的角色感知 Dashboard 结构兼容,改动最小
2.2 科室主任视角
对比了三种主任工作台方案:
| 方案 | 描述 | 优势 | 劣势 |
|---|---|---|---|
| D · 个人待办 + 团队概览卡 | 和医生同结构,右侧替换为团队概览 | 设计一致性最高 | 团队管理能力相对有限 |
| E · 独立管理仪表盘 | 纯管理视角,6列统计+团队表+告警线 | 管理信息最全面 | 完全不同的页面,开发成本高 |
| F · Tab 双视图 | 同一页面内 Tab 切换 | 兼顾两种需求 | Tab 切换增加认知负担 |
最终选择:方案D — 个人待办 + 团队概览卡
理由:
- 与医生方案保持设计一致性,同一页面结构
- 团队概览卡提供足够的主任管理信息(每人工作负载、处理率、超时数)
- 实现成本最低,角色感知逻辑复用现有模式
2.3 AI 建议交互
决策:弹窗 + 抽屉混合
| 操作类型 | 交互方式 | 原因 |
|---|---|---|
| 批准/拒绝/忽略 | Modal 弹窗确认 | 轻操作,一步完成 |
| 查看完整 AI 分析 | 右侧 Drawer 抽屉 | 需要展示长文本、基线指标、建议详情 |
| 修改后批准 | Drawer 内编辑 | 需要足够空间修改建议内容 |
3. 页面布局
3.1 整体结构
┌─────────────────────────────────────────────────────────────┐
│ 顶部 Tab 切换栏(仅原型用)│ 实际:MainLayout 侧边栏 + 顶栏 │
├──────┬──────────────────────────────────────────────────────┤
│ │ 欢迎语 + 日期 + 待办总数 │
│ 侧 │ ┌──────┬──────┬──────┬──────┬──────┐ │
│ 边 │ │统计卡1│统计卡2│统计卡3│统计卡4│(主任+1)│ │
│ 导 │ └──────┴──────┴──────┴──────┴──────┘ │
│ 航 │ ┌─────────────────────┬──────────────┐ │
│ │ │ │ │ │
│ 220px│ │ 待办任务列表 │ AI 洞察 / │ │
│ │ │ (按紧急度排序) │ 团队概览 │ │
│ │ │ │ (主任) │ │
│ │ │ 类型筛选条 │ │ │
│ │ │ │ │ │
│ │ └─────────────────────┴──────────────┘ │
│ │ 快捷操作区 │
├──────┴──────────────────────────────────────────────────────┤
3.2 医生视角(Doctor)
统计卡片(4 列):
| 序号 | 标签 | 数据源 | 颜色 |
|---|---|---|---|
| 1 | 今日待办 | ActionItem count(assigned_to=me, status=pending) | 蓝 #2563EB |
| 2 | AI 建议待审 | ActionItem count(type=ai_suggestion, status=pending) | 紫 #7C3AED |
| 3 | 危急值告警 | ActionItem count(type=alert, severity=urgent) | 红 #DC2626 |
| 4 | 随访到期 | ActionItem count(type=followup, status=pending) | 橙 #D97706 |
待办列表:
- 默认按紧急度排序:urgent > high > normal > low
- 顶部筛选条:全部 / AI 建议 / 告警 / 随访 / 数据异常
- 每条显示:紧急度圆点 + 标题 + 摘要 + 类型标签 + 风险等级 + 时间 + 操作按钮
- 点击条目 → Drawer 展开详情
右侧 AI 洞察面板(340px):
- 顶部:AI 图标 + "智能洞察" 标题 + 实时标记
- 最近 3 条 AI 分析洞察,每条包含:患者姓名/年龄/诊断、分析摘要、风险等级标签
- 第一条洞察下方放快捷操作按钮(联系患者/安排急诊/调整用药)
- 底部:快捷操作区(查询患者/新建随访/AI 分析)
3.3 科室主任视角(Director)
与医生共享同一页面结构,差异化:
统计卡片(5 列,多 2 个):
| 序号 | 标签 | 说明 |
|---|---|---|
| 1 | 科室待办总计 | 全科室 pending 总数,副文本显示"我负责 N 项" |
| 2 | AI 建议待审 | 全科室范围 |
| 3 | 危急值告警 | 全科室范围 |
| 4 | 随访到期 | 全科室范围 |
| 5 | 今日处理率 | 已处理/总数,绿色 |
待办列表:
- 仅显示分配给主任的待办:超时升级项、高风险 AI 建议审批、随访审核
- 超时升级项带"超时升级"标签和红色高亮
右侧团队概览面板(340px):
- 团队概览卡片:每位医生一行,显示姓名、职称、待办数、处理率进度条、超时数
- 超时医生卡片左侧红色边框 + 红色背景高亮
- 点击医生卡片 → 展开该医生的待办列表
- 底部:科室患者风险分布(高/中/低危统计)
4. 待办数据模型
4.1 ActionItem 统一结构
interface ActionItem {
id: string; // UUID v7
tenant_id: string;
type: 'ai_suggestion' | 'alert' | 'followup' | 'data_anomaly';
severity: 'urgent' | 'high' | 'normal' | 'low';
status: 'pending' | 'in_progress' | 'completed' | 'escalated';
title: string; // "张伟 — 血压危急值告警"
summary: string; // 一句话摘要
patient_id: string;
patient_name: string;
assigned_to: string; // user_id
source_id: string; // 来源记录 ID(ai_suggestion.id / alert.id 等)
source_type: string; // "ai_suggestion" / "alert" / "followup" / "data_anomaly"
created_at: string;
updated_at: string;
due_at?: string; // 超时时间(用于升级判断)
metadata: Record<string, any>; // 类型特定的附加数据
}
4.2 类型与来源映射
| type | 来源模块 | 触发条件 | 默认 severity |
|---|---|---|---|
ai_suggestion |
erp-ai | AI 分析完成 + structured_output 含 suggestions | 从 AI risk_level 映射 |
alert |
erp-health | 告警引擎触发危急值 | urgent |
followup |
erp-health | 随访计划到期 | normal |
data_anomaly |
erp-health | 规则引擎检测到异常 | 从规则配置映射 |
4.3 严重度与升级规则
| severity | 圆点颜色 | 超时 | 升级行为 |
|---|---|---|---|
urgent |
红 #DC2626 | 4 小时 | 升级至科室主任 |
high |
橙 #D97706 | 24 小时 | 升级至科室主任 |
normal |
蓝 #2563EB | 72 小时 | 标记逾期 |
low |
灰 #94A3B8 | 无 | 不升级 |
4.4 不建新表
Phase 1 采用三表 JOIN 聚合查询,不创建独立的 action_items 表:
ai_suggestions+ai_analysis+patient→ AI 建议类待办alerts+patient→ 告警类待办followup_plans+patient→ 随访类待办device_readings(异常) +patient→ 数据异常类待办
理由:避免数据冗余和同步问题。各模块已有完整数据,工作台只做聚合展示。未来如需独立表,可作为 Phase 2 引入。
5. 交互设计
5.1 待办列表交互
筛选:
- 顶部筛选条:全部 / AI 建议 / 告警 / 随访 / 数据异常
- 点击切换,无页面刷新,前端过滤已加载的数据
- 默认显示"全部"
排序:
- 默认按紧急度排序(urgent > high > normal > low)
- 同级别按创建时间倒序
- 未来可扩展:按患者、按时间排序
点击行为:
- 点击待办条目 → 右侧 Drawer 抽屉展开(宽度 480px)
- Drawer 内容根据
type不同渲染不同详情组件
5.2 Drawer 详情面板
AI 建议 (ai_suggestion):
- 顶部:类型标签 + 风险等级 + 触发时间
- 患者信息:姓名、年龄、性别、诊断、科室
- AI 分析摘要(Markdown 渲染)
- 建议方案(高亮框)
- 基线指标网格(2x2:关键数值 + 趋势箭头)
- 操作按钮:批准 / 拒绝 / 修改后批准
危急告警 (alert):
- 告警详情:触发指标、阈值、当前值
- 患者基本信息
- 快捷操作:联系患者 / 安排急诊 / 调整用药
- 操作按钮:已处理 / 转交
随访 (followup):
- 随访计划详情
- 上次随访摘要
- 操作按钮:开始随访 / 延期 / 标记完成
数据异常 (data_anomaly):
- 异常指标详情
- 历史趋势迷你图
- 操作按钮:查看详情 / AI 分析 / 忽略
5.3 Modal 弹窗
批准确认:
- 显示建议摘要
- "确认批准?" + 备注(可选)
- 按钮:确认 / 取消
拒绝确认:
- 必填拒绝原因
- 按钮:确认拒绝 / 取消
忽略确认:
- "确认忽略此待办?"
- 按钮:确认 / 取消
5.4 右侧面板交互
医生 — AI 洞察面板:
- 显示最近 3 条 AI 分析洞察(按时间倒序)
- 第一条洞察下方显示快捷操作按钮
- 点击洞察标题 → 打开对应患者的 AI 建议 Drawer
主任 — 团队概览面板:
- 每位医生一行卡片,hover 高亮
- 点击医生卡片 → Drawer 展开该医生的待办列表
- 超时医生卡片:左侧红色边框 + 浅红背景 + 超时数红色高亮
- 底部风险分布:高/中/低危三色统计块
6. 角色感知
6.1 渲染逻辑
if user.role contains 'director' or 'department_head':
render DirectorDashboard()
else:
render DoctorDashboard()
共享组件:
WorkbenchLayout— 整体布局框架StatCardGrid— 统计卡片网格TodoList— 待办列表ActionDrawer— 详情抽屉ActionModal— 操作弹窗
差异组件:
AiInsightPanel— 医生专属,AI 洞察TeamOverviewPanel— 主任专属,团队概览RiskDistribution— 主任专属,风险分布
6.2 数据范围差异
| 维度 | 医生 | 主任 |
|---|---|---|
| 待办范围 | assigned_to = my_id |
assigned_to = my_id + 超时升级项 |
| 统计范围 | 仅自己 | 全科室 |
| 团队概览 | 不显示 | 显示本科室所有医生 |
| 风险分布 | 不显示 | 全科室患者 |
| AI 洞察 | 自己负责的患者 | 不显示(用团队概览替代) |
7. 后端 API
7.1 ActionInboxService
归属 crate:erp-health
核心方法:
| 方法 | 路由 | 说明 | 权限码 |
|---|---|---|---|
list_action_items |
GET /api/v1/health/action-inbox |
聚合查询待办列表 | health.action_inbox.list |
get_action_thread |
GET /api/v1/health/action-inbox/:id/thread |
获取待办处理线程 | health.action_inbox.list |
get_team_overview |
GET /api/v1/health/action-inbox/team |
主任:团队概览 | health.action_inbox.team |
get_workbench_stats |
GET /api/v1/health/action-inbox/stats |
统计卡片数据 | health.action_inbox.list |
7.2 list_action_items 查询参数
GET /api/v1/health/action-inbox?type=ai_suggestion&severity=urgent&page=1&page_size=20
| 参数 | 类型 | 说明 |
|---|---|---|
type |
string | 可选,筛选类型:ai_suggestion / alert / followup / data_anomaly |
severity |
string | 可选,筛选紧急度 |
status |
string | 可选,默认 pending |
patient_id |
uuid | 可选,按患者筛选 |
page |
number | 页码,默认 1 |
page_size |
number | 每页条数,默认 20 |
7.3 聚合查询策略
不建独立表,通过 SQL UNION 聚合四类数据源:
-- AI 建议类
SELECT s.id, 'ai_suggestion' as type, s.risk_level as severity,
s.title, s.summary, s.patient_id, p.name as patient_name,
s.assigned_to, s.created_at, 'ai_suggestion' as source_type
FROM ai_suggestions s JOIN patients p ON s.patient_id = p.id
WHERE s.status = 'pending' AND s.tenant_id = $1
UNION ALL
-- 告警类
SELECT a.id, 'alert' as type, 'urgent' as severity,
a.title, a.summary, a.patient_id, p.name as patient_name,
a.assigned_to, a.created_at, 'alert' as source_type
FROM alerts a JOIN patients p ON a.patient_id = p.id
WHERE a.status = 'active' AND a.tenant_id = $1
-- ... 随访、异常类同理
ORDER BY severity_priority, created_at DESC
7.4 get_team_overview 响应
{
"members": [
{
"user_id": "uuid",
"name": "李明远",
"title": "副主任医师",
"pending_count": 5,
"completed_count": 3,
"overdue_count": 1,
"completion_rate": 0.6
}
],
"risk_distribution": {
"high": 3,
"medium": 8,
"low": 24
},
"total_pending": 18,
"total_completed": 12
}
8. 与现有模块的关系
8.1 复用已有能力
| 能力 | 来源 | 复用方式 |
|---|---|---|
| AI 建议数据 | erp-ai AiSuggestionService |
直接查询 ai_suggestions 表 |
| 告警数据 | erp-health AlertService |
直接查询 alerts 表 |
| 随访数据 | erp-health FollowupService |
直接查询 followup_plans 表 |
| 角色感知 | Home.tsx 已有模式 |
参考现有 role-based Dashboard 分发 |
| Drawer 组件 | ActionThreadDrawer 已存在 |
复用并扩展 |
| 建议审批 | AiSuggestionTab 已存在 |
复用审批逻辑 |
| SSE 客户端 | analysisSse.ts 已存在 |
不涉及(工作台不触发分析) |
8.2 新增代码归属
| 文件 | crate/模块 | 说明 |
|---|---|---|
action_inbox_service.rs |
erp-health/service | 聚合查询服务 |
action_inbox_handler.rs |
erp-health/handler | API 路由处理 |
WorkbenchHome.tsx |
web/pages | 新首页组件(替代 Home.tsx 中的 Dashboard 部分) |
TodoList.tsx |
web/components | 待办列表组件 |
AiInsightPanel.tsx |
web/components | AI 洞察面板 |
TeamOverviewPanel.tsx |
web/components | 团队概览面板 |
ActionDetailDrawer.tsx |
web/components | 操作详情抽屉 |
actionInbox.ts |
web/api/health | API 客户端(已存在,需补充) |
8.3 权限码
新增权限码(注册在 erp-health):
| 权限码 | 说明 |
|---|---|
health.action_inbox.list |
查看待办列表 |
health.action_inbox.manage |
处理待办(批准/拒绝/转交) |
health.action_inbox.team |
查看团队概览(主任专属) |
9. 实施分步
Phase 1A:后端聚合 API(2-3 天)
- 创建
action_inbox_service.rs— 实现四类数据源 UNION 聚合查询 - 创建
action_inbox_handler.rs— 注册 4 个 API 端点 - 注册权限码
health.action_inbox.* - 编写单元测试
Phase 1B:Web 前端组件(2-3 天)
- 创建
TodoList.tsx— 待办列表组件(筛选、排序、点击) - 创建
AiInsightPanel.tsx— AI 洞察面板 - 创建
TeamOverviewPanel.tsx— 团队概览面板 - 创建
ActionDetailDrawer.tsx— 详情抽屉(按类型渲染不同内容) - 补充
actionInbox.tsAPI 客户端 - 改造
Home.tsx— 用新组件替换现有 Dashboard
Phase 1C:联调验证(1 天)
- 前后端联调
- 角色感知测试(医生视角 vs 主任视角)
- 四类待办数据验证
pnpm build生产构建通过
10. 验证标准
功能验证
- 医生登录后,首页显示工作台(4 个统计卡片 + 待办列表 + AI 洞察)
- 主任登录后,首页显示工作台(5 个统计卡片 + 我的待办 + 团队概览)
- 待办列表按紧急度正确排序
- 类型筛选条正确过滤
- 点击 AI 建议待办 → Drawer 展示完整分析 + 操作按钮
- 批准/拒绝操作 → Modal 确认 → 调用后端 API 成功
- 主任团队概览正确显示每位医生的工作负载
- 超时升级项正确出现在主任的待办列表
技术验证
cargo check全 workspace 通过cargo test相关测试通过pnpm build前端生产构建通过- API 可通过 Swagger UI 测试
- 权限码正确拦截未授权访问