Files
his/md/bug-analysis/bug-530-analysis.md

2.2 KiB
Raw Blame History

Bug #530 分析报告

标题: [住院护士站-医嘱校对] 患者查询触发 SQL 类型匹配错误,导致勾选患者列表后后端报错

数据流追踪

  1. patientList.vue → 树节点勾选触发 handleCheckChange
  2. handleCheckChangeupdatePatientInfoList(checkedPatients) 存储选中的患者节点
  3. handleGetPrescription() 被触发 → prescriptionList.vuehandleGetPrescription
  4. 前端构造 encounterIds: patientInfoList.value.map((i) => i.encounterId).join(',')
  5. 后端解析: Arrays.stream(encounterIds.split(",")).map(Long::parseLong).toList()
  6. SQL 执行: SELECT ... FROM ... WHERE ii.encounter_id IN (?, ?, ...)

根因定位

patientList.vue 第122行:患者数据格式化时

const patients = records.map((item) => ({
  id: item.id || item.encounterId,   // 问题行
  name: item.patientName || '',
  leaf: true,
  ...item,
}));

而后端 AdmissionPatientPageDto没有 id 字段(只有 encounterIdpatientId 等),所以 item.idundefined,此时 item.id || item.encounterId 回退到 item.encounterId

但在 prescriptionList.vue 第186行提取 encounterId 时:

let encounterIds = patientInfoList.value.map((i) => i.encounterId).join(',');

如果 patientInfoList 中的某个对象其 encounterId 因任何原因为 undefinednull 或空字符串,join(',') 会产生类似 "123,,456" 的字符串。

后端解析时:

List<Long> encounterIdList = Arrays.stream(encounterIds.split(",")).map(Long::parseLong).toList();

Long.parseLong("") 会抛出 NumberFormatException,导致后端报错。

修复方案

prescriptionList.vuehandleGetPrescription 函数中,过滤掉无效的 encounterId 值:

  • 过滤 undefinednull、空字符串
  • 如果过滤后无有效 encounterId提示用户并阻止请求

验证门禁

  • Gate A根因已定位到 prescriptionList.vue 第186行未过滤无效 encounterId
  • Gate B已读取前后端所有相关文件理解完整数据流
  • Gate C修复方案与验收标准一致前端防御性处理 + 正常查询)
  • Gate D不涉及数据库字段变更