242 lines
21 KiB
Markdown
242 lines
21 KiB
Markdown
# AI 对话/报告直接开方链路审计(2026-08-21)
|
||
|
||
## 结论
|
||
|
||
**当前不能从 AI 的回答或 AI 报告“一键形成并提交处方”。** 当前工作树实现的是另一条链路:医生在 AI 对话框输入一条明确的本地命令(如“开个处方”),桌面端不请求 AI,而是重新核对诊单/患者后打开通用处方编辑器;医生仍需人工填写药材、剂量、用法和手写签名,点击确认后才调用真实创建接口,服务端保存为 `audit_status = 0` 的待审核处方。
|
||
|
||
因此应区分三种能力:
|
||
|
||
| 能力 | 当前状态 | 判断 |
|
||
|---|---|---|
|
||
| AI 输出诊断/风险/用药建议文本 | 已有 | 助手返回 `answer` 文本;结构化分析仅有诊断建议、风险和治疗建议 |
|
||
| 从 AI 对话入口手工新建并提交待审核处方 | 部分可用 | 输入特定命令可打开编辑器,人工完成后调用 `tcm.prescription/add` |
|
||
| 把 AI 生成的药味、剂量、用法直接转换成处方草稿/一键提交 | 不存在 | 无处方草稿 schema、无 AI 结果到编辑器的字段映射、无“采用为处方”按钮,也无服务端 AI 开方接口 |
|
||
| AI 直接生成已审核/生效处方 | 不存在,且不应建设成无人工复核链路 | 创建接口强制待审核;审核由独立权限和角色控制 |
|
||
|
||
## 审计范围与验证
|
||
|
||
- 审计当前工作树中的桌面端 Python/PySide6、repository/API、PHP controller/logic/validate、权限及数据绑定。
|
||
- 未修改生产代码或测试,只新增本报告。
|
||
- 已运行:`uv run pytest tests/test_ai_consult_ui.py tests/test_prescription_ui.py -q`,67 项通过。
|
||
- 已运行:`DiagnosisAiAssistantContractTest.php`、`DiagnosisAiAssistantStreamContractTest.php`、`DiagnosisWorkspaceRowAuthorizationTest.php`,均通过。
|
||
- 仓库根目录没有 AGENTS.md 声明的 `.trellis/workflow.md` 和 `.trellis/spec/`,故无法应用缺失的 Trellis 分层规范;本报告按现有实现和测试取证。
|
||
|
||
## 端到端链路
|
||
|
||
### 1. AI 返回结构:只能给建议,不能形成处方 DTO
|
||
|
||
服务端病例助手的返回契约只有 `answer/model_key/model_label/model_name/task`,其中 `answer` 是清洗后的纯文本;没有 `herbs`、`medicine_id`、`dosage`、`usage_*` 或可执行 action。证据:
|
||
|
||
- `server/app/adminapi/logic/tcm/DiagnosisAiLogic.php:276-307`:助手调用上游并交给 `formatAssistantResult()`。
|
||
- `server/app/adminapi/logic/tcm/DiagnosisAiLogic.php:419-437`:最终响应只有 `answer` 和模型/任务元数据。
|
||
- `server/app/adminapi/logic/tcm/DiagnosisAiLogic.php:64-104`:`prescription_review` 仅定义为“分析处方/用药并提示复核重点”,不是生成处方。
|
||
- `server/app/adminapi/logic/tcm/DiagnosisAiLogic.php:1084-1106`:提示词要求“简洁、分点的专业回答”和执业医师复核,没有处方 JSON schema。
|
||
|
||
另一路结构化 `aiAnalysis` 也只能返回 `diagnosis_advice`、`risk_assessment`、`treatment_advice`:
|
||
|
||
- `server/app/adminapi/logic/tcm/DiagnosisAiLogic.php:1035-1069`:模型被要求输出的唯一 JSON schema 不包含处方字段。
|
||
- `server/app/adminapi/logic/tcm/DiagnosisAiLogic.php:1281-1352`:解析器严格只接受上述三类业务字段。
|
||
|
||
桌面端流式处理也只拼接 `delta.text` 并渲染答案,不解析处方动作或草稿:
|
||
|
||
- `app/src/doctor_workstation/ui/dialogs/ai_consult.py:5243-5282`:`start/delta/done` 只更新文本和模型标签。
|
||
- `app/src/doctor_workstation/ui/dialogs/ai_consult.py:5284-5289`:流式片段直接拼成 `_stream_text`。
|
||
|
||
### 2. 桌面 AI UI:有“命令开编辑器”,没有“AI 结果转处方”
|
||
|
||
AI 入口和患者选择已接通:
|
||
|
||
- `app/src/doctor_workstation/ui/shell.py:1103-1122,1551-1565`:有全局“AI 助手/开始对话”入口,并先进入患者诊单选择器。
|
||
- `app/src/doctor_workstation/ui/dialogs/ai_consult_picker.py:57-119`:选择对象分别保存 `diagnosis_id` 与 `source_patient_id`,不会把诊单主键误当患者主键,只保留掩码手机号。
|
||
- `app/src/doctor_workstation/ui/dialogs/ai_consult_picker.py:274-298,390-419`:通过专用 repository 拉取权限范围内诊单,再携带诊单/患者上下文打开 AI 工作区。
|
||
|
||
所谓“开方”实际是本地意图拦截:
|
||
|
||
- `app/src/doctor_workstation/ui/dialogs/ai_consult.py:2931-2967`:仅识别不超过 24 字的明确命令;带“怎么/是否/建议/分析/复核/审核”等词时不会触发。
|
||
- `app/src/doctor_workstation/ui/dialogs/ai_consult.py:5171-5179`:本地动作发生在 `_compose_ai_prompt()` 和 AI worker 之前,命中后直接返回,不会调用模型。
|
||
- `app/src/doctor_workstation/ui/dialogs/ai_consult.py:4881-4919`:本地检查 `tcm.diagnosis/chufang` 或 `tcm.diagnosis/kaifang`,再开始诊单核对。
|
||
- `app/src/doctor_workstation/ui/dialogs/ai_consult.py:4921-5001`:重新读取只读诊单详情,严格比对诊单 ID 和当前会话患者 ID。
|
||
- `app/src/doctor_workstation/ui/dialogs/ai_consult.py:5003-5044`:仅从权威诊单构造患者/诊断种子,没有从 AI 答案提取药材。
|
||
- `app/src/doctor_workstation/ui/dialogs/ai_consult.py:5055-5105`:打开通用 `PrescriptionEditorDialog`;只有对话框返回 Accepted 后才调用 `create_prescription`。
|
||
|
||
这意味着:
|
||
|
||
- 输入“怎么开方更合理”会得到 AI 文本建议,但该回答没有“采用为处方”入口。
|
||
- 输入“开个处方”不会让 AI 开方,只会打开人工编辑器。
|
||
- 即便在命令里写药名和剂量,当前代码也不会解析或带入编辑器。
|
||
- UI 没有可发现的“开方”快捷按钮;现有快捷指令都是病情总结、用药建议、检查建议等(`app/src/doctor_workstation/ui/dialogs/ai_consult.py:762-783,3189-3215`)。
|
||
|
||
### 3. 人工编辑与提交:接口已复用,但仍是完整人工处方流程
|
||
|
||
通用处方编辑器可复用程度较高:
|
||
|
||
- `app/src/doctor_workstation/ui/dialogs/prescription.py:2652-2765`:完整新增/编辑处方表单。
|
||
- `app/src/doctor_workstation/ui/dialogs/prescription.py:2910-3007`:患者、诊断、诊单提示等表单字段。
|
||
- `app/src/doctor_workstation/ui/dialogs/prescription.py:3015-3042`:可从处方库或文本导入药材;这不是 AI 回答映射。
|
||
- `app/src/doctor_workstation/ui/dialogs/prescription.py:3205-3227`:医师姓名和手写签名是必填 UI。
|
||
- `app/src/doctor_workstation/ui/dialogs/prescription.py:3770-3831`:提交前校验患者、临床诊断、医师、手写签名、至少一味药材、药材主数据选择和正剂量。
|
||
|
||
repository/API 已接真实端点:
|
||
|
||
- `app/src/doctor_workstation/services/repository.py:1563-1572`:`create_prescription()` POST `tcm.prescription/add`。
|
||
- `app/src/doctor_workstation/services/repository.py:1574-1593`:`update_prescription()` POST `tcm.prescription/edit`。
|
||
- `app/src/doctor_workstation/services/repository.py:1643-1649`:按诊单刷新 `tcm.prescription/listByDiagnosis`。
|
||
- `app/src/doctor_workstation/services/repository.py:3249-3279`:repository 只做浅层 DTO 规范化,不承担患者/诊单一致性校验。
|
||
|
||
### 4. 服务端创建与审核:创建即待审,不等于审核通过
|
||
|
||
服务端创建流程已有一些正确的安全边界:
|
||
|
||
- `server/app/adminapi/controller/tcm/PrescriptionController.php:27-35`:控制器忽略客户端 `creator_id`,以当前 `$adminId` 调用创建逻辑。
|
||
- `server/app/adminapi/logic/tcm/PrescriptionLogic.php:220-245`:限制同诊单、同开方人、同日只能有一张未作废处方。
|
||
- `server/app/adminapi/logic/tcm/PrescriptionLogic.php:268-278`:要求药材数组并通过药材主数据解析。
|
||
- `server/app/adminapi/logic/tcm/PrescriptionLogic.php:332-340`:忽略客户端审核状态,强制 `audit_status = 0`,创建人与诊单医助由服务端写入。
|
||
|
||
“提交审核”只是保存一条待审核记录;AI 链路不会调用审核接口。真正审核是独立动作:
|
||
|
||
- `server/app/adminapi/controller/tcm/PrescriptionController.php:102-129`:审核需另行调用 `audit`。
|
||
- `server/app/adminapi/logic/tcm/PrescriptionLogic.php:55-73,796-840`:审核还需允许角色、对象可见性和待审状态;通过后才变为 `audit_status = 1`。
|
||
|
||
## 主要缺口与风险
|
||
|
||
### P1 / 高:创建接口没有诊单写权限和行级数据域校验
|
||
|
||
`PrescriptionLogic::add()` 在有 `diagnosis_id` 时只做 `Diagnosis::find()` 存在性检查,没有复用 `DiagnosisLogic::canManageDiagnosis()` 或 `canViewReadonlyDiagnosis()`,controller 也没有传入 `$adminInfo`:
|
||
|
||
- `server/app/adminapi/controller/tcm/PrescriptionController.php:27-35`
|
||
- `server/app/adminapi/logic/tcm/PrescriptionLogic.php:251-266`
|
||
- 可复用的写权限入口已经存在于 `server/app/adminapi/logic/tcm/DiagnosisLogic.php:4458-4468`。
|
||
|
||
桌面 AI 流程虽然会先走只读详情并做客户端 ID 比对,但这不是服务端写操作授权。调用者只要能到达 `tcm.prescription/add`,就可能对一个仅知道 ID、但不在其可管理范围内的诊单创建处方。医疗数据完整性和越权写入风险都应由服务端兜底。
|
||
|
||
**建议:** `add()` 接收 `$adminInfo`,在任何读取患者/预约信息和写入前调用 `DiagnosisLogic::canManageDiagnosis($diagnosisId, $adminId, $adminInfo)`;不存在和越权统一报错,避免枚举。AI 页面可继续保留客户端核对作为 UX 防误操作,但不能代替服务端鉴权。
|
||
|
||
### P1 / 高:诊单、预约、患者和患者快照没有权威一致性校验
|
||
|
||
创建逻辑只验证诊单存在,随后直接信任客户端提交的 `appointment_id`、`patient_id`、`patient_name`、`phone` 和病例快照:
|
||
|
||
- `server/app/adminapi/logic/tcm/PrescriptionLogic.php:251-260`:只查诊单是否存在。
|
||
- `server/app/adminapi/logic/tcm/PrescriptionLogic.php:291-315`:诊单、预约、患者 ID 和患者快照直接来自 `$params`。
|
||
- `server/database/migrations/create_tcm_prescription.sql:5-7,27-31`:三个关系字段只有普通索引,没有外键约束。
|
||
|
||
因此直接 API 请求可构造“诊单 A + 预约 B + 患者 C + 姓名 D”的处方。即便 UI 正常使用,也存在下一项实际丢字段问题。
|
||
|
||
**建议:** 创建时仅接受 `diagnosis_id` 和处方临床字段;由服务端基于授权诊单解析并写入 `appointment_id/patient_id/patient_name/phone/gender/age`,对病例快照使用服务端当前诊单生成。若必须允许修正患者打印信息,应走现有独立 `patchPatient` 权限和审计链路。
|
||
|
||
### P1 / 高:桌面处方编辑器会丢失 `patient_id` 和 `phone`
|
||
|
||
AI 入口的种子包含患者 ID 和电话:
|
||
|
||
- `app/src/doctor_workstation/ui/dialogs/ai_consult.py:5021-5030`
|
||
|
||
但 `PrescriptionEditorDialog.payload()` 的保留字段没有 `patient_id`、`appointment_id`、`phone`、`case_record`,表单输出也没有这些字段:
|
||
|
||
- `app/src/doctor_workstation/ui/dialogs/prescription.py:3692-3758`
|
||
- 领域模型 `Prescription` 本身也没有 `patient_id` 字段:`app/src/doctor_workstation/core/models.py:577-588`。
|
||
|
||
AI 流程在确认后只强制补回 `diagnosis_id`、`appointment_id` 和 `case_record`,没有补回 `patient_id` 或 `phone`:
|
||
|
||
- `app/src/doctor_workstation/ui/dialogs/ai_consult.py:5078-5093`
|
||
|
||
服务端对缺失值使用 `patient_id = 0`、`phone = ''`:
|
||
|
||
- `server/app/adminapi/logic/tcm/PrescriptionLogic.php:300-307`
|
||
|
||
所以从 AI 对话新建的处方虽然能按 `diagnosis_id` 找到,但患者 ID/手机号快照会为空。诊单详情里的既有手工开方流程采用同样的 payload 回填方式,也有同类问题(`app/src/doctor_workstation/ui/dialogs/diagnosis.py:3085-3104,3117-3127`)。
|
||
|
||
现有 AI UI 测试只断言强制回填了诊单、预约和病例快照,没有断言 `patient_id/phone`:`app/tests/test_ai_consult_ui.py:293-305`。
|
||
|
||
**建议:** 短期在编辑器 DTO 中不可编辑地保留 `patient_id/phone/appointment_id/case_record` 并补测试;最终仍应由服务端从诊单权威派生,避免信任客户端快照。
|
||
|
||
### P1 / 高:编辑接口允许关系漂移,且共享处方的对象级编辑边界过宽
|
||
|
||
服务端编辑时允许客户端提供新的 `diagnosis_id`,但没有验证新诊单存在、调用者能管理新诊单,也不会同步/校验 `patient_id`、`appointment_id` 和 `phone`:
|
||
|
||
- `server/app/adminapi/logic/tcm/PrescriptionLogic.php:388-425`:新诊单 ID 用于唯一性检查,但没有授权/存在性检查。
|
||
- `server/app/adminapi/logic/tcm/PrescriptionLogic.php:438-485`:保存新 `diagnosis_id`,患者 ID、预约 ID、电话和病例快照不在更新集合中。
|
||
|
||
同时对象级编辑规则是“创建者或 `is_shared = 1`”,即任何能到达编辑端点的用户都可编辑共享处方:`server/app/adminapi/logic/tcm/PrescriptionLogic.php:408-412`。这会让处方既可能被重新绑定到其他诊单,又可能保留旧患者关系字段。
|
||
|
||
**建议:** 编辑禁止修改关系字段;若确需迁移,使用专用、强审计接口并同时校验新诊单写权限和重建全部患者快照。共享应只扩大读取范围,不应自动扩大编辑权。
|
||
|
||
### P1 / 高(部署相关):桌面权限码与真实 API 路由没有统一的服务端别名契约
|
||
|
||
AI UI 以 `tcm.diagnosis/chufang` 或 `tcm.diagnosis/kaifang` 判断可开方(`app/src/doctor_workstation/ui/dialogs/ai_consult.py:4891-4901`),独立已开处方页则使用 `cf.prescription/add|edit`(`app/src/doctor_workstation/ui/pages/prescriptions.py:558-565,676-683`),但 repository 最终调用的是 `tcm.prescription/add|edit`。
|
||
|
||
`AuthMiddleware` 的通用规则是:如果真实路由不在全量菜单 URI 中就直接放行;若已注册则要求真实路由或显式别名:
|
||
|
||
- `server/app/adminapi/http/middleware/AuthMiddleware.php:70-92`
|
||
- 现有别名仅为“处方库列表导入”覆盖多套权限,不包含 `tcm.prescription/add|edit` 的开方别名:`server/app/adminapi/http/middleware/AuthMiddleware.php:169-202`。
|
||
|
||
本仓库没有找到为 `tcm.prescription/add|edit` 注册并分配权限的版本化 SQL,故实际安全性依赖部署数据库里是否已有旧菜单记录:
|
||
|
||
- 若未注册,middleware 的第 77-82 行会 fail-open。
|
||
- 若注册但未分配真实路由,拥有 `chufang/kaifang/cf.prescription/add` 的桌面用户可能被 403。
|
||
|
||
**建议:** 选择一套 canonical 权限,版本化注册真实路由,并在 middleware 对兼容码做双向、可测试的精确别名;未知业务写路由应 fail-closed,而不是因为未注册就绕过鉴权。
|
||
|
||
### P2 / 中:AI “开方命令”不可发现,且会丢弃命令中的处方内容
|
||
|
||
界面没有开方快捷按钮或“采用为处方”CTA;只有文本意图正则。命中后清空输入并进入本地编辑流程(`app/src/doctor_workstation/ui/dialogs/ai_consult.py:4881-4889`),未保存原命令里的药味、剂量或 AI 建议。用户容易误解为 AI 已生成处方,实际看到的是诊单预填的空药材表单。
|
||
|
||
**建议:** AI 答案与本地命令分离。提供明确的“生成处方草稿”与“采用草稿”按钮,展示字段来源、缺失项和风险提示;任何药材/剂量进入正式表单前都需医生逐项确认。
|
||
|
||
### P2 / 中:医师显示名和签名缺少服务端身份约束
|
||
|
||
编辑器预填当前用户姓名,但姓名仍可编辑,签名由客户端 data URL 提交(`app/src/doctor_workstation/ui/dialogs/prescription.py:3205-3227,3349-3355,3740-3741`);服务端虽然强制 `creator_id = $adminId`,却直接保存客户端 `doctor_name/doctor_signature`(`server/app/adminapi/logic/tcm/PrescriptionLogic.php:327-339`)。待审核机制降低了风险,但不能防止错误/冒用的签名快照进入系统。
|
||
|
||
**建议:** 医师显示名由 authenticated profile 派生;签名使用账号绑定的签名资产或至少保存签名来源、哈希、提交人、时间和确认事件,不接受 AI 生成签名。
|
||
|
||
### P2 / 中:删除、作废的对象级服务端授权也不完整
|
||
|
||
虽不是 AI 新建的主路径,但同一处方生命周期中:
|
||
|
||
- `delete()` 未接收当前管理员,也没有创建者/共享/可见性检查:`server/app/adminapi/logic/tcm/PrescriptionLogic.php:636-675`。
|
||
- `void()` 接收管理员仅用于记录作废人,没有对象级授权:`server/app/adminapi/logic/tcm/PrescriptionLogic.php:1137-1178`。
|
||
|
||
如果路由权限配置漂移或范围过宽,可能修改他人处方。建议所有写操作统一通过同一个处方对象授权策略。
|
||
|
||
## 可直接复用的接口和组件
|
||
|
||
| 层 | 可复用能力 | 证据 / 用途 |
|
||
|---|---|---|
|
||
| AI 患者选择 | `list_ai_patient_options` / `tcm.diagnosis/aiPatientOptions` | `app/src/doctor_workstation/services/repository.py:2029-2044`;用于只暴露数据域内、脱敏的诊单目标 |
|
||
| 诊单权威读取 | `get_diagnosis_detail(..., readonly=True)` / `readonlyDetail` | `app/src/doctor_workstation/services/repository.py:2046-2060`;服务端在 `server/app/adminapi/logic/tcm/DiagnosisLogic.php:4362-4412` 做行级只读授权 |
|
||
| AI 问答 | `stream_diagnosis_ai` / `aiAssistantStream` | `app/src/doctor_workstation/services/repository.py:1373-1405`;适合继续提供解释,不应直接作为可执行处方 DTO |
|
||
| 人工处方编辑 | `PrescriptionEditorDialog` | 已有主数据药材选择、剂量、用法、签名和本地校验,可作为 AI 草稿的人工复核容器 |
|
||
| 药材主数据 | `doctor.medicine/lists` + `RemoteMedicineComboBox` | `app/src/doctor_workstation/ui/dialogs/prescription.py:1425-1536`;AI 草稿必须解析为有效 `medicine_id` |
|
||
| 处方提交 | `create_prescription` / `tcm.prescription/add` | 可复用,但应先补服务端诊单写授权和权威关系派生 |
|
||
| 处方刷新 | `list_prescriptions_by_diagnosis` | 创建成功后已能按当前诊单刷新并过滤归属 |
|
||
| 服务端药材校验 | `normalizeHerbIdentities()` | `server/app/adminapi/logic/tcm/PrescriptionLogic.php:165-175`;AI 草稿落表前必须复用 |
|
||
| 服务端重复控制 | `assertUniquePrescriptionPerDiagnosisDay()` | `server/app/adminapi/logic/tcm/PrescriptionLogic.php:220-245` |
|
||
| 诊单写授权 | `DiagnosisLogic::canManageDiagnosis()` | `server/app/adminapi/logic/tcm/DiagnosisLogic.php:4458-4468`;应接入处方 add/edit |
|
||
| 审核 | `PrescriptionLogic::audit()` | 保留独立人工审核,不与 AI 生成合并 |
|
||
|
||
## 推荐目标链路
|
||
|
||
不建议把“AI 可以直接给患者开方”实现为模型静默调用创建接口。更安全且可交付的目标是“AI 生成结构化草稿,医生确认并签名,服务端权威绑定,进入独立审核”。
|
||
|
||
1. 新增只读草稿能力:AI 返回 `prescription_draft`,至少包含 `clinical_diagnosis`、主/辅方药材(`medicine_id/name/dosage/formula_type`)、剂数、用法、禁忌、生成依据、缺失信息和风险警示;不得包含可自行决定的患者/诊单/医生身份字段。
|
||
2. 服务端严格解析草稿:使用药材主数据解析、剂量范围、重复药名、特殊人群/相互作用规则;无法解析的草稿只作为文本展示。
|
||
3. UI 显示“采用为处方草稿”,而不是“直接提交”;逐字段标记“AI 建议/诊单原值/医生修改”,打开现有 `PrescriptionEditorDialog`。
|
||
4. 医生必须人工复核、补齐必填项并手写/绑定签名;确认页明确显示“将创建待审核处方”。
|
||
5. 创建接口仅接收授权 `diagnosis_id` 和临床处方字段;患者、预约、医生身份、病例快照全部由服务端权威派生,并在事务内校验诊单写权限与唯一性。
|
||
6. 审核继续使用独立角色/权限;AI 生成标记、模型、prompt 版本、草稿哈希、采用人和修改差异写审计日志。
|
||
|
||
## 建议补充的最小测试集
|
||
|
||
1. AI `done` 事件的合法/非法 `prescription_draft` schema、超量药材、无 `medicine_id`、负剂量和重复药名。
|
||
2. “AI 建议 → 采用草稿 → 人工修改 → 签名 → 创建待审”端到端桌面测试。
|
||
3. AI 创建 payload 必须包含当前诊单,并由服务端返回的处方断言 `diagnosis_id/appointment_id/patient_id` 一致。
|
||
4. 任意其他诊单 ID、跨数据域诊单、错配预约/患者 ID 的创建请求必须失败。
|
||
5. 编辑请求尝试修改 `diagnosis_id/patient_id/appointment_id` 必须失败。
|
||
6. 只有读取权限、只有 AI 权限、只有 `cf.prescription/add`、只有 `chufang/kaifang` 的权限矩阵测试,并覆盖 middleware 菜单已注册/未注册两种状态。
|
||
7. 创建后必须仍为待审核;没有审核权限的创建者不能把处方变为已通过。
|
||
8. 共享处方仅扩大读取范围,非创建者不能编辑、删除或作废。
|
||
|
||
## 最终判断
|
||
|
||
- **问:目前能否从 AI 对话/报告一键形成并提交处方?答:不能。**
|
||
- **问:能否在 AI 对话窗口里用一句“开方”命令进入处方流程,并在人工填写/签名后创建待审核处方?答:当前工作树可以。**
|
||
- **问:这条半自动链路是否已达到可安全上线的端到端闭环?答:尚未。** 服务端诊单写授权、患者/预约权威绑定、权限 canonical 化和患者字段丢失问题应先修复;之后再建设“AI 结构化草稿 → 医生确认 → 待审核”的链路。
|