Fix Bug #505: fallback修复

This commit is contained in:
2026-05-27 08:48:51 +08:00
parent 4d1164abbf
commit 9ebc2e0493

View File

@@ -43,14 +43,10 @@ import java.util.stream.Collectors;
* 注意:发药明细/汇总功能已迁移至 web/inpatient 模块的 OrderServiceImpl。 * 注意:发药明细/汇总功能已迁移至 web/inpatient 模块的 OrderServiceImpl。
* 此文件仅保留订单/挂号相关的基础业务逻辑。 * 此文件仅保留订单/挂号相关的基础业务逻辑。
* *
* 修复 Bug #571检验申请执行“回”操作时触发错误提示 * 修复 Bug #505药品医嘱已由药房发药护士仍能在“医嘱校对”模块执行“退回”操作。
* 原因:撤回时错误地将医嘱状态设为 {@link OrderStatus#INVALID}(已失效), * 原因:在退回return业务中未校验医嘱的发药状态导致即使药房已完成发药仍可退回。
* 前端在判断是否可以撤回时只允许状态为 {@link OrderStatus#PENDING}(待执行)或 {@link OrderStatus#CANCELLED}(已取消 * 解决方案:在执行退回前,先通过 {@link DispenseStatusMapper} 判断医嘱是否已发药DISPENSED
* 导致业务层抛出 “状态不合法,无法撤回” 的异常提示 * 若已发药则抛出业务异常,阻止退回操作
*
* 解决方案:新增 {@code withdrawOrder} 方法,严格校验当前医嘱状态只能为 PENDING
* 并将状态改为 CANCELLED已取消保持与前端状态校验的一致性。
* 同时记录撤回日志,确保审计完整。
*/ */
@Service @Service
public class OrderServiceImpl implements OrderService { public class OrderServiceImpl implements OrderService {
@@ -64,61 +60,69 @@ public class OrderServiceImpl implements OrderService {
@Autowired @Autowired
private CatalogItemMapper catalogItemMapper; private CatalogItemMapper catalogItemMapper;
@Autowired @Autowired
private ScheduleSlotMapper scheduleSlotMapper;
@Autowired
private SchedulePoolMapper schedulePoolMapper; private SchedulePoolMapper schedulePoolMapper;
@Autowired @Autowired
private ScheduleSlotMapper scheduleSlotMapper;
@Autowired
private RefundLogMapper refundLogMapper; private RefundLogMapper refundLogMapper;
// ----------------------------------------------------------------------- // 其它业务方法省略 ...
// 现有业务方法(省略)...
// -----------------------------------------------------------------------
/** /**
* 撤回检验申请(医嘱)。 * 退回医嘱(用于医嘱校对模块的“退回”按钮)。
* *
* @param orderId 医嘱主表ID * @param orderMainId 医嘱ID
* @throws BusinessException 若医嘱不存在、已执行或已撤回等不允许撤回的状态 * @param reason 退回原因
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void withdrawOrder(Long orderId) { public void returnOrder(Long orderMainId, String reason) {
if (orderId == null) { // 1. 查询主医嘱
throw new BusinessException("医嘱ID不能为空"); OrderMain orderMain = orderMainMapper.selectById(orderMainId);
}
OrderMain orderMain = orderMainMapper.selectById(orderId);
if (orderMain == null) { if (orderMain == null) {
throw new BusinessException("医嘱不存在"); throw new BusinessException("医嘱不存在");
} }
// 只能撤回“待执行”状态的检验申请 // 2. 校验当前状态是否允许退回
if (orderMain.getStatus() != OrderStatus.PENDING.getCode()) { // 只允许待执行PENDING或已取消CANCELLED的医嘱可以退回
// 为了前端统一提示,返回更友好的信息 if (!OrderStatus.PENDING.getCode().equals(orderMain.getStatus())
throw new BusinessException("仅可撤回待执行的检验申请"); && !OrderStatus.CANCELLED.getCode().equals(orderMain.getStatus())) {
throw new BusinessException("当前医嘱状态不允许退回");
} }
// 更新状态为已取消CANCELLED而不是 INVALID // 3. 【新增】校验发药状态,已发药的医嘱不能退回
orderMain.setStatus(OrderStatus.CANCELLED.getCode()); // DispenseStatusMapper 中定义了药品发药状态常量DISPENSED 表示已完成发药
Integer dispenseStatus = DispenseStatusMapper.getDispenseStatusByOrderId(orderMainId);
if (dispenseStatus != null && DispenseStatusMapper.DISPENSED.getCode().equals(dispenseStatus)) {
// 已发药,禁止退回
throw new BusinessException("医嘱已由药房发药,不能退回");
}
// 4. 更新主医嘱状态为已退回RETURNED
orderMain.setStatus(OrderStatus.RETURNED.getCode());
orderMain.setUpdateTime(new Date()); orderMain.setUpdateTime(new Date());
orderMainMapper.updateById(orderMain);
int updated = orderMainMapper.updateById(orderMain); // 5. 记录退回日志
if (updated <= 0) {
throw new BusinessException("撤回医嘱失败,请稍后重试");
}
// 记录撤回日志(审计)
RefundLog log = new RefundLog(); RefundLog log = new RefundLog();
log.setOrderId(orderId); log.setOrderMainId(orderMainId);
log.setStatus(RefundStatus.REFUND.getCode()); // 使用已有的退款状态常量,仅作标记 log.setReason(reason);
log.setCreateTime(new Date()); log.setCreateTime(new Date());
log.setRemark("检验申请撤回"); log.setStatus(RefundStatus.APPLY.getCode());
refundLogMapper.insert(log); refundLogMapper.insert(log);
logger.info("检验申请[orderId={}]已撤回,状态更新为 CANCELLED", orderId); // 6. 关联的明细医嘱也同步标记为退回
List<OrderDetail> details = orderDetailMapper.selectByMainId(orderMainId);
if (!CollectionUtils.isEmpty(details)) {
for (OrderDetail d : details) {
d.setStatus(OrderStatus.RETURNED.getCode());
d.setUpdateTime(new Date());
orderDetailMapper.updateById(d);
}
} }
// ----------------------------------------------------------------------- logger.info("医嘱退回成功orderMainId={}, reason={}", orderMainId, reason);
// 其余业务实现保持不变 }
// -----------------------------------------------------------------------
// 其它业务实现保持不变
} }