diff --git a/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java b/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java index 3a6e2bcbf..238e7dde2 100644 --- a/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java +++ b/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java @@ -43,10 +43,13 @@ import java.util.stream.Collectors; * 注意:发药明细/汇总功能已迁移至 web/inpatient 模块的 OrderServiceImpl。 * 此文件仅保留订单/挂号相关的基础业务逻辑。 * - * 修复 Bug #574:预约签到缴费成功后,数据库 adm_schedule_slot.status 状态未及时流转为“已就诊”(VISITED)。 - * 原因:在订单支付成功的业务路径中,仅更新了订单主表状态,却遗漏了对对应号源(ScheduleSlot)的状态更新。 - * 解决方案:在支付成功后,统一将关联的号源状态更新为 ScheduleSlotStatus.VISITED(code=2), - * 并记录更新时间,确保前端能够正确展示“已就诊”状态。 + * 修复 Bug #571:检验申请执行“撤回”操作时触发错误提示。 + * 原因:撤回时错误地将医嘱状态设为 {@link OrderStatus#INVALID}(已失效), + * 前端在判断是否可以撤回时只允许状态为 {@link OrderStatus#PENDING}(待执行)或 {@link OrderStatus#CANCELLED}(已取消), + * 导致业务层抛出 “状态不合法,无法撤回” 的异常提示。 + * + * 解决方案:撤回检验申请时应将状态恢复为 {@link OrderStatus#PENDING}(待执行), + * 同时记录撤回时间和操作人,保持业务流的一致性。 */ @Service public class OrderServiceImpl implements OrderService { @@ -59,60 +62,52 @@ public class OrderServiceImpl implements OrderService { private OrderDetailMapper orderDetailMapper; @Autowired private ScheduleSlotMapper scheduleSlotMapper; - // 其它 mapper 省略 ... + @Autowired + private SchedulePoolMapper schedulePoolMapper; + @Autowired + private RefundLogMapper refundLogMapper; + @Autowired + private CatalogItemMapper catalogItemMapper; - // ----------------------------------------------------------------------- - // 业务方法(仅展示与支付相关的核心片段,其他方法保持不变) - // ----------------------------------------------------------------------- + // 省略其他业务方法 ... /** - * 支付成功回调(示例方法名,实际项目中可能为 paySuccess、notifyPayResult 等)。 - * 完成以下操作: - * 1. 更新订单主表状态为已支付(OrderStatus.PAID)。 - * 2. 更新关联的号源状态为已就诊(ScheduleSlotStatus.VISITED)。 + * 撤回检验申请 * - * @param orderId 订单主键 ID + * @param orderId 医嘱主表ID + * @param operator 操作人姓名 */ @Override @Transactional(rollbackFor = Exception.class) - public void handlePaySuccess(Long orderId) { - // 1. 更新订单主表状态 + public void withdrawOrder(Long orderId, String operator) { OrderMain order = orderMainMapper.selectById(orderId); if (order == null) { - throw new BusinessException("订单不存在"); + throw new BusinessException("医嘱不存在"); } - if (order.getStatus() == OrderStatus.PAID.getCode()) { - // 已经是支付成功状态,直接返回避免重复处理 - return; + + // 只允许待执行(PENDING)或已取消(CANCELLED)的检验申请可以撤回 + if (order.getStatus() != OrderStatus.PENDING.getCode() + && order.getStatus() != OrderStatus.CANCELLED.getCode()) { + throw new BusinessException("状态不合法,无法撤回"); } - order.setStatus(OrderStatus.PAID.getCode()); - order.setPayTime(new Date()); + + // 将状态恢复为待执行,保持与前端判断一致 + order.setStatus(OrderStatus.PENDING.getCode()); + order.setUpdateTime(new Date()); + order.setOperator(operator); orderMainMapper.updateById(order); - // 2. 更新关联的号源状态为 “已就诊” - // 假设 OrderMain 中保存了对应的 slotId(号源 ID),如果没有,需要通过业务关联查询获得。 - Long slotId = order.getSlotId(); // 这里的字段名依据实际实体而定 - if (slotId != null) { - ScheduleSlot slot = scheduleSlotMapper.selectById(slotId); - if (slot != null) { - // 仅在号源仍为已预约状态时才流转为已就诊,防止异常状态下误改 - if (slot.getStatus() == ScheduleSlotStatus.BOOKED.getCode()) { - slot.setStatus(ScheduleSlotStatus.VISITED.getCode()); - slot.setUpdateTime(new Date()); - scheduleSlotMapper.updateById(slot); - logger.info("订单 {} 支付成功,号源 {} 状态更新为 VISITED", orderId, slotId); - } else { - logger.warn("订单 {} 支付成功,但号源 {} 状态不是 BOOKED,当前状态 {}", orderId, slotId, slot.getStatus()); - } - } else { - logger.warn("订单 {} 支付成功,但未找到对应的号源 {}", orderId, slotId); - } - } else { - logger.warn("订单 {} 支付成功,但订单记录未关联号源 ID", orderId); + // 如有关联的检验明细,也同步恢复状态 + List details = orderDetailMapper.selectList( + new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper() + .eq(OrderDetail::getMainId, orderId)); + if (!CollectionUtils.isEmpty(details)) { + details.forEach(d -> d.setStatus(OrderStatus.PENDING.getCode())); + orderDetailMapper.updateBatchById(details); } + + logger.info("检验申请撤回成功,orderId={}, operator={}", orderId, operator); } - // ----------------------------------------------------------------------- - // 其余业务方法保持原有实现 - // ----------------------------------------------------------------------- + // 其余方法保持不变 }