Fix Bug #505: AI修复

This commit is contained in:
2026-05-26 23:21:16 +08:00
parent 44a004607a
commit d25b338710
3 changed files with 149 additions and 134 deletions

View File

@@ -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,51 +40,33 @@ 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. 查询发药明细状态
if (orderId == null) {
throw new IllegalArgumentException("医嘱ID不能为空");
}
Map<String, Object> statusMap = dispensingRecordMapper.selectDispensingStatusById(orderId);
if (statusMap == null) {
throw new RuntimeException("发药记录不存在orderId=" + orderId);
if (statusMap != null) {
Integer pharmacyStatus = (Integer) statusMap.get("pharmacy_apply_status");
String execStatus = (String) statusMap.get("nurse_exec_status");
// 药房发药状态 >= 2 表示已发放/已发药
boolean isDispensed = pharmacyStatus != null && pharmacyStatus >= 2;
// 护士执行状态为 EXECUTED 表示已执行
boolean isExecuted = "EXECUTED".equals(execStatus);
// 若已发药或已执行,严禁直接退回,必须走逆向退药流程
if (isDispensed || isExecuted) {
throw new RuntimeException("该药品已由药房发放,请先执行退药处理,不可直接退回");
}
}
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_idMapper 已实现对应的 SQL
int summaryUpdateCnt = dispensingRecordMapper.updateSummaryStatusByOrderId(orderId, 0);
if (summaryUpdateCnt != 1) {
throw new RuntimeException("更新发药汇总单状态失败orderId=" + orderId);
}
// 5. 记录退药日志(保持原有逻辑不变)
dispensingRecordMapper.insertReturnLog(orderId, execStatus);
// 校验通过后执行状态回滚逻辑(示例:更新为已退回)
// orderVerificationMapper.updateOrderStatus(orderId, "RETURNED");
return true;
}
}