# 健康管理系统 — erp-health 模块设计规格 > **文档版本**: 1.0 > **日期**: 2026-04-23 > **状态**: 已确认 > **范围**: V1 — 患者管理 + 健康数据 + 预约排班 + 随访管理 + 咨询管理 --- ## 1. 项目背景 ### 1.1 产品定位 构建一个面向体检中心/医疗机构的**综合型健康管理平台**,以体检中心为数据源,汇集不同情况的患者,提供全生命周期的健康管理服务。 本系统从 ERP 平台底座分叉独立,作为 **Health Management System (HMS)** 产品演进。ERP 底座提供身份权限、工作流、消息通知、系统配置等基础能力,`erp-health` 作为原生 Rust 模块承载所有医疗业务逻辑。 ### 1.2 系统架构 ``` 📱 患者端(微信小程序) ──┐ ├──→ 🔀 API 网关 ──→ 🖥️ ERP 后端(HMS) 👨‍⚕️ 医护端(小程序/H5) ──┘ │ │ │ ├── erp-auth(用户/角色/权限) │ ├── erp-workflow(工作流引擎) │ ├── erp-message(消息通知) │ ├── erp-config(字典/配置) │ └── erp-health(健康管理)★ 新增 │ └──→ 💾 PostgreSQL + Redis ``` **关键决策:** - ERP 只负责 **PC 管理后台**功能 - 小程序(患者端/医护端)作为**独立系统**开发 - 数据共享通过 **API 网关**实现 - 健康管理使用**原生 Rust 模块**(非 WASM 插件),获得完整的数据库访问和自定义 API 能力 ### 1.3 为什么不用 WASM 插件 | 限制 | 影响 | |------|------| | 实体上限 20 个 | 综合健康平台轻松超过 | | JSONB 存储 | 医疗数据需要强类型、索引、关联 | | 无自定义 API | 趋势分析、统计报表需要专用端点 | | 无文件上传 | 化验单、体检报告无法存储 | | WASM 沙箱限制 | 无法引入加密、AI、外部 API | 原生模块遵循现有模式(如 erp-auth、erp-workflow)。**注意:**`ErpModule` trait 没有 `register_routes` 方法。模块通过固有方法 `public_routes()` 和 `protected_routes()` 暴露路由,在 `erp-server` 的 `main.rs` 中通过 `.nest("/api/v1/health", HealthModule::protected_routes())` 集成。通过 EventBus 通信,未来可平滑拆分为独立微服务。 --- ## 2. V1 功能范围 | 模块 | 功能 | 页面数 | |------|------|--------| | ① 患者与医护管理 | 患者档案、家庭成员、医护档案、患者标签 | 3 | | ② 健康数据管理 | 体检记录、日常监测、化验报告、趋势分析 | 3 | | ③ 预约与排班 | 预约管理、医生排班、日历视图 | 2 | | ④ 随访管理 | 随访任务、随访记录台账 | 2 | | ⑤ 咨询管理 | 会话管理、对话记录查看/导出 | 2 | | ⑥ 医护管理 | 医护人员列表 | 1 | | **合计** | | **13** | **V2 预留:** 积分商城、数据统计中心、内容管理增强。 --- ## 3. 实体模型 ### 3.1 设计原则 - 患者和医护的**账号**走 `erp-auth` 的 `users` 表,`erp-health` 只存医疗业务扩展字段 - 通过 `user_id` 外键关联 `users` 表 - 所有表含 `tenant_id`(多租户隔离)、`id`(UUIDv7)、`created_at`、`updated_at`、`created_by`、`updated_by`、`deleted_at`、`version` - 多对多关系使用中间表 ### 3.2 实体定义 #### ① 患者与医护管理 **patient — 患者档案** | 字段 | 类型 | 说明 | |------|------|------| | id | UUID PK | UUIDv7 | | tenant_id | UUID NOT NULL | 租户 ID | | user_id | UUID FK → users | 关联 erp-auth 账号 | | name | VARCHAR(100) | 姓名 | | gender | VARCHAR(10) | 性别 (male/female/other) | | birth_date | DATE | 出生日期 | | blood_type | VARCHAR(10) | 血型 (A/B/AB/O/RH-/RH+) | | id_number | VARCHAR(20) | 身份证号 | | allergy_history | TEXT | 过敏史 | | medical_history_summary | TEXT | 病史摘要 | | emergency_contact_name | VARCHAR(100) | 紧急联系人姓名 | | emergency_contact_phone | VARCHAR(20) | 紧急联系人电话 | | status | VARCHAR(20) | 状态 (active/inactive/deceased) | | verification_status | VARCHAR(20) | 实名认证 (pending/verified/rejected) | | source | VARCHAR(100) | 来源(体检中心名称) | | notes | TEXT | 备注 | | created_at, updated_at, created_by, updated_by, deleted_at, version | — | 标准字段 | 索引:`(tenant_id, name)`, `(tenant_id, status)`, `(tenant_id, id_number) UNIQUE WHERE deleted_at IS NULL` **patient_family_member — 家庭成员** | 字段 | 类型 | 说明 | |------|------|------| | id | UUID PK | | | tenant_id | UUID NOT NULL | | | patient_id | UUID FK → patient | 患者关联 | | name | VARCHAR(100) | 姓名 | | relationship | VARCHAR(50) | 关系(父亲/母亲/配偶/子女等) | | phone | VARCHAR(20) | 电话 | | birth_date | DATE | 出生日期 | | notes | TEXT | 备注 | | 标准 ERP 字段 | — | | **doctor_profile — 医护档案** | 字段 | 类型 | 说明 | |------|------|------| | id | UUID PK | | | tenant_id | UUID NOT NULL | | | user_id | UUID FK → users | 关联 erp-auth 账号 | | department | VARCHAR(100) | 科室 | | title | VARCHAR(50) | 职称(主任医师/副主任医师/主治医师等) | | specialty | VARCHAR(200) | 专长 | | license_number | VARCHAR(50) | 执业证号 | | bio | TEXT | 简介 | | online_status | VARCHAR(20) | 在线状态 (online/offline/busy) | | 标准 ERP 字段 | — | | 索引:`(tenant_id, patient_id)` **patient_tag — 患者标签** | 字段 | 类型 | 说明 | |------|------|------| | id | UUID PK | | | tenant_id | UUID NOT NULL | | | name | VARCHAR(50) | 标签名 | | color | VARCHAR(20) | 颜色值 | | description | TEXT | 描述 | | is_system | BOOLEAN | 系统标签(不可删除) | | 标准 ERP 字段 | — | | 索引:`UNIQUE (tenant_id, name) WHERE deleted_at IS NULL` **patient_tag_relation — 患者-标签关联** | 字段 | 类型 | 说明 | |------|------|------| | id | UUID PK | | | tenant_id | UUID NOT NULL | | | patient_id | UUID FK → patient | | | tag_id | UUID FK → patient_tag | | | created_at | TIMESTAMPTZ | | | updated_at | TIMESTAMPTZ | | | created_by | UUID | | | updated_by | UUID | | | deleted_at | TIMESTAMPTZ | 软删除 | 索引:`(tenant_id, patient_id)`, `(tenant_id, tag_id)` **patient_doctor_relation — 医患关系** | 字段 | 类型 | 说明 | |------|------|------| | id | UUID PK | | | tenant_id | UUID NOT NULL | | | patient_id | UUID FK → patient | | | doctor_id | UUID FK → doctor_profile | | | relationship_type | VARCHAR(20) | 类型 (primary/consulting) | | created_at | TIMESTAMPTZ | | | updated_at | TIMESTAMPTZ | | | created_by | UUID | | | updated_by | UUID | | | deleted_at | TIMESTAMPTZ | 软删除 | 索引:`(tenant_id, patient_id)`, `(tenant_id, doctor_id)` #### ② 健康数据管理 **health_record — 体检/就诊记录** | 字段 | 类型 | 说明 | |------|------|------| | id | UUID PK | | | tenant_id | UUID NOT NULL | | | patient_id | UUID FK → patient | | | record_type | VARCHAR(20) | 类型 (checkup/outpatient/inpatient) | | record_date | DATE | 记录日期 | | source | VARCHAR(200) | 来源(体检中心/医院名称) | | overall_assessment | TEXT | 总体评估 | | report_file_url | VARCHAR(500) | 报告文件 URL | | notes | TEXT | 备注 | | 标准 ERP 字段 | — | | 索引:`(tenant_id, patient_id, record_date DESC)` **vital_signs — 日常监测数据** | 字段 | 类型 | 说明 | |------|------|------| | id | UUID PK | | | tenant_id | UUID NOT NULL | | | patient_id | UUID FK → patient | | | record_date | DATE | 记录日期 | | systolic_bp_morning | INTEGER | 晨起收缩压 | | diastolic_bp_morning | INTEGER | 晨起舒张压 | | systolic_bp_evening | INTEGER | 晚间收缩压 | | diastolic_bp_evening | INTEGER | 晚间舒张压 | | heart_rate | INTEGER | 心率 | | weight | DECIMAL(5,1) | 体重 (kg) | | blood_sugar | DECIMAL(5,1) | 血糖 (mmol/L) | | water_intake_ml | INTEGER | 饮水量 (ml) | | urine_output_ml | INTEGER | 尿量 (ml) | | notes | TEXT | 备注 | | 标准 ERP 字段 | — | | 索引:`(tenant_id, patient_id, record_date DESC)` **lab_report — 化验报告** | 字段 | 类型 | 说明 | |------|------|------| | id | UUID PK | | | tenant_id | UUID NOT NULL | | | patient_id | UUID FK → patient | | | report_date | DATE | 报告日期 | | report_type | VARCHAR(50) | 报告类型(肾功能/血常规/尿常规等) | | indicators | JSONB | 指标数据 [{name, value, unit, ref_range, is_abnormal}] | | image_urls | JSONB | 图片 URLs [url1, url2, ...] | | doctor_interpretation | TEXT | 医生解读 | | 标准 ERP 字段 | — | | 索引:`(tenant_id, patient_id, report_date DESC)`, GIN on `indicators`, `(tenant_id, report_type)` **health_trend — 健康趋势报告** | 字段 | 类型 | 说明 | |------|------|------| | id | UUID PK | | | tenant_id | UUID NOT NULL | | | patient_id | UUID FK → patient | | | period_start | DATE | 周期开始 | | period_end | DATE | 周期结束 | | indicator_summary | JSONB | 指标摘要 | | abnormal_items | JSONB | 异常项 | | generation_type | VARCHAR(20) | 生成方式 (auto/manual) | | report_file_url | VARCHAR(500) | 报告文件 URL | | 标准 ERP 字段 | — | | 索引:`(tenant_id, patient_id, period_start DESC)` #### ③ 预约排班 **appointment — 预约记录** | 字段 | 类型 | 说明 | |------|------|------| | id | UUID PK | | | tenant_id | UUID NOT NULL | | | patient_id | UUID FK → patient | | | doctor_id | UUID FK → doctor_profile | | | appointment_type | VARCHAR(20) | 类型 (dialysis/recheck/outpatient) | | appointment_date | DATE | 预约日期 | | start_time | TIME | 开始时间 | | end_time | TIME | 结束时间 | | status | VARCHAR(20) | 状态 (pending/confirmed/cancelled/completed/no_show) | | cancel_reason | TEXT | 取消原因 | | notes | TEXT | 备注 | | 标准 ERP 字段 | — | | 索引:`(tenant_id, appointment_date, status)`, `(tenant_id, doctor_id, appointment_date)` **doctor_schedule — 医生排班** | 字段 | 类型 | 说明 | |------|------|------| | id | UUID PK | | | tenant_id | UUID NOT NULL | | | doctor_id | UUID FK → doctor_profile | | | schedule_date | DATE | 排班日期 | | period_type | VARCHAR(20) | 时段 (am/pm/night/full_day) | | start_time | TIME | 开始时间 | | end_time | TIME | 结束时间 | | max_appointments | INTEGER | 最大预约数 | | current_appointments | INTEGER | 已预约数(默认 0) | | status | VARCHAR(20) | 状态 (enabled/disabled) | | 标准 ERP 字段 | — | 索引:`(tenant_id, doctor_id, schedule_date)`, `UNIQUE (tenant_id, doctor_id, schedule_date, period_type) WHERE deleted_at IS NULL` **预约并发控制:** 创建预约时使用原子 CAS 操作 `UPDATE doctor_schedule SET current_appointments = current_appointments + 1 WHERE id = $1 AND current_appointments < max_appointments RETURNING *`,防止超额预约。 #### ④ 随访管理 **follow_up_task — 随访任务** | 字段 | 类型 | 说明 | |------|------|------| | id | UUID PK | | | tenant_id | UUID NOT NULL | | | patient_id | UUID FK → patient | | | assigned_to | UUID FK → users | 负责医护 | | follow_up_type | VARCHAR(20) | 类型 (phone/face_to_face/online) | | planned_date | DATE | 计划日期 | | status | VARCHAR(20) | 状态 (pending/in_progress/completed/overdue/cancelled) | | content_template | TEXT | 随访内容模板 | | related_appointment_id | UUID FK → appointment | 关联预约 | | 标准 ERP 字段 | — | | 索引:`(tenant_id, assigned_to, status)`, `(tenant_id, planned_date, status)` **follow_up_record — 随访记录** | 字段 | 类型 | 说明 | |------|------|------| | id | UUID PK | | | tenant_id | UUID NOT NULL | | | task_id | UUID FK → follow_up_task | | | executed_by | UUID FK → users | 执行医护 | | executed_date | DATE | 执行日期 | | result | VARCHAR(20) | 结果 (followed_up/unreachable/refused/other) | | patient_condition | TEXT | 患者状况 | | medical_advice | TEXT | 医嘱建议 | | next_follow_up_date | DATE | 下次随访日期 | | 标准 ERP 字段 | — | | 索引:`(tenant_id, task_id)`, `(tenant_id, executed_date)` #### ⑤ 咨询管理 **consultation_session — 咨询会话** | 字段 | 类型 | 说明 | |------|------|------| | id | UUID PK | | | tenant_id | UUID NOT NULL | | | patient_id | UUID FK → patient | | | doctor_id | UUID FK → doctor_profile | | | type | VARCHAR(20) | 类型 (customer_service/doctor) | | status | VARCHAR(20) | 状态 (waiting/active/closed) | | last_message_at | TIMESTAMPTZ | 最后消息时间 | | unread_count_patient | INTEGER | 患者未读数 | | unread_count_doctor | INTEGER | 医生未读数 | | 标准 ERP 字段 | — | | 索引:`(tenant_id, doctor_id, status)`, `(tenant_id, patient_id, status)` **consultation_message — 咨询消息** | 字段 | 类型 | 说明 | |------|------|------| | id | UUID PK | | | tenant_id | UUID NOT NULL | | | session_id | UUID FK → consultation_session | | | sender_id | UUID | 发送者 ID | | sender_role | VARCHAR(20) | 角色 (patient/doctor/system) | | content_type | VARCHAR(20) | 类型 (text/image/voice/file) | | content | TEXT | 内容 | | is_read | BOOLEAN | 已读状态(默认 false) | | created_at | TIMESTAMPTZ | 发送时间 | | updated_at | TIMESTAMPTZ | | | created_by | UUID | | | updated_by | UUID | | | deleted_at | TIMESTAMPTZ | 软删除(内容审核用) | | version | INT NOT NULL DEFAULT 1 | 乐观锁 | 索引:`(tenant_id, session_id, created_at)` **数据增长策略:** 对 `created_at` 按月分区(PostgreSQL table partitioning),超过 1 年的已关闭会话消息归档到冷存储。 **说明:** - `patient.user_id` 允许 NULL — 患者可先创建档案(如体检中心导入),后续再绑定 erp-auth 账号 - `consultation_message.sender_id` 引用 `users.id` — 统一使用 erp-auth 用户体系标识发送者 --- ## 3.3 状态机定义 ### appointment.status 转换 ``` pending ──→ confirmed ──→ completed │ │ │ └──→ no_show(预约时间过后,系统自动或前台手动触发) │ └──→ cancelled(任意时刻可取消,需填 cancel_reason) ``` ### follow_up_task.status 转换 ``` pending ──→ in_progress ──→ completed │ │ └──→ cancelled └──→ overdue(系统定时任务:planned_date 已过且仍 pending 自动标记) ``` ### consultation_session.status 转换 ``` waiting ──→ active(第一条消息发送时自动触发)──→ closed(手动关闭或超时自动关闭) ``` ### patient.status 转换 ``` active ──→ inactive(手动停用) active ──→ deceased(标记死亡,不可逆) inactive ──→ active(重新激活) ``` ### patient.verification_status 转换 ``` pending ──→ verified(实名认证通过) pending ──→ rejected(认证被拒) rejected ──→ pending(重新提交认证) ``` --- ## 4. API 设计 所有端点前缀: `/api/v1/health/` ### 4.1 患者管理 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/patients` | 患者列表(分页、搜索、标签筛选) | | POST | `/patients` | 创建患者 | | GET | `/patients/:id` | 患者详情 | | PUT | `/patients/:id` | 更新患者 | | DELETE | `/patients/:id` | 软删除 | | POST | `/patients/:id/tags` | 管理标签(批量设置) | | GET | `/patients/:id/health-summary` | 健康摘要 | | GET | `/patients/:id/family-members` | 家庭成员列表 | | POST | `/patients/:id/family-members` | 新增家庭成员 | | PUT | `/patients/:id/family-members/:fid` | 更新家庭成员 | | DELETE | `/patients/:id/family-members/:fid` | 删除家庭成员 | | POST | `/patients/:id/doctors` | 分配主治医生 | | DELETE | `/patients/:id/doctors/:did` | 移除医患关系 | ### 4.2 健康数据 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/patients/:id/vital-signs` | 日常监测列表 | | POST | `/patients/:id/vital-signs` | 新增监测数据 | | GET | `/patients/:id/lab-reports` | 化验报告列表 | | POST | `/patients/:id/lab-reports` | 新增化验报告 | | GET | `/patients/:id/health-records` | 体检/就诊记录 | | POST | `/patients/:id/health-records` | 新增记录 | | GET | `/patients/:id/trends` | 趋势报告 | | POST | `/patients/:id/trends/generate` | 生成趋势报告 | | GET | `/patients/:id/trends/:indicator` | 单指标时序数据 | | PUT | `/patients/:id/vital-signs/:vid` | 更新监测数据 | | DELETE | `/patients/:id/vital-signs/:vid` | 删除监测数据 | | PUT | `/patients/:id/lab-reports/:rid` | 更新化验报告 | | DELETE | `/patients/:id/lab-reports/:rid` | 删除化验报告 | | PUT | `/patients/:id/health-records/:rid` | 更新体检记录 | | DELETE | `/patients/:id/health-records/:rid` | 删除体检记录 | ### 4.3 预约排班 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/appointments` | 预约列表 | | POST | `/appointments` | 创建预约 | | PUT | `/appointments/:id/status` | 更新状态 | | GET | `/doctor-schedules` | 排班列表 | | POST | `/doctor-schedules` | 创建排班 | | PUT | `/doctor-schedules/:id` | 更新排班 | | GET | `/doctor-schedules/calendar` | 日历视图 | ### 4.4 随访管理 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/follow-up-tasks` | 任务列表 | | POST | `/follow-up-tasks` | 创建任务 | | PUT | `/follow-up-tasks/:id` | 更新任务 | | DELETE | `/follow-up-tasks/:id` | 删除任务 | | POST | `/follow-up-tasks/:id/records` | 填写随访记录 | | GET | `/follow-up-records` | 随访台账 | ### 4.5 咨询管理 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/consultation-sessions` | 会话列表 | | GET | `/consultation-sessions/:id/messages` | 消息记录 | | PUT | `/consultation-sessions/:id/close` | 关闭会话 | | POST | `/consultation-messages` | 写入消息(API 网关用) | | GET | `/consultation-sessions/export` | 导出 | ### 4.6 医护管理 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/doctors` | 医护列表 | | POST | `/doctors` | 创建医护档案 | | GET | `/doctors/:id` | 医护详情 | | PUT | `/doctors/:id` | 更新医护档案 | | DELETE | `/doctors/:id` | 软删除医护档案 | --- ## 5. 前端页面设计 文件位置: `apps/web/src/pages/health/` ### 5.1 页面清单 | # | 页面 | 文件名 | 类型 | |---|------|--------|------| | 1 | 患者列表 | PatientList.tsx | 表格+搜索+标签筛选+导出 | | 2 | 患者详情 | PatientDetail.tsx | Tab布局:基本信息/健康趋势/化验报告/就诊记录/随访记录 | | 3 | 标签管理 | PatientTagManage.tsx | CRUD+颜色+批量打标 | | 4 | 日常监测 | VitalSignsList.tsx | 按患者+日期+ECharts趋势折线图 | | 5 | 化验报告 | LabReportList.tsx | 列表+图片预览+指标详情+解读 | | 6 | 体检记录 | HealthRecordList.tsx | 类型筛选+报告文件查看/上传 | | 7 | 预约管理 | AppointmentList.tsx | 列表/日历切换+状态流转 | | 8 | 排班管理 | DoctorSchedule.tsx | 周/月日历+排班模板 | | 9 | 随访任务 | FollowUpTaskList.tsx | 任务CRUD+分配+关联工作流 | | 10 | 随访台账 | FollowUpRecordList.tsx | 按患者/医护/日期筛选+导出 | | 11 | 会话管理 | ConsultationList.tsx | 列表+未回复统计 | | 12 | 对话记录 | ConsultationDetail.tsx | 聊天气泡+图片/语音查看+导出 | | 13 | 医护列表 | DoctorList.tsx | 列表+科室筛选+在线状态 | ### 5.2 技术要点 - **ECharts 趋势图** — 血压/体重/血糖曲线图,按日期范围展示 - **文件上传/预览** — 化验单图片、体检报告 PDF(需新增基础能力) - **日历组件** — Ant Design Calendar 用于排班和预约视图 - **聊天 UI** — 消息气泡展示(只读,非实时聊天) - **导出** — 随访台账、咨询记录导出为 Excel --- ## 6. 事件集成 ### 6.1 发布事件 | 事件类型 | 触发时机 | 载荷 | |----------|----------|------| | `patient.created` | 创建患者 | `{patient_id, name, tenant_id}` | | `patient.updated` | 更新患者信息 | `{patient_id, changed_fields}` | | `appointment.created` | 创建预约 | `{appointment_id, patient_id, doctor_id, date}` | | `appointment.confirmed` | 确认预约 | `{appointment_id}` | | `appointment.cancelled` | 取消预约 | `{appointment_id, cancel_reason}` | | `appointment.completed` | 完成就诊 | `{appointment_id}` | | `follow_up.created` | 创建随访任务 | `{task_id, patient_id, assigned_to, planned_date}` | | `follow_up.completed` | 完成随访 | `{task_id, record_id, result}` | | `lab_report.uploaded` | 上传化验报告 | `{report_id, patient_id, report_type, abnormal_count}` | | `consultation.opened` | 开启咨询 | `{session_id, patient_id, doctor_id}` | | `consultation.closed` | 关闭咨询 | `{session_id}` | | `patient.deceased` | 患者死亡标记 | `{patient_id}` | | `patient.verified` | 实名认证通过 | `{patient_id, id_number}` | | `follow_up.overdue` | 随访任务逾期 | `{task_id, patient_id, planned_date}` | | `doctor.online_status_changed` | 医护在线状态变更 | `{doctor_id, old_status, new_status}` | **随访记录自动创建后续任务:** 当 `follow_up_record.next_follow_up_date` 不为空时,服务层自动创建新的 `follow_up_task`(planned_date = next_follow_up_date,assigned_to 沿用当前医护)。 ### 6.2 订阅事件 | 事件类型 | 处理逻辑 | |----------|----------| | `workflow.task.completed` | 工作流任务完成时更新随访任务状态 | | `message.sent` | 消息发送时联动咨询会话的 last_message_at | --- ## 7. 模块结构 ``` crates/erp-health/ ├── Cargo.toml ├── src/ │ ├── lib.rs ← ErpModule trait + public_routes() / protected_routes() │ ├── error.rs ← HealthError → AppError │ ├── state.rs ← HealthState (共享状态) │ ├── entity/ ← SeaORM Entity │ │ ├── mod.rs │ │ ├── patient.rs │ │ ├── patient_family_member.rs │ │ ├── patient_tag.rs │ │ ├── patient_tag_relation.rs │ │ ├── patient_doctor_relation.rs │ │ ├── doctor_profile.rs │ │ ├── health_record.rs │ │ ├── vital_signs.rs │ │ ├── lab_report.rs │ │ ├── health_trend.rs │ │ ├── appointment.rs │ │ ├── doctor_schedule.rs │ │ ├── follow_up_task.rs │ │ ├── follow_up_record.rs │ │ ├── consultation_session.rs │ │ └── consultation_message.rs │ ├── service/ ← 业务逻辑 │ │ ├── mod.rs │ │ ├── patient_service.rs │ │ ├── health_data_service.rs │ │ ├── appointment_service.rs │ │ ├── follow_up_service.rs │ │ └── consultation_service.rs │ ├── handler/ ← Axum 路由 │ │ ├── mod.rs │ │ ├── patient_handler.rs │ │ ├── health_data_handler.rs │ │ ├── appointment_handler.rs │ │ ├── follow_up_handler.rs │ │ └── consultation_handler.rs │ ├── dto/ ← 请求/响应结构体 │ │ ├── mod.rs │ │ ├── patient_dto.rs │ │ ├── health_data_dto.rs │ │ ├── appointment_dto.rs │ │ ├── follow_up_dto.rs │ │ └── consultation_dto.rs │ └── event.rs ← 事件定义和处理器 ``` --- ## 8. 权限定义 ### 8.1 权限码 | 权限码 | 名称 | 说明 | |--------|------|------| | `health.patient.list` | 查看患者列表 | 查看和搜索患者列表、详情 | | `health.patient.manage` | 管理患者 | 创建、编辑、删除患者 | | `health.health-data.list` | 查看健康数据 | 查看体检记录、监测数据、化验报告 | | `health.health-data.manage` | 管理健康数据 | 录入、编辑、删除健康数据 | | `health.appointment.list` | 查看预约 | 查看预约列表和排班 | | `health.appointment.manage` | 管理预约 | 创建、确认、取消预约 | | `health.follow-up.list` | 查看随访 | 查看随访任务和记录 | | `health.follow-up.manage` | 管理随访 | 创建、分配、完成随访任务 | | `health.consultation.list` | 查看咨询 | 查看咨询会话和消息记录 | | `health.consultation.manage` | 管理咨询 | 关闭会话、导出记录 | | `health.doctor.list` | 查看医护 | 查看医护列表和详情 | | `health.doctor.manage` | 管理医护 | 创建、编辑医护档案、排班 | ### 8.2 数据范围 | 实体 | 支持的数据范围级别 | 说明 | |------|-------------------|------| | patient | self, department, department_tree, all | 医生只能看自己负责的患者或本科室患者 | | follow_up_task | self, department, department_tree, all | 医护只能看分配给自己的随访任务 | | appointment | self, department, department_tree, all | 按科室隔离预约数据 | ### 8.3 角色模板 | 角色 | 权限 | |------|------| | health_admin | 全部 health.* 权限 | | doctor | health.patient.list, health.health-data.*, health.appointment.list, health.follow-up.*, health.consultation.list, health.doctor.list | | nurse | health.patient.list, health.health-data.*, health.follow-up.*, health.appointment.list | | receptionist | health.patient.*, health.appointment.*, health.doctor.list | --- ## 9. 能力扩展 V1 需要新增以下基础能力(在 erp-core 或独立模块中): 1. **文件上传服务** — 文件存储(本地/OSS)、URL 生成、图片缩略图 2. **趋势分析** — 时序数据聚合、异常检测逻辑 3. **报告批注** — 医生对化验报告的解读/批注能力 4. **导出增强** — 健康数据导出为 Excel/PDF --- ## 10. 实施步骤 ### Phase 1: 项目初始化 - 拷贝 ERP 到 hms - 验证编译和构建 ### Phase 2: erp-health 骨架 - 创建 crate 结构 - 实现 ErpModule trait + `public_routes()` / `protected_routes()` 固有方法 - 注册到 workspace ### Phase 3: 数据库迁移 - 16 张表(14 业务实体 + 2 关联表)的迁移文件 - 索引创建、唯一约束 ### Phase 4: 业务逻辑(按域迭代) - ① 患者与医护管理 - ② 健康数据管理 - ③ 预约排班 - ④ 随访管理 - ⑤ 咨询管理 ### Phase 5: 前端页面 - 13 个自定义 React 页面 - 路由注册和侧边栏菜单 ### Phase 6: 集成测试 - API 端点测试 - 多租户隔离验证 - 端到端功能验证