Fix Bug #432: 根因+修复方案摘要

This commit is contained in:
关羽
2026-05-16 12:12:00 +08:00
parent 3b92d6bf08
commit dfe54e1b87

View File

@@ -0,0 +1,56 @@
# 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 为 NULL50%
- log_id=1852026-05-12无队列项encounter 有 order_id=328 → 回退路径应返回 pool=231, slot=4222但实际为空
- log_id=170/1682026-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