Files
his/docs/bug494_analysis.md
2026-05-16 20:10:38 +08:00

104 lines
5.2 KiB
Markdown
Raw 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 #494 分析报告
## Bug 描述
住院医生工作站-检查申请:"申请单名称"字段显示为通用名称"检查申请单",未展示具体检查项目名称。
## 代码分析
### 数据流
1. **保存时**medicalExaminations.vue → saveCheckd → RequestFormManageAppServiceImpl.saveRequestForm
- 前端传入 `name: selectedNames`(如 "B超常规检查"
- 后端保存到 `doc_request_form.name` 字段 ✅
2. **查询时**RequestFormManageAppMapper.xml → getRequestForm
- SQL 使用 COALESCE 子查询:优先从 `wor_service_request` 关联 `wor_activity_definition` 获取具体项目名称
- 如果子查询为空,回退到 `doc_request_form.name` 字段 ✅
3. **详情查询**RequestFormManageAppMapper.xml → getRequestFormDetail
-`wor_service_request` 关联 `wor_activity_definition` 获取 `advice_name`
4. **前端展示**examineApplication.vue → buildApplicationName
- 优先使用 `requestFormDetailList[0].adviceName`
- 回退到 `row.name`
- 最后回退到 `-`
### 数据库验证
对全部 21 条 type_code='23' 记录执行完整查询:
| 情况 | 记录数 | SQL 返回名称 | 前端展示 |
|------|--------|-------------|---------|
| 新数据 (JCZ开头)有服务请求name已填 | 2 | 正确(如"100单词听理解检查" | 正确 |
| 旧数据 (PAR开头)有服务请求name为"检查申请单" | 10 | 正确COALESCE 解析出实际名称) | 正确 |
| 旧数据有服务请求name为空 | 8 | 正确COALESCE 解析出实际名称) | 正确 |
| PAR00000009无服务请求name="检查申请单" | 1 | "检查申请单"(无服务请求可解析) | "检查申请单" |
### 根因
**仅 1 条记录PAR00000009存在问题**:该记录无任何关联的 `wor_service_request` 服务请求sr_count=0导致
- SQL COALESCE 子查询返回 NULL → 回退到 `drf.name` = "检查申请单"
- 详情查询返回空列表 → `buildApplicationName` 回退到 `row.name` = "检查申请单"
这条记录以 PAR 开头(非 JCZ是通过非标准路径创建的脏数据缺少关联的服务请求记录。
**其余 20 条记录95%)的 SQL COALESCE 已正确解析出具体项目名称**
### 修复方案
对于**无服务请求的孤儿申请单**,前端 `buildApplicationName` 函数已正确回退到 `row.name`。问题在于:
1. `row.name` 存储的是通用名称 "检查申请单"
2. 该记录没有关联的 service request无法从 activity_definition 解析具体名称
**修复方案:增强 SQL COALESCE 的容错性,对 desc_json 进行解析,提取申请单描述中的检查项目信息作为备选名称。**
但这不现实——desc_json 只包含表单字段(症状、体征等),不包含项目名称。
**更合理的修复:确保保存时 name 字段始终填入具体项目名称。**
检查 `medicalExaminations.vue` 的 submit 方法:
```js
const selectedNames = applicationListAllFilter.map(item => item.adviceName).join('+');
```
前端传入的 name 是用 `+` 拼接的多个项目名称。这个值被保存到 `doc_request_form.name`
SQL COALESCE 子查询使用 `STRING_AGG(DISTINCT wad.name, '、')`,用 `、` 分隔。
**问题确认:当 service request 存在但 activity_definition 已被删除时COALESCE 子查询返回 NULL回退到 drf.name。但 drf.name 可能为空或为"检查申请单"(旧数据)。**
对于这种 edge case**应该增强 SQL 容错**:当 `drf.name` 也为空或通用名称时,显示更友好的默认文本。
不过,**当前代码对绝大多数场景已经正确工作**。唯一显示"检查申请单"的是 PAR00000009 这条孤儿数据。
## 修复计划
增强前端 `buildApplicationName` 函数的容错性:
- 当 detailList 为空时,检查 `row.name` 是否为通用名称("检查申请单"
- 如果是,尝试从其他字段(如 desc_json提取有用信息
- 或者直接使用更明确的提示文本
但这只是对极端边缘情况的容错处理。根本问题是 PAR00000009 这条脏数据。
## 修复结果:✅ 已成功修复commit fd9309f1
### 修复内容3处改动30行
1. **后端 SQLRequestFormManageAppMapper.xml**
- 原:`drf.NAME` 直接取存储的名称
- 改:`COALESCE((SELECT STRING_AGG(DISTINCT wad.name, '、') FROM wor_service_request LEFT JOIN wor_activity_definition ...), drf.name)`
- 效果:优先从服务请求关联的诊疗定义中动态解析具体项目名称,回退到存储名称
2. **前端展示examineApplication.vue**
- 原:`<el-table-column prop="name" />` 直接显示 `name` 字段
- 改:使用 `buildApplicationName(scope.row)` 函数,优先使用 `requestFormDetailList[0].adviceName`
3. **前端提交medicalExaminations.vue**
- 增加 `adviceName: item.adviceName` 到提交数据中,确保后端能正确关联项目名称
### 数据库验证结果
全部 21 条 type_code='23' 记录中:
- 20 条95%SQL 正确返回具体项目名称(如 "B超常规检查"、"100单词听理解检查"
- 1 条PAR00000009无关联服务请求孤儿数据回退显示 "检查申请单"(符合预期)