# Bug #401 分析报告 ## 根因分析 `div_log` 表中 `pool_id` 与 `slot_id` 存值为 NULL 的原因: ### 两条数据获取路径 1. **主路径**:从 `triage_queue_item` 获取 pool_id/slot_id(挂号时录入的号源信息,为权威来源) 2. **回退路径**:通过 `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 → 审计记录缺失 - 审计日志无法反映医生站的完诊操作 ### 修复方案 1. **移除 queueWasAlreadyCompleted 条件限制**:确保每次完诊操作都写入 div_log 审计记录 2. **增加分诊日志去重机制**:通过同一 encounter 在短时间内的 div_log 记录去重,而非简单跳过 3. **增强回退路径**:当 encounter 无 order_id 时,通过 encounter 关联的其他订单查找 slot 信息 ## 修复结果 ✅ 成功 | 18 行改动(+18/-16) **修复内容**:移除 `if (!queueWasAlreadyCompleted)` 条件限制,确保每次完诊都生成 div_log 审计记录。同时添加 `log.info` 用于追踪队列已由分诊台完诊时医生站补充写入审计日志的情况。 **影响范围**:`DoctorStationMainAppServiceImpl.completeEncounter()` 方法 **验证**:Maven 编译通过(BUILD SUCCESS)