Files
his/MD/bugs/BUG_764_ANALYSIS.md

122 lines
6.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Bug #764 诸葛亮分析报告
> **文档类型**: Bug分析
> **分析时间**: 2026-06-12 16:05:34
> **分析模型**: mimo-v2.5 (LLM深度分析)
---
## 基本信息
- **Bug #**: 764
- **标题**: [门诊医生工作站-检验] 已维护诊疗项目的检验项目“肾功能5项”在开立保存时报错“未找到对应的诊疗定义”
- **模块**: 门诊医生工作站
- **提出人**: 陈显精
---
Now I have a complete understanding of the bug. Let me output the analysis.
---
### 一、Bug 理解
用户在门诊医生工作站选择检验项目"肾功能5项"并点击保存时,系统报错"未找到检验项目 '肾功能5项' 对应的诊疗定义"。该检验项目已在后台正确维护,期望保存成功并自动联动生成门诊医嘱记录。
### 二、根因分析
**根因**`DoctorStationLabApplyServiceImpl.java` 的检验申请保存方法包含两个阶段:
1. **阶段一(保存申请单明细)**:正确使用 `labActivityDefinitionService.getById(activityId)``lab_activity_definition` 表查询检验项目定义第182行
2. **阶段二(自动创建门诊医嘱)****错误地**调用 `activityDefinitionService.getAppointActivityDefinitionId(itemName)`,该方法按名称精确匹配 `wor_activity_definition`SQL: `WHERE NAME = #{activityName}`)。
**关键问题**:检验项目(如"肾功能5项")存储在独立的 `lab_activity_definition` 表中,**不存在于** `wor_activity_definition` 表中。按名称查询 `wor_activity_definition` 必然返回 null触发 RuntimeException。
**对比参考**`ExamApplyController`(检查申请)已正确处理类似情况——使用 `activityId = 0L` 占位,不依赖 `wor_activity_definition`第224行注释"检查申请不走诊疗定义设置为0占位")。
**涉及文件**
- `DoctorStationLabApplyServiceImpl.java:254-259` — 查询逻辑错误(根因)
- `ActivityDefinitionMapper.xml:7-13` — SQL 查询 `wor_activity_definition` by name
- `ActivityDefinitionServiceImpl.java:76-77``getAppointActivityDefinitionId` 方法
### 三、修复方案
修改 `DoctorStationLabApplyServiceImpl.java` 中阶段二(门诊医嘱创建循环),将从 `wor_activity_definition` 按名称查询改为使用 `lab_activity_definition``activityId` 直接查询:
**修改文件**`healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/doctorstation/appservice/impl/DoctorStationLabApplyServiceImpl.java`
**具体改动**
将第254-370行附近的代码从
```java
// 1. 根据检验项目名称查询诊疗定义(检验项目)
String itemName = labApplyItemDto.getItemName();
Long activityDefinitionId = activityDefinitionService.getAppointActivityDefinitionId(itemName);
if (activityDefinitionId == null) {
throw new RuntimeException("未找到检验项目 '" + itemName + "' 对应的诊疗定义");
}
// 2. 获取诊疗定义详情
ActivityDefinition activityDefinition = activityDefinitionService.getById(activityDefinitionId);
if (activityDefinition == null) {
throw new RuntimeException("诊疗定义不存在");
}
...
adviceSaveDto.setAdviceDefinitionId(activityDefinitionId);
adviceSaveDto.setDefinitionId(activityDefinitionId);
adviceSaveDto.setCategoryCode(activityDefinition.getCategoryCode());
adviceSaveDto.setActivityId(activityDefinitionId);
adviceSaveDto.setAdviceTableName("wor_activity_definition");
...
adviceSaveDto.setUnitCode(activityDefinition.getPermittedUnitCode());
Long feePackageId = activityDefinition.getFeePackageId();
```
改为:
```java
// 1. 获取检验项目定义(从 lab_activity_definition 表,不走 wor_activity_definition
String itemName = labApplyItemDto.getItemName();
Long labActivityId = labApplyItemDto.getActivityId();
if (labActivityId == null) {
throw new RuntimeException("检验项目 '" + itemName + "' 未传入 activityId请重新选择检验项目");
}
LabActivityDefinition labActivityDef = labActivityDefinitionService.getById(labActivityId);
if (labActivityDef == null) {
throw new RuntimeException("检验项目定义不存在activityId=" + labActivityId);
}
...
// 医嘱定义 ID使用 lab_activity_definition 的 ID
adviceSaveDto.setAdviceDefinitionId(labActivityId);
// 费用定价 ID检验项目不走 wor_activity_definition 定价体系,用 0 占位(与 ExamApplyController 一致)
adviceSaveDto.setDefinitionId(0L);
adviceSaveDto.setCategoryCode(labActivityDef.getCategoryCode());
adviceSaveDto.setActivityId(labActivityId);
adviceSaveDto.setAdviceTableName("lab_activity_definition");
...
adviceSaveDto.setUnitCode(labActivityDef.getPermittedUnitCode());
Long feePackageId = labActivityDef.getFeePackageId();
```
**核心改动点**
| 字段 | 原值 | 新值 | 原因 |
|------|------|------|------|
| 数据源 | `wor_activity_definition` (by name) | `lab_activity_definition` (by ID) | 检验项目独立存储 |
| `adviceDefinitionId` | `wor_activity_definition.id` | `lab_activity_definition.id` | 正确引用产品表 |
| `definitionId` | `wor_activity_definition.id` | `0L` 占位 | 检验项目不走诊疗定价体系 |
| `adviceTableName` | `"wor_activity_definition"` | `"lab_activity_definition"` | 正确指向产品来源表 |
| `categoryCode` | `ActivityDefinition.categoryCode` | `LabActivityDefinition.categoryCode` | 同名字段,来源切换 |
| `unitCode` | `ActivityDefinition.permittedUnitCode` | `LabActivityDefinition.permittedUnitCode` | 同名字段,来源切换 |
| `feePackageId` | `ActivityDefinition.feePackageId` | `LabActivityDefinition.feePackageId` | 同名字段,来源切换 |
### 四、路由决策
**FIXER**: `guanyu`(后端开发)
**REASON**: 此 Bug 仅涉及后端 Java 代码修改(`DoctorStationLabApplyServiceImpl.java` 一个文件),核心是修正检验项目的数据源查询逻辑——从 `wor_activity_definition` 切换到 `lab_activity_definition`。不需要前端改动(前端已正确传递 `activityId`),不需要数据库变更。属于后端 Service 层逻辑修复,由关羽执行最合适。
---
## 路由决策
- **修复 Agent**: guanyu
- **原因**: LLM 分析决策