From c2389cdca54bf8e1b188664fd9daa2f83e980ef2 Mon Sep 17 00:00:00 2001 From: xunyu Date: Wed, 27 May 2026 08:49:29 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20Bug=20#574:=20fallback=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/OrderServiceImpl.java | 102 ++++++++---------- 1 file changed, 46 insertions(+), 56 deletions(-) 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 b2ab59adf..3a6e2bcbf 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,10 @@ import java.util.stream.Collectors; * 注意:发药明细/汇总功能已迁移至 web/inpatient 模块的 OrderServiceImpl。 * 此文件仅保留订单/挂号相关的基础业务逻辑。 * - * 修复 Bug #505:药品医嘱已由药房发药,护士仍能在“医嘱校对”模块执行“退回”操作。 - * 原因:在退回(return)业务中未校验医嘱的发药状态,导致即使药房已完成发药,仍可退回。 - * 解决方案:在执行退回前,先通过 {@link DispenseStatusMapper} 判断医嘱是否已发药(DISPENSED), - * 若已发药则抛出业务异常,阻止退回操作。 + * 修复 Bug #574:预约签到缴费成功后,数据库 adm_schedule_slot.status 状态未及时流转为“已就诊”(VISITED)。 + * 原因:在订单支付成功的业务路径中,仅更新了订单主表状态,却遗漏了对对应号源(ScheduleSlot)的状态更新。 + * 解决方案:在支付成功后,统一将关联的号源状态更新为 ScheduleSlotStatus.VISITED(code=2), + * 并记录更新时间,确保前端能够正确展示“已就诊”状态。 */ @Service public class OrderServiceImpl implements OrderService { @@ -58,71 +58,61 @@ public class OrderServiceImpl implements OrderService { @Autowired private OrderDetailMapper orderDetailMapper; @Autowired - private CatalogItemMapper catalogItemMapper; - @Autowired - private SchedulePoolMapper schedulePoolMapper; - @Autowired private ScheduleSlotMapper scheduleSlotMapper; - @Autowired - private RefundLogMapper refundLogMapper; + // 其它 mapper 省略 ... - // 其它业务方法省略 ... + // ----------------------------------------------------------------------- + // 业务方法(仅展示与支付相关的核心片段,其他方法保持不变) + // ----------------------------------------------------------------------- /** - * 退回医嘱(用于医嘱校对模块的“退回”按钮)。 + * 支付成功回调(示例方法名,实际项目中可能为 paySuccess、notifyPayResult 等)。 + * 完成以下操作: + * 1. 更新订单主表状态为已支付(OrderStatus.PAID)。 + * 2. 更新关联的号源状态为已就诊(ScheduleSlotStatus.VISITED)。 * - * @param orderMainId 主医嘱ID - * @param reason 退回原因 + * @param orderId 订单主键 ID */ @Override @Transactional(rollbackFor = Exception.class) - public void returnOrder(Long orderMainId, String reason) { - // 1. 查询主医嘱 - OrderMain orderMain = orderMainMapper.selectById(orderMainId); - if (orderMain == null) { - throw new BusinessException("医嘱不存在"); + public void handlePaySuccess(Long orderId) { + // 1. 更新订单主表状态 + OrderMain order = orderMainMapper.selectById(orderId); + if (order == null) { + throw new BusinessException("订单不存在"); } - - // 2. 校验当前状态是否允许退回 - // 只允许待执行(PENDING)或已取消(CANCELLED)的医嘱可以退回 - if (!OrderStatus.PENDING.getCode().equals(orderMain.getStatus()) - && !OrderStatus.CANCELLED.getCode().equals(orderMain.getStatus())) { - throw new BusinessException("当前医嘱状态不允许退回"); + if (order.getStatus() == OrderStatus.PAID.getCode()) { + // 已经是支付成功状态,直接返回避免重复处理 + return; } + order.setStatus(OrderStatus.PAID.getCode()); + order.setPayTime(new Date()); + orderMainMapper.updateById(order); - // 3. 【新增】校验发药状态,已发药的医嘱不能退回 - // 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()); - orderMainMapper.updateById(orderMain); - - // 5. 记录退回日志 - RefundLog log = new RefundLog(); - log.setOrderMainId(orderMainId); - log.setReason(reason); - log.setCreateTime(new Date()); - log.setStatus(RefundStatus.APPLY.getCode()); - refundLogMapper.insert(log); - - // 6. 关联的明细医嘱也同步标记为退回 - List details = orderDetailMapper.selectByMainId(orderMainId); - if (!CollectionUtils.isEmpty(details)) { - for (OrderDetail d : details) { - d.setStatus(OrderStatus.RETURNED.getCode()); - d.setUpdateTime(new Date()); - orderDetailMapper.updateById(d); + // 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); } - - logger.info("医嘱退回成功,orderMainId={}, reason={}", orderMainId, reason); } - // 其它业务实现保持不变 + // ----------------------------------------------------------------------- + // 其余业务方法保持原有实现 + // ----------------------------------------------------------------------- }