# 统一工作台设计规格 > 日期: 2026-05-01 | 状态: 草案 | 作者: brainstorming session ## 目录 1. **背景与目标** — 为什么要做、要解决什么问题 2. **设计决策** — 方案选择过程和最终决策 3. **页面布局** — 医生视角和主任视角的详细布局 4. **待办数据模型** — ActionItem 统一结构和类型定义 5. **交互设计** — 弹窗/抽屉混合、筛选、排序、操作按钮 6. **角色感知** — 医生 vs 主任的渲染差异 7. **后端 API** — ActionInboxService 聚合查询接口 8. **与现有模块的关系** — 复用 erp-health / erp-ai 已有能力 9. **实施分步** — Phase 划分和依赖关系 10. **验证标准** — 完成标准 --- ## 1. 背景与目标 ### 1.1 问题 HMS 平台功能完成度已达 83%,后端 AI 能力成熟(4 个 SSE 分析端点、建议系统、自动趋势分析、本地规则引擎),但审计揭示了一个核心矛盾:**后端能力远超前端覆盖**。 具体表现: - **AI 分析"有脑无手"** — 后端 4 个 SSE 端点就绪,AI 建议可自动创建,但前端无统一入口展示和处理 - **告警"有声无窗"** — 后端告警引擎完整,Web 端无集中展示 - **待办分散** — AI 建议、告警、随访、数据异常分布在不同页面,医生需要逐一查看 - **主任视角缺失** — 科室主任无法快速掌握团队工作负载和科室风险概况 ### 1.2 目标 设计一个**统一工作台**,作为医生和科室主任的默认首页,实现: 1. **一眼看到所有待办** — AI 建议、危急告警、随访、数据异常集中展示 2. **一键操作** — 每条待办可直接处理(审批/联系/安排),不强制跳转 3. **AI 洞察直达** — 右侧面板实时展示最新 AI 分析洞察 4. **主任管理视角** — 团队工作负载、超时升级、科室风险分布一目了然 5. **设计一致性** — 医生和主任使用相同的页面结构,通过角色感知差异化 ### 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 统一结构 ```typescript 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; // 类型特定的附加数据 } ``` ### 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 聚合四类数据源: ```sql -- 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 响应 ```json { "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 天) 1. 创建 `action_inbox_service.rs` — 实现四类数据源 UNION 聚合查询 2. 创建 `action_inbox_handler.rs` — 注册 4 个 API 端点 3. 注册权限码 `health.action_inbox.*` 4. 编写单元测试 ### Phase 1B:Web 前端组件(2-3 天) 1. 创建 `TodoList.tsx` — 待办列表组件(筛选、排序、点击) 2. 创建 `AiInsightPanel.tsx` — AI 洞察面板 3. 创建 `TeamOverviewPanel.tsx` — 团队概览面板 4. 创建 `ActionDetailDrawer.tsx` — 详情抽屉(按类型渲染不同内容) 5. 补充 `actionInbox.ts` API 客户端 6. 改造 `Home.tsx` — 用新组件替换现有 Dashboard ### Phase 1C:联调验证(1 天) 1. 前后端联调 2. 角色感知测试(医生视角 vs 主任视角) 3. 四类待办数据验证 4. `pnpm build` 生产构建通过 --- ## 10. 验证标准 ### 功能验证 - [ ] 医生登录后,首页显示工作台(4 个统计卡片 + 待办列表 + AI 洞察) - [ ] 主任登录后,首页显示工作台(5 个统计卡片 + 我的待办 + 团队概览) - [ ] 待办列表按紧急度正确排序 - [ ] 类型筛选条正确过滤 - [ ] 点击 AI 建议待办 → Drawer 展示完整分析 + 操作按钮 - [ ] 批准/拒绝操作 → Modal 确认 → 调用后端 API 成功 - [ ] 主任团队概览正确显示每位医生的工作负载 - [ ] 超时升级项正确出现在主任的待办列表 ### 技术验证 - [ ] `cargo check` 全 workspace 通过 - [ ] `cargo test` 相关测试通过 - [ ] `pnpm build` 前端生产构建通过 - [ ] API 可通过 Swagger UI 测试 - [ ] 权限码正确拦截未授权访问