# 患者模块说明(`src/patients`) ## 1. 目标 - B 端:按组织与角色范围查询患者,并维护患者基础档案。 - B 端:支持患者首术录入、二次手术追加、旧设备弃用标记。 - 数据关系升级为 `Patient -> PatientSurgery -> Device -> TaskItem -> Task`。 - C 端:按 `phone + idCard` 做跨院生命周期聚合,返回手术事件与调压事件。 ## 2. 患者基础档案 患者表新增以下字段: - `inpatientNo`:住院号 - `projectName`:项目名称 - `phone`:联系电话 - `idCard`:身份证号原文 - `doctorId`:患者归属人员(医生/主任/组长) 说明: - `name` 仍然保留为患者姓名必填字段。 - `doctorId + hospitalId` 仍然是患者的组织归属来源,不直接绑定小组/科室。 - 手术表单中的 `原发病 / 脑积水类型 / 分流方式 / 近端穿刺区域 / 阀门植入部位 / 远端分流方向` 改为读取系统字典,不再前端硬编码。 ## 3. 手术档案 新增 `PatientSurgery` 表,每次手术保存: - `surgeryDate`:手术日期 - `surgeryName`:手术名称 - `surgeonId`:主刀医生账号 ID(自动等于患者归属医生) - `surgeonName`:主刀医生姓名快照 - `preOpPressure`:术前测压,可为空 - `primaryDisease`:原发病 - `hydrocephalusTypes`:脑积水类型,多选 - `previousShuntSurgeryDate`:上次分流手术时间,可为空 - `preOpMaterials`:术前 CT 影像/资料,保存为附件元数据数组 - `notes`:手术备注,可为空 返回时会自动补充: - `shuntSurgeryCount`:当前这台手术是该患者第几次分流手术 - `activeDeviceCount`:本次手术仍在用设备数 - `abandonedDeviceCount`:本次手术已弃用设备数 说明: - 新增/修改手术时,前端不再单独提交主刀医生。 - 后端会直接使用患者当前的 `doctorId` 作为 `surgeonId`,并保存当时的 `surgeonName` 快照。 - 如果后续患者归属医生发生变化,只会影响后续新建手术;历史手术仍保留创建当时的主刀医生快照。 ## 4. 植入设备 设备表仍沿用 `Device`,但语义改为“患者手术下植入的设备实例”。 新增/使用字段: - `implantCatalogId`:植入物型号字典 ID - `implantModel` / `implantManufacturer` / `implantName`:型号快照 - `isValve`:是否为阀门 - `isPressureAdjustable`:是否可调压 - `isAbandoned`:是否已弃用 - `shuntMode`:分流方式 - `proximalPunctureAreas`:近端穿刺区域,最多 2 个 - `valvePlacementSites`:阀门植入部位,最多 2 个 - `distalShuntDirection`:远端分流方向 - `initialPressure`:初始压力挡位标签,可为空 - `implantNotes`:植入物备注,可为空 - `labelImageUrl`:植入物标签图片地址,可为空 说明: - 患者手术里选择的是“全局植入物目录”,不是按医院单独维护的设备库。 - 同一个植入物目录可被多个患者手术重复绑定,患者侧保存的是目录快照。 - 旧设备弃用后,`TaskItem` 历史不会删除。 - 任务发布只允许选择 `ACTIVE + isPressureAdjustable=true + isAbandoned=false` 的设备。 - 同一患者一次手术可录入多个设备,因此支持“两个可调压仪器同时佩戴”。 - 管子/附件类型不会显示“阀门植入部位”和“初始压力”录入项。 - 如果植入物目录配置了挡位,`initialPressure` 必须取挡位中的字符串标签值,例如 `0.5 / 1 / 1.5 / 10 / 20 / 30`。 - 挡位标签保存前会自动标准化,例如 `01.0 -> 1`、`1.50 -> 1.5`。 - 手术创建时不允许手工录入 `currentPressure`,设备当前压力默认继承 `initialPressure`;发布调压任务时不会立刻改当前压力,只有工程师完成任务后才会更新。 - 术前资料与植入物标签现在支持直接上传;上传成功后,患者详情会按图片/视频做预览,不再只是裸链接。 ## 5. B 端可见性 - `DOCTOR`:仅可查自己名下患者 - `LEADER`:可查本组医生名下患者 - `DIRECTOR`:可查本科室医生名下患者 - `HOSPITAL_ADMIN`:可查本院全部患者 - `SYSTEM_ADMIN`:需显式传入目标 `hospitalId` ## 6. B 端接口 - `GET /b/patients`:按角色查询可见患者列表 - `GET /b/patients/doctors`:查询当前角色可见的归属人员候选 - `POST /b/patients`:创建患者,可选带 `initialSurgery` - `POST /b/patients/:id/surgeries`:为患者新增手术 - `GET /b/patients/:id`:查询患者详情 - `PATCH /b/patients/:id`:更新患者基础信息 - `DELETE /b/patients/:id`:删除患者 约束: - `PATCH /b/patients/:id` 不直接修改手术,手术必须走新增手术接口。 - 新增二次手术时可传 `abandonedDeviceIds`,后端会将这些旧设备标记为 `INACTIVE + isAbandoned=true`。 - 患者建档时会自动记录 `creator`,列表和详情都会返回创建人信息。 ## 7. C 端生命周期聚合 接口:`GET /c/patients/lifecycle?phone=...&idCard=...` 查询策略: 1. 不做医院隔离(跨租户) 2. 先将 `idCard` 做轻量标准化,再做双字段精确匹配 3. 聚合 `Patient -> PatientSurgery -> Device` 的手术事件 4. 聚合 `Patient -> Device -> TaskItem -> Task` 的调压事件 5. 全部事件按 `occurredAt DESC` 返回 事件类型: - `SURGERY` - `TASK_PRESSURE_ADJUSTMENT` 说明: - 生命周期中的 `initialPressure / currentPressure / oldPressure / targetPressure` 均返回字符串挡位标签。 ## 8. 响应结构 全部接口统一返回: - 成功:`{ code: 0, msg: "成功", data: ... }` - 失败:`{ code: x, msg: "中文错误", data: null }`