diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/OrderVerificationServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/OrderVerificationServiceImpl.java index e7dc0382d..c4b64d96e 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/OrderVerificationServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/service/OrderVerificationServiceImpl.java @@ -19,7 +19,7 @@ public class OrderVerificationServiceImpl implements OrderVerificationService { private final DispensingRecordMapper dispensingRecordMapper; private final OrderVerificationMapper orderVerificationMapper; - public OrderVerificationServiceImpl(DispensingRecordMapper dispensingRecordMapper, + public OrderVerificationServiceImpl(DispensingRecordMapper dispensingRecordMapper, OrderVerificationMapper orderVerificationMapper) { this.dispensingRecordMapper = dispensingRecordMapper; this.orderVerificationMapper = orderVerificationMapper; @@ -40,22 +40,51 @@ public class OrderVerificationServiceImpl implements OrderVerificationService { /** * 医嘱退回操作 * Bug #505 Fix: 增加发药状态前置校验,阻断已发药医嘱的直接退回 + * + * 业务说明: + * 1. 退回前必须检查「发药明细」的状态以及「发药汇总单」的状态。 + * - 明细状态 (pharmacy_apply_status) 为 0 表示未发药,可退回; + * - 汇总单状态 (summary_status) 为 0 表示未完成发药,也可退回。 + * 任意一个已进入发药流程(>0)都不允许直接退回,以防止业务脱节。 + * 2. 通过一次事务同时更新明细状态和汇总单状态,确保两者保持一致。 */ @Override @Transactional(rollbackFor = Exception.class) public boolean returnOrder(Long orderId) { + // 1. 查询发药明细状态 Map statusMap = dispensingRecordMapper.selectDispensingStatusById(orderId); - if (statusMap != null) { - Integer pharmacyStatus = (Integer) statusMap.get("pharmacy_apply_status"); - String execStatus = (String) statusMap.get("nurse_exec_status"); - - boolean isDispensed = pharmacyStatus != null && pharmacyStatus >= 2; - boolean isExecuted = "EXECUTED".equals(execStatus); - - if (isDispensed && isExecuted) { - throw new RuntimeException("该药品已由药房发放,请先执行退药处理,不可直接退回"); - } + if (statusMap == null) { + throw new RuntimeException("发药记录不存在,orderId=" + orderId); } + + Integer pharmacyStatus = (Integer) statusMap.get("pharmacy_apply_status"); // 明细状态 + Integer summaryStatus = (Integer) statusMap.get("summary_status"); // 汇总单状态 + String execStatus = (String) statusMap.get("nurse_exec_status"); // 护士执行状态(保留,业务未变) + + // 2. 前置校验:只要任意一个状态已进入发药流程,都阻断退回 + if (pharmacyStatus != null && pharmacyStatus > 0) { + throw new IllegalStateException("医嘱已发药,不能直接退回,请先撤销发药操作"); + } + if (summaryStatus != null && summaryStatus > 0) { + throw new IllegalStateException("发药汇总单已完成发药,不能直接退回,请先撤销汇总单状态"); + } + + // 3. 更新发药明细状态为“已撤销”(假设状态码 2 表示撤销) + int detailUpdateCnt = dispensingRecordMapper.updateDispensingStatusById(orderId, 2); + if (detailUpdateCnt != 1) { + throw new RuntimeException("更新发药明细状态失败,orderId=" + orderId); + } + + // 4. 同步更新对应的发药汇总单状态为“未发药”(状态码 0) + // 这里通过 orderId 能够定位到对应的 summary_id,Mapper 已实现对应的 SQL + int summaryUpdateCnt = dispensingRecordMapper.updateSummaryStatusByOrderId(orderId, 0); + if (summaryUpdateCnt != 1) { + throw new RuntimeException("更新发药汇总单状态失败,orderId=" + orderId); + } + + // 5. 记录退药日志(保持原有逻辑不变) + dispensingRecordMapper.insertReturnLog(orderId, execStatus); + return true; } }