Files
zyt/app/research/diagnosis_post_flow_audit.md
2026-08-11 09:12:51 +08:00

14 KiB
Raw Permalink Blame History

诊单视觉重构最终业务回归审计(三次终验)

  • 终验日期:2026-08-10
  • 范围:生产视频/IM、医生备注与日常记录 mutation、处方/订单、多挂号精确取消、诊单 Shell owner、列表 QR/日志/订单;并复核上一版已关闭的权限、DTO、隐私与 generation 项。
  • 基准:当前最新 Python 源码与测试,以及 D:/web/zyt/adminD:/web/zyt/server 的实际 admin 行为和服务端控制器/Logic。
  • 约束:只读业务终验;未安装依赖、未打包、未访问线上接口。除更新本报告外,未修改业务源码或测试。

最终结论

第三次终验后的剩余项为:

  • P00,明确无 P0。
  • P11 项 OPEN。 诊单列表“创建订单”已调用真实 order.order/create,但没有消费返回的 order_no 并调用现成的 generate_order_qrcodeadmin 的付款二维码闭环仍中断。
  • P22 项 OPEN。 一是日常矩阵不能编辑已有血糖/饮食/运动记录;二是视频回放只显示每条记录的第一个 URL,且没有 admin 的“向具体通话记录追加回放”入口。
  • 服务端不可实现限制:不计入 P0/P1/P2。 医生备注与跟踪备注的服务端契约只支持按当天追加;服务端没有任意旧正文覆盖或整条删除 endpoint,桌面端无法在不扩展后端的前提下实现这些动作。
  • 其余本轮复核项均 CLOSED:生产视频/IM 取数与同步、备注追加/附件、日常新增与待办、处方动作、订单详情/偏移、精确挂号取消、列表视频/确认 QR 与日志、真实 Shell 60%/move-resize/close generation。
  • 定向离线回归:128/128 passed
复核项 三次终验状态 最终等级 摘要
生产视频/IM only_archived、sync、上传、回放 OPEN(主体 CLOSED P2 生产接口、同步、工具栏上传和首个回放可用;多 URL 与指定 call-record 追加入口缺失
医生备注 mutation CLOSED 追加正文、上传舌象/报告、删除单附件均走真实合同;正文覆盖/整条删除属后端无 endpoint 限制
日常记录 mutation OPEN(新增 CLOSED P2 新增血糖/饮食/运动/跟踪备注及待办新增/取消可用;已有三类记录不能编辑
处方/详情订单动作 CLOSED 开方、处方查看、业务订单列表/详情与诊次偏移均真实落库/取数
多挂号精确取消 CLOSED 每个挂号卡携带精确 ID,最终调用 doctor.appointment/cancel
诊单 owner、60%、move-resize、generation CLOSED 每次打开重绑真实 Shell,宽度为 Shell 60%,移动/缩放/关闭同步且所有异步代次失效
列表 QR / 日志 / 创建订单 OPENQR/日志/创建主体 CLOSED P1 视频/确认 QR、日志、创建订单均真实调用;创建成功后的支付 QR 未接入 UI

上一版已关闭的 phonePlain、canonical diagnosis_typeviewOnly endpoint 分流、detail 失败禁存、身份证 15/18 位校验、权限 Tab 裁剪与隐私脱敏,本轮定向回归均未发现反弹。

逐项证据

1. 生产视频/IM[OPEN / P2,主体 CLOSED]

已关闭部分:

  • RemoteDoctorRepository 已实现生产 getCallRecords、手工 call record、附件关联及“上传 → 创建记录 → 关联”顺序:src/doctor_workstation/services/repository.py:1875-1943。这与 admin CallRecordPanel 的真实流程一致:D:/web/zyt/admin/src/views/tcm/diagnosis/components/CallRecordPanel.vue:109-180
  • IM 首次读取明确发 only_archived=1,同步走 triggerImChatSyncsrc/doctor_workstation/services/repository.py:1945-1965dialog 的 lazy 查询也固定 only_archived=Truesrc/doctor_workstation/ui/dialogs/diagnosis.py:2016-2038。admin 对照为 D:/web/zyt/admin/src/views/tcm/diagnosis/components/ImChatRecordPanel.vue:148-185
  • edit 态视频工具栏调用真实上传,成功后按 media generation 重新加载;聊天同步成功后延时重新读取归档:src/doctor_workstation/ui/dialogs/diagnosis.py:2541-2611。聊天图片/文件只能通过 HTTP(S) 安全打开::2652-2658
  • production/server 合同存在:D:/web/zyt/server/app/adminapi/controller/tcm/DiagnosisController.php:397-438:505-538;归档快路径在 D:/web/zyt/server/app/adminapi/logic/tcm/DiagnosisLogic.php:1015-1045

仍 OPEN 的 P2

  • 服务端返回 recording_urls_list 数组:D:/web/zyt/server/app/adminapi/logic/tcm/DiagnosisLogic.php:1810-1833;admin 把完整数组交给播放器,并在每个具体 call row 提供上传入口:D:/web/zyt/admin/src/views/tcm/diagnosis/components/CallRecordPanel.vue:30-72
  • Python _fill_video 只取 raw_urls[0],其余回放不可见,且视频表没有指定 call_record_id 的上传操作列:src/doctor_workstation/ui/dialogs/diagnosis.py:1126-1135:2844-2881。虽然 repository 已支持 call_record_idsrc/doctor_workstation/services/repository.py:1894-1913),UI 没有把它接出来。

该问题不造成错误写入,且工具栏上传与一个回放可用,故按 P2 而非 P1 计。

2. 医生备注:[CLOSED;后端限制已明确]

  • NotesTimeline 已暴露新增、上传、删除单附件与打开附件信号:src/doctor_workstation/ui/diagnosis_drawer.py:1804-1810:1820-1851:1887-1961dialog 绑定真实方法:src/doctor_workstation/ui/dialogs/diagnosis.py:989-997:2376-2487
  • production DTO 分别走 doctor.appointment/addDoctorNotedoctor.appointment/doctorNotesdoctor.appointment/deleteDoctorNoteImagesrc/doctor_workstation/services/repository.py:935-985。权限分别按新增与删除附件 endpoint 裁剪:src/doctor_workstation/ui/dialogs/diagnosis.py:478-483:1233-1241
  • admin 自身也只有追加、上传、删除单附件动作:D:/web/zyt/admin/src/views/patient/reception/components/NoteTimeline.vue:195-268API 定义仅三条:D:/web/zyt/admin/src/api/patient.ts:19-40

服务端不可实现边界:

  • controller 仅暴露 addDoctorNotedoctorNotesdeleteDoctorNoteImage,随后类即结束:D:/web/zyt/server/app/adminapi/controller/doctor/AppointmentController.php:168-198
  • DoctorNoteLogic::addOrAppend 对当天正文使用换行追加,不支持任意旧正文覆盖:D:/web/zyt/server/app/adminapi/logic/doctor/DoctorNoteLogic.php:12-76;唯一删除逻辑只删除附件数组中的单项::111-136

因此“任意旧笔记正文覆盖/整条删除”不是桌面端漏接已有合同,而是服务端没有 endpoint;本报告将其列为后端限制,不计客户端 P0/P1/P2

3. 日常记录:[OPEN / P2,新增 CLOSED]

已关闭部分:

  • edit 态已提供血糖、饮食、运动、跟踪备注新增按钮和待办新增/取消;只读态/无权限态隐藏:src/doctor_workstation/ui/diagnosis_drawer.py:1363-1371:1431-1450:1481-1511:1760-1791
  • dialog 将 signal 接到真实 add/todo repository,并为每次 mutation 使用 diagnosis-id + generation 校验后强制刷新:src/doctor_workstation/ui/dialogs/diagnosis.py:1089-1101:2175-2358
  • production 合同为 tcm.bloodRecord/addtcm.dietRecord/addtcm.exerciseRecord/addtcm.diagnosis/addTrackingNote、todo add/cancelsrc/doctor_workstation/services/repository.py:1745-1765:1778-1805:1847-1873

仍 OPEN 的 P2

  • admin 点击已有单元格时会把记录(含 id)放入表单,保存时分别调用 blood/diet/exercise editD:/web/zyt/admin/src/views/tcm/diagnosis/components/DailyMatrix.vue:921-1013
  • Python matrix 明确 NoEditTriggersNoSelection,只有 daily_add_requested,没有已有记录 edit signalsrc/doctor_workstation/ui/diagnosis_drawer.py:1366-1371:1455-1463。dialog 也只选择 add_*src/doctor_workstation/ui/dialogs/diagnosis.py:2260-2284
  • 这不是后端限制:production repository 已实现三类 editsrc/doctor_workstation/services/repository.py:1767-1776:1787-1796:1807-1818

跟踪备注例外:server 设计就是“仅给今天追加”。controller 仅有 add/listD:/web/zyt/server/app/adminapi/controller/tcm/DiagnosisController.php:180-214TrackingNoteLogic 只有 addOrAppend/getByDiagnosis,类在第 95 行结束:D:/web/zyt/server/app/adminapi/logic/tcm/TrackingNoteLogic.php:8-95。其任意旧正文覆盖/整条删除同样属于后端无 endpoint 限制,不计客户端问题。

4. 处方与详情订单动作:[CLOSED]

  • “开具处方”打开真实 PrescriptionEditorDialogaccepted 后调用 create_prescription,并携带 diagnosis/appointment/case snapshotsrc/doctor_workstation/ui/dialogs/diagnosis.py:2489-2539
  • 历史处方的“查看”打开真实 PrescriptionDetailDialog:2791-2842
  • 业务订单 lazy 列表、详情权限/真实 repository 门禁、异步 order generation 及详情 dialog 均已接通::1998-2000:2069-2074:2883-2991
  • 全局诊次偏移调用真实 setRevisitSlotStartOffset,并有独立 generation:2613-2650

未发现处方或详情订单的假动作/越权入口,本项 CLOSED

5. 多挂号精确取消:[CLOSED]

  • 每个可取消挂号卡按精确 primary key 生成按钮,signal 携带原 record 与该 appointment-idsrc/doctor_workstation/ui/diagnosis_index_widgets.py:150-163:1121-1148。歧义的行级“取消挂号”仍只在唯一挂号时出现::1403-1410
  • handler 选择当前诊单后再次按 ID 和状态校验,确认前后都防 stale,最终仅调用 exact capabilitysrc/doctor_workstation/ui/pages/consultations.py:1868-1921
  • production 方法明确走 doctor.appointment/cancel,不再误用患者工作区 endpoint:src/doctor_workstation/services/repository.py:1545-1555
  • 新测试覆盖两个挂号、超 32 位 appointment-id、错误诊单、状态刷新、权限/能力缺失与 canonical endpointtests/test_diagnosis_index_visual.py:340-379tests/test_consultations_parity_ui.py:610-774tests/test_diagnosis_detail_contract.py:90-105

本项 CLOSED

6. 真实 Shell owner / 60% / move-resize / generation[CLOSED]

  • _owner 不再在 page 构造期缓存;每次 open_for/showEvent 都从当前 parent.window() 重绑真实 Shellsrc/doctor_workstation/ui/dialogs/diagnosis.py:526-527:1314-1349:1398-1408
  • overlay 与 owner 同位置/尺寸,宽屏 drawer 固定为 owner 宽度 60%;监听 owner 的 Resize/Move/Show/Close:1283-1299:1351-1371
  • reject/done 及 owner Close 会使 detail/save/orders/order-detail/daily/notes/media/offset/所有 lazy-tab generation 全部失效::1373-1383:1681-1700

真实 ShellWindow -> QStackedWidget -> ConsultationsPage -> cached DiagnosisDialog offscreen 探针结果:

OPEN  owner_shell=True shell=(1200,760) dialog=(1200,760) panel=720 expected=720 pos=(80,60)
MOVED shell=(1024,650) dialog=(1024,650) panel=614 expected=614 pos=(190,140)
CLOSE visible=False generation=True media=True

本项 CLOSED。现有 tests/test_diagnosis_drawer_visual.py:837-861 仍只用直接顶层 owner;本次额外真实 Shell 探针补足了业务终验,但建议后续把该探针固化成回归测试。

7. 列表 QR / 日志 / 订单:[OPEN / P1,主体 CLOSED]

已关闭部分:

  • 页面只在 canonical 权限与真实 repository 方法同时存在时展示视频 QR、确认 QR、日志、订单入口:src/doctor_workstation/ui/pages/consultations.py:704-715:1005-1030
  • QR DTO 校验 patient/doctor/share-user/diagnosis,日志使用 diagnosis-id,所有菜单请求均受 selection generation 保护::1972-2091
  • production repository 真实调用 generateMiniProgramQrcodeguahaoLogListorder.order/createsrc/doctor_workstation/services/repository.py:1967-2060。测试验证 exact DTO、权限裁剪与 stale callbacktests/test_diagnosis_detail_contract.py:85-127tests/test_consultations_parity_ui.py:777-958

仍 OPEN 的 P1

  • admin 创建订单成功后读取 order_no,立即调用 generateOrderQrcode 并展示付款 QRD:/web/zyt/admin/src/views/tcm/diagnosis/index.vue:1474-1509
  • Python _create_diagnosis_order 把真实 create 放进通用 _run_mutation;该 helper 丢弃 _result,只 toast + refresh,因此永远不会生成付款 QR:src/doctor_workstation/ui/pages/consultations.py:2093-2128:2460-2479
  • repository 明明已有 generate_order_qrcodesrc/doctor_workstation/services/repository.py:2062-2076,但 UI 源码没有任何调用。现有测试也只分别测试“UI 创建订单”和“repository 可生成 QR”,未覆盖两者串联:tests/test_consultations_parity_ui.py:777-872tests/test_diagnosis_detail_contract.py:88-89

订单已实际创建却不展示付款入口,用户容易停在半完成状态或重复建单;这是主流程闭环缺失,按 P1 OPEN 计。

离线验证记录

使用项目现有 .venv,设置 QT_QPA_PLATFORM=offscreenPYTHONDONTWRITEBYTECODE=1,禁用 pytest cache,并把 basetemp 放在系统临时目录;未安装任何依赖:

pytest -q -p no:cacheprovider \
  tests/test_diagnosis_detail_contract.py \
  tests/test_diagnosis_index_visual.py \
  tests/test_diagnosis_drawer_visual.py \
  tests/test_appointment_drawer_visual.py \
  tests/test_consultations_parity_ui.py \
  tests/test_prescription_security_ui.py \
  tests/test_patients_ui.py \
  tests/test_repository_parity.py \
  tests/test_permissions.py

128 passed

测试退出码为 0--collect-only -q 分文件计数合计 128。另执行了上述真实 Shell owner 探针,退出码为 0。

发布判断

当前不存在错误 endpoint、歧义挂号取消、权限泄漏、隐私明文回流或关闭后旧异步回调落地等 P0 风险。生产视频/IM、备注追加、日常新增、处方、订单详情及列表主要动作均已从“假动作/未接入”进展为真实 repository 行为。

但若发布标准是“完整保留 admin 的订单支付闭环与所有已存在的数据编辑/回放能力”,当前仍不满足:剩余 P0 0 / P1 1 / P2 2。其中任意旧医生/跟踪笔记正文覆盖或整条删除必须先扩展 server endpoint,不能作为桌面端单独修复项。