122 lines
6.1 KiB
Markdown
122 lines
6.1 KiB
Markdown
# 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 分析决策
|