2.8 KiB
2.8 KiB
Bug #401 分析报告
根因分析
div_log 表中 pool_id 与 slot_id 存值为 NULL 的原因:
两条数据获取路径
- 主路径:从
triage_queue_item获取 pool_id/slot_id(挂号时录入的号源信息,为权威来源) - 回退路径:通过
encounter.order_id → order_main.slot_id → adm_schedule_slot.pool_id获取
失败场景
当两条路径均失败时,div_log 记录写入 NULL 值:
- 场景A:患者未经过分诊队列(如直接挂号就诊),
triage_queue_item不存在 - 场景B:
triage_queue_item存在但 pool_id/slot_id 为 NULL(前端未传递号源信息),且 encounter 无 order_id
数据库现状
12 条 COMPLETE 记录中有 6 条 pool_id/slot_id 为 NULL(50%):
- log_id=185(2026-05-12):无队列项,encounter 有 order_id=328 → 回退路径应返回 pool=231, slot=4222,但实际为空
- log_id=170/168(2026-05-09):队列项存在 pool=223/slot=3981,但 div_log 为空
- log_id=164/162/159:多条队列项均有 pool/slot,但 div_log 为空
历史原因:2026-05-13 之前的代码版本中,回退路径的查询条件有缺陷(SecurityUtils.getLoginUser().getTenantId() 与队列项 tenant_id 不匹配),导致回退查询失败。
现有修复回顾
| 提交 | 日期 | 修复内容 |
|---|---|---|
af0a0957 |
05-13 10:15 | 添加回退路径(queueItem → encounter→order→slot) |
fc1ed6c4 |
05-13 14:06 | 回退路径从 else-if 改为独立 if |
96102e8b |
05-13 23:27 | 添加 queueAlreadyCompleted 检查防重复写入 |
164ac604 |
05-14 08:51 | 修复 queueAlreadyCompleted 竞态条件 |
当前代码仍存在的问题
queueWasAlreadyCompleted 检查虽然修复了竞态条件,但引入了新的问题:当队列项已是 COMPLETED 状态时,div_log 完全不写入。这导致:
- 分诊台操作已完诊的患者 → 医生站完诊不写 div_log → 审计记录缺失
- 审计日志无法反映医生站的完诊操作
修复方案
- 移除 queueWasAlreadyCompleted 条件限制:确保每次完诊操作都写入 div_log 审计记录
- 增加分诊日志去重机制:通过同一 encounter 在短时间内的 div_log 记录去重,而非简单跳过
- 增强回退路径:当 encounter 无 order_id 时,通过 encounter 关联的其他订单查找 slot 信息
修复结果
✅ 成功 | 18 行改动(+18/-16)
修复内容:移除 if (!queueWasAlreadyCompleted) 条件限制,确保每次完诊都生成 div_log 审计记录。同时添加 log.info 用于追踪队列已由分诊台完诊时医生站补充写入审计日志的情况。
影响范围:DoctorStationMainAppServiceImpl.completeEncounter() 方法
验证:Maven 编译通过(BUILD SUCCESS)