2.7 KiB
2.7 KiB
Bug #443 分析报告
Bug 描述
手术计费:点击"签发"耗材时异常报错
复现步骤
- 以"手术室护士"角色登录
- 进入【门诊手术安排】→ 点击【计费】
- 勾选一条状态为"待签发"的耗材项目
- 点击【签发】按钮
预期 vs 实际
- 预期:提示"签发成功",状态变为"已签发"
- 实际:弹出"后端程序异常"报错
代码分析
前端流程
surgicalschedule/index.vue→handleChargeCharge()打开计费弹窗- 弹窗中使用
prescriptionlist.vue组件,传入generateSourceEnum=6,sourceBillNo=operCode - 用户勾选"待签发"项目 → 点击"签发" → 触发
handleSave() handleSave()过滤item.check && item.statusEnum == 1 && (Number(item.bizRequestFlag)==1||!item.bizRequestFlag)- 构造请求体:解析
contentJson+ 补充顶层字段(encounterId, patientId, adviceType 等) - 调用
savePrescriptionSign()→ POST/doctor-station/advice/sign-advice
后端流程
DoctorStationAdviceController.signAdvice()→saveAdvice(param, SIGN_ADVICE)saveAdvice()校验 encounterId/patientId 非空- 按 adviceType 分类:药品(1)、耗材(2)、诊疗(3)
- 耗材走
handDevice(deviceList, curDate, adviceOpType)处理 - 签发后更新 DeviceRequest 状态为 ACTIVE(2)
- 更新 ChargeItem 状态:DRAFT(0)→PLANNED(1) 或 BILLABLE(2)→PLANNED(1)
可能根因
根因1:dbOpType 语义错误
- 前端
handleSave()对已存在的耗材发送dbOpType: '1'(INSERT) - 后端
handDevice中insertOrUpdateList通过requestId != null过滤包含这些项 - 但对于 INSERT 操作,如果 DeviceRequest 已存在,
saveOrUpdate走 UPDATE 路径 - 问题在于:INSERT 语义下某些字段(如
bus_no)仅在is_save=true时设置
根因2:contentJson 数据一致性
- 前端将
contentJson解析后 spread 回对象,再序列化为新的 JSON 发送 - 后端
handDevice直接将该 JSON 存入content_json字段 - 如果原始
content_json中的字段名与AdviceSaveDto不匹配(如 snake_case vs camelCase),可能导致数据丢失
根因3:缺少空列表校验
handleSave()未校验saveList.length == 0的情况- 如果过滤后列表为空,后端会返回"医嘱列表为空"错误
- 虽然 watch 逻辑应在列表为空时禁用按钮,但存在竞态条件可能
修复方案
- 前端
handleSave()添加saveList.length == 0校验(防御性编程) - 前端
handleSave()对已存在记录(requestId 不为空)使用dbOpType: '2'(UPDATE) 而非 '1' (INSERT) - 前端
handleSave()确保关键字段(quantity, unitCode)从顶层补充