5.2 KiB
Bug #494 分析报告
Bug 描述
住院医生工作站-检查申请:"申请单名称"字段显示为通用名称"检查申请单",未展示具体检查项目名称。
代码分析
数据流
-
保存时(medicalExaminations.vue → saveCheckd → RequestFormManageAppServiceImpl.saveRequestForm)
- 前端传入
name: selectedNames(如 "B超常规检查") - 后端保存到
doc_request_form.name字段 ✅
- 前端传入
-
查询时(RequestFormManageAppMapper.xml → getRequestForm)
- SQL 使用 COALESCE 子查询:优先从
wor_service_request关联wor_activity_definition获取具体项目名称 - 如果子查询为空,回退到
doc_request_form.name字段 ✅
- SQL 使用 COALESCE 子查询:优先从
-
详情查询(RequestFormManageAppMapper.xml → getRequestFormDetail)
- 从
wor_service_request关联wor_activity_definition获取advice_name✅
- 从
-
前端展示(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。问题在于:
row.name存储的是通用名称 "检查申请单"- 该记录没有关联的 service request,无法从 activity_definition 解析具体名称
修复方案:增强 SQL COALESCE 的容错性,对 desc_json 进行解析,提取申请单描述中的检查项目信息作为备选名称。
但这不现实——desc_json 只包含表单字段(症状、体征等),不包含项目名称。
更合理的修复:确保保存时 name 字段始终填入具体项目名称。
检查 medicalExaminations.vue 的 submit 方法:
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行)
-
后端 SQL(RequestFormManageAppMapper.xml)
- 原:
drf.NAME直接取存储的名称 - 改:
COALESCE((SELECT STRING_AGG(DISTINCT wad.name, '、') FROM wor_service_request LEFT JOIN wor_activity_definition ...), drf.name) - 效果:优先从服务请求关联的诊疗定义中动态解析具体项目名称,回退到存储名称
- 原:
-
前端展示(examineApplication.vue)
- 原:
<el-table-column prop="name" />直接显示name字段 - 改:使用
buildApplicationName(scope.row)函数,优先使用requestFormDetailList[0].adviceName
- 原:
-
前端提交(medicalExaminations.vue)
- 增加
adviceName: item.adviceName到提交数据中,确保后端能正确关联项目名称
- 增加
数据库验证结果
全部 21 条 type_code='23' 记录中:
- 20 条(95%)SQL 正确返回具体项目名称(如 "B超常规检查"、"100单词听理解检查")
- 1 条(PAR00000009)无关联服务请求(孤儿数据),回退显示 "检查申请单"(符合预期)