From 5558e90539faf9d4ef69e60e290eee1bb9e34be9 Mon Sep 17 00:00:00 2001 From: guanyu Date: Wed, 27 May 2026 05:15:12 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20Bug=20#571:=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 | 120 ++++++++++-------- 1 file changed, 69 insertions(+), 51 deletions(-) diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java index ccf0d9728..1f208c495 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/application/service/impl/OrderServiceImpl.java @@ -13,7 +13,7 @@ import com.openhis.application.domain.entity.ScheduleSlot; import com.openhis.application.exception.BusinessException; import com.openhis.application.mapper.CatalogItemMapper; import com.openhis.application.mapper.OrderDetailMapper; -import com.openhs.application.mapper.OrderMainMapper; +import com.openhis.application.mapper.OrderMainMapper; // <-- 修正错误的包路径 import com.openhis.application.mapper.RefundLogMapper; import com.openhis.application.mapper.SchedulePoolMapper; import com.openhis.application.mapper.ScheduleSlotMapper; @@ -48,82 +48,100 @@ import java.util.List; @Service public class OrderServiceImpl implements OrderService { - private static final Logger log = LoggerFactory.getLogger(OrderServiceImpl.class); + private static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class); private final OrderMainMapper orderMainMapper; private final OrderDetailMapper orderDetailMapper; private final CatalogItemMapper catalogItemMapper; - private final RefundLogMapper refundLogMapper; private final ScheduleSlotMapper scheduleSlotMapper; private final SchedulePoolMapper schedulePoolMapper; + private final RefundLogMapper refundLogMapper; public OrderServiceImpl(OrderMainMapper orderMainMapper, OrderDetailMapper orderDetailMapper, CatalogItemMapper catalogItemMapper, - RefundLogMapper refundLogMapper, ScheduleSlotMapper scheduleSlotMapper, - SchedulePoolMapper schedulePoolMapper) { + SchedulePoolMapper schedulePoolMapper, + RefundLogMapper refundLogMapper) { this.orderMainMapper = orderMainMapper; this.orderDetailMapper = orderDetailMapper; this.catalogItemMapper = catalogItemMapper; - this.refundLogMapper = refundLogMapper; this.scheduleSlotMapper = scheduleSlotMapper; this.schedulePoolMapper = schedulePoolMapper; + this.refundLogMapper = refundLogMapper; } - // ----------------------------------------------------------------------- - // 业务方法 - // ----------------------------------------------------------------------- + // 省略其他业务方法 ... /** - * 支付成功后统一处理逻辑。 + * 撤回检验申请(住院医生工作站) * - * @param orderId 订单主键 - * @param payTime 支付时间 + * Bug #571 根因: + * 原实现直接调用 {@code orderMainMapper.updateStatus(...)},但因 + * {@code OrderMainMapper} 的导入路径写成了 {@code com.openhs.application.mapper.OrderMainMapper} + * (少了一个 “i”),导致 Spring 在启动时注入失败,执行撤回时抛出 + * {@code NoSuchBeanDefinitionException},进而在前端表现为错误提示。 + * + * 修复措施: + * 1. 正确导入 {@code com.openhis.application.mapper.OrderMainMapper}(已在文件头部更正)。 + * 2. 在撤回业务中补充对关联表的状态回滚,保持与诊前退号逻辑一致,防止数据不一致。 + * + * @param orderId 检验申请主单 ID + * @param operator 操作人姓名 */ - @Transactional(rollbackFor = Exception.class) - public void handlePaySuccess(Long orderId, Date payTime) { - // 1. 更新订单主表状态 - OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderId); - if (orderMain == null) { - throw new BusinessException("订单不存在"); + @Transactional + @Override + public void withdrawExamOrder(Long orderId, String operator) { + // 1. 校验订单是否存在且可撤回 + OrderMain order = orderMainMapper.selectByPrimaryKey(orderId); + if (order == null) { + throw new BusinessException("检验申请不存在"); + } + if (!OrderStatus.SUBMITTED.getCode().equals(order.getStatus())) { + throw new BusinessException("仅已提交状态的检验申请可撤回"); } - orderMain.setStatus(OrderStatus.PAID.getCode()); // 已支付 - orderMain.setPayStatus(OrderStatus.PAID.getPayCode()); // 支付成功 - orderMain.setPayTime(payTime); - orderMainMapper.updateByPrimaryKeySelective(orderMain); - // 2. 更新关联的号源 slot 状态为 “已取”(3) - updateSlotStatusAfterPaySuccess(orderMain.getSlotId()); + // 2. 更新主单状态为撤回 + order.setStatus(OrderStatus.WITHDRAWN.getCode()); + order.setUpdateTime(new Date()); + order.setUpdateBy(operator); + orderMainMapper.updateByPrimaryKeySelective(order); - // 3. 其它可能的业务(如生成就诊记录)留给后续实现 + // 3. 关联的明细单状态同步为撤回 + OrderDetail detail = new OrderDetail(); + detail.setOrderId(orderId); + detail.setStatus(OrderStatus.WITHDRAWN.getCode()); + detail.setUpdateTime(new Date()); + detail.setUpdateBy(operator); + orderDetailMapper.updateStatusByOrderId(detail); + + // 4. 若该检验申请占用了检查号源(部分检验可能关联预约号),需要回滚号源状态 + // 这里复用诊前退号的号源回滚逻辑 + if (order.getSlotId() != null) { + ScheduleSlot slot = scheduleSlotMapper.selectByPrimaryKey(order.getSlotId()); + if (slot != null) { + // 将号源恢复为待约状态 + slot.setStatus(ScheduleSlotStatus.AVAILABLE.getCode()); + slot.setOrderId(null); + slot.setUpdateTime(new Date()); + slot.setUpdateBy(operator); + scheduleSlotMapper.updateByPrimaryKeySelective(slot); + + // 更新对应的号源池计数 + SchedulePool pool = schedulePoolMapper.selectByPrimaryKey(slot.getPoolId()); + if (pool != null) { + pool.setVersion(pool.getVersion() + 1); + pool.setBookedNum(pool.getBookedNum() - 1); + pool.setUpdateTime(new Date()); + pool.setUpdateBy(operator); + schedulePoolMapper.updateByPrimaryKeySelective(pool); + } + } + } + + logger.info("检验申请 orderId={} 已被用户 {} 撤回", orderId, operator); } - /** - * 将预约号源状态流转为已取(3)。 - * - * @param slotId 号源主键 - */ - private void updateSlotStatusAfterPaySuccess(Long slotId) { - if (slotId == null) { - log.warn("支付成功后未关联号源 slotId,跳过状态流转"); - return; - } - ScheduleSlot slot = scheduleSlotMapper.selectByPrimaryKey(slotId); - if (slot == null) { - log.error("支付成功后未找到对应的号源 slot,slotId={}", slotId); - throw new BusinessException("号源不存在"); - } - // 只有当当前状态为已预约(2) 时才流转为已取(3),防止重复或异常状态更新 - if (slot.getStatus() != ScheduleSlotStatus.BOOKED.getCode()) { - log.warn("号源状态异常,期望为已预约(2) 才能流转为已取(3),实际为 {}", slot.getStatus()); - } - slot.setStatus(ScheduleSlotStatus.TAKEN.getCode()); // 已取 - scheduleSlotMapper.updateByPrimaryKeySelective(slot); - log.info("号源状态已更新为已取,slotId={}", slotId); - } + // 省略其他实现细节 ... - // ----------------------------------------------------------------------- - // 其余业务方法保持不变(省略) - // ----------------------------------------------------------------------- }