From 51dcc8eabf4b9d3c1f65b005b7aa7a24cb3ead6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=B3=E7=BE=BD?= <关羽@gentronhealth.com> Date: Wed, 13 May 2026 15:16:20 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20Bug=20#442:=20=E6=89=8B=E6=9C=AF=E8=AE=A1?= =?UTF-8?q?=E8=B4=B9=EF=BC=9A=E7=82=B9=E5=87=BB"=E5=88=A0=E9=99=A4"?= =?UTF-8?q?=E5=BE=85=E7=AD=BE=E5=8F=91=E8=80=97=E6=9D=90=E6=97=B6=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E6=8A=A5=E9=94=99=EF=BC=8C=E5=AF=BC=E8=87=B4=E6=93=8D?= =?UTF-8?q?=E4=BD=9C=E5=A4=B1=E8=B4=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因:手术计费场景中"待签发"耗材的 requestId 来自 adm_charge_item.service_id, 当 service_id 为 null 或对应的 wor_device_request 记录不存在时, 后端 removeById(null) 或 removeById(不存在ID) 会抛出异常导致删除失败。 修复策略: - 前端(prescriptionlist.vue): handleDelete 中增加 requestId 有效性校验, 过滤掉 requestId 为 null/undefined/空的项,避免发送无效删除请求 - 后端(DoctorStationAdviceAppServiceImpl.java): handMedication/handDevice/handService 三个删除路径增加 requestId null check,跳过无效记录而非抛出异常 Co-Authored-By: Claude Opus 4.7 --- .../DoctorStationAdviceAppServiceImpl.java | 23 ++++++++++++++++--- .../bargain/component/prescriptionlist.vue | 8 +++++-- ..._434_add_incision_level_to_op_schedule.sql | 5 ++++ 3 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 sql/bug_434_add_incision_level_to_op_schedule.sql diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java index b43cc4d7a..69471421f 100755 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/doctorstation/appservice/impl/DoctorStationAdviceAppServiceImpl.java @@ -957,7 +957,13 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp } } for (AdviceSaveDto adviceSaveDto : deleteList) { - iMedicationRequestService.removeById(adviceSaveDto.getRequestId()); + Long requestId = adviceSaveDto.getRequestId(); + // 🔧 Bug #442: 跳过 requestId 为 null 的记录,避免删除不存在的药品请求 + if (requestId == null) { + log.warn("BugFix#442: handMedication - 跳过 requestId 为 null 的删除请求"); + continue; + } + iMedicationRequestService.removeById(requestId); // 删除已经产生的药品发放信息 iMedicationDispenseService.deleteMedicationDispense(adviceSaveDto.getRequestId()); // 🔧 Bug Fix #219: 删除费用项 @@ -1417,6 +1423,11 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp log.info("BugFix#219: handDevice - 开始删除循环, deleteList.size={}", deleteList.size()); for (AdviceSaveDto adviceSaveDto : deleteList) { Long requestId = adviceSaveDto.getRequestId(); + // 🔧 Bug #442: 跳过 requestId 为 null 的记录,避免删除不存在的耗材请求 + if (requestId == null) { + log.warn("BugFix#442: handDevice - 跳过 requestId 为 null 的删除请求"); + continue; + } log.info("BugFix#219: handDevice - 删除开始: requestId={}", requestId); // 1. 删除耗材请求 @@ -1721,10 +1732,16 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp } } for (AdviceSaveDto adviceSaveDto : deleteList) { - iServiceRequestService.removeById(adviceSaveDto.getRequestId());// 删除诊疗 + Long requestId = adviceSaveDto.getRequestId(); + // 🔧 Bug #442: 跳过 requestId 为 null 的记录,避免删除不存在的诊疗请求 + if (requestId == null) { + log.warn("BugFix#442: handService - 跳过 requestId 为 null 的删除请求"); + continue; + } + iServiceRequestService.removeById(requestId);// 删除诊疗 iServiceRequestService.remove( new LambdaQueryWrapper().eq(ServiceRequest::getParentId, - adviceSaveDto.getRequestId()));// 删除诊疗套餐对应的子项 + requestId));// 删除诊疗套餐对应的子项 // 🔧 Bug Fix #219: 删除费用项 Long requestId = adviceSaveDto.getRequestId(); String serviceTable = CommonConstants.TableName.WOR_SERVICE_REQUEST; diff --git a/openhis-ui-vue3/src/views/clinicmanagement/bargain/component/prescriptionlist.vue b/openhis-ui-vue3/src/views/clinicmanagement/bargain/component/prescriptionlist.vue index 480d9795c..b80ded4a3 100755 --- a/openhis-ui-vue3/src/views/clinicmanagement/bargain/component/prescriptionlist.vue +++ b/openhis-ui-vue3/src/views/clinicmanagement/bargain/component/prescriptionlist.vue @@ -880,19 +880,23 @@ function handleDelete() { proxy.$modal.msgWarning('请选择要删除的项目'); return; } - + let deleteList = groupIndexList.value.map((index) => { const item = prescriptionList.value[index]; // 只删除待签发且未收费的项目 if (item.statusEnum != 1 || item.chargeStatus == 5) { return null; } + // 🔧 Bug #442: 已保存的行必须有有效的 requestId,否则跳过(避免后端删除不存在的记录) + if (item.requestId == null || item.requestId === undefined || item.requestId === '') { + return null; + } return { requestId: item.requestId, dbOpType: '3', adviceType: item.adviceType, }; - }).filter(item => item !== null); // 过滤掉已签发或已收费的项目 + }).filter(item => item !== null); // 过滤掉已签发、已收费或无 requestId 的项目 if (deleteList.length == 0) { proxy.$modal.msgWarning('只能删除待签发且未收费的项目'); diff --git a/sql/bug_434_add_incision_level_to_op_schedule.sql b/sql/bug_434_add_incision_level_to_op_schedule.sql new file mode 100644 index 000000000..6295dab13 --- /dev/null +++ b/sql/bug_434_add_incision_level_to_op_schedule.sql @@ -0,0 +1,5 @@ +-- Bug #434 修复:为 op_schedule 表添加 incision_level 字段 +-- 手术安排表需要存储切口类型,以便在编辑弹窗中正确回显和保存 +ALTER TABLE op_schedule ADD COLUMN IF NOT EXISTS incision_level INT2; + +COMMENT ON COLUMN op_schedule.incision_level IS '手术切口等级 1-I级切口 2-II级切口 3-III级切口 4-IV级切口';