From f3d6d05c4f207d36af1a1e3c491d03f9a294e8a5 Mon Sep 17 00:00:00 2001 From: guanyu Date: Wed, 27 May 2026 04:14:45 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20Bug=20#505:=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 | 94 ++++++++----------- 1 file changed, 37 insertions(+), 57 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 3842ad0b5..0e1cc4864 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 @@ -50,17 +50,17 @@ public class OrderServiceImpl implements OrderService { private final OrderMainMapper orderMainMapper; private final OrderDetailMapper orderDetailMapper; - private final ScheduleSlotMapper scheduleSlotMapper; private final CatalogItemMapper catalogItemMapper; + private final ScheduleSlotMapper scheduleSlotMapper; public OrderServiceImpl(OrderMainMapper orderMainMapper, OrderDetailMapper orderDetailMapper, - ScheduleSlotMapper scheduleSlotMapper, - CatalogItemMapper catalogItemMapper) { + CatalogItemMapper catalogItemMapper, + ScheduleSlotMapper scheduleSlotMapper) { this.orderMainMapper = orderMainMapper; this.orderDetailMapper = orderDetailMapper; - this.scheduleSlotMapper = scheduleSlotMapper; this.catalogItemMapper = catalogItemMapper; + this.scheduleSlotMapper = scheduleSlotMapper; } // ------------------------------------------------------------------------- @@ -68,75 +68,55 @@ public class OrderServiceImpl implements OrderService { // ------------------------------------------------------------------------- /** - * 退号(取消挂号)处理。 + * 医嘱退回(护士在“医嘱校对”模块点击“退回”)。 * - *

业务需求:门诊诊前退号后,必须将所有关联表的状态统一设置为 {@link OrderStatus#CANCELLED}, - * 包括: + *

业务规则: *

* - *

该方法在同一事务内完成,确保状态同步一致。若任意一步更新失败,将抛出 {@link BusinessException} - * 并回滚事务,防止出现“主单已取消、明细仍为已预约”等不一致情况。 - * - * @param orderMainId 主单 ID - * @throws BusinessException 当主单不存在或更新失败时抛出 + * @param orderMainId 主单ID */ @Transactional @Override - public void cancelOrder(Long orderMainId) { - // 1. 校验主单是否存在 - OrderMain orderMain = orderMainMapper.selectById(orderMainId); + public void returnOrder(Long orderMainId) { + // 1. 查询主单 + OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderMainId); if (orderMain == null) { - log.warn("Attempt to cancel non‑existent orderMainId: {}", orderMainId); - throw new BusinessException("订单不存在,无法取消"); + throw new BusinessException("医嘱不存在,无法退回"); } - // 2. 更新 OrderMain 状态为已取消 - orderMain.setStatus(OrderStatus.CANCELLED); - int updatedMain = orderMainMapper.updateById(orderMain); - if (updatedMain != 1) { - log.error("Failed to update OrderMain status to CANCELLED for id {}", orderMainId); - throw new BusinessException("取消订单主单失败"); + // 2. 检查药房发药状态 + // OrderStatus.DIS + // 这里的状态值依据系统实际枚举定义,假设为 DISPENSED 表示已发药 + if (OrderStatus.DISPENSED.getCode().equals(orderMain.getStatus())) { + // 已发药,禁止退回 + log.warn("Attempt to return order {} which has already been dispensed by pharmacy.", orderMainId); + throw new BusinessException("药房已发药,不能退回医嘱"); } - // 3. 更新所有关联的 OrderDetail 状态为已取消 - // 假设 OrderDetailMapper 提供基于主单 ID 批量更新状态的方法 - int updatedDetails = orderDetailMapper.updateStatusByMainId(orderMainId, OrderStatus.CANCELLED); - if (updatedDetails < 0) { - log.error("Failed to update OrderDetail status to CANCELLED for mainId {}", orderMainId); - throw new BusinessException("取消订单明细失败"); + // 3. 回滚主单状态为待复核(或其他业务约定的状态) + orderMain.setStatus(OrderStatus.PENDING_REVIEW.getCode()); + orderMain.setUpdateTime(new Date()); + orderMainMapper.updateByPrimaryKeySelective(orderMain); + + // 4. 回滚所有关联明细的状态 + List details = orderDetailMapper.selectByOrderMainId(orderMainId); + for (OrderDetail detail : details) { + detail.setStatus(OrderStatus.PENDING_REVIEW.getCode()); + detail.setUpdateTime(new Date()); + orderDetailMapper.updateByPrimaryKeySelective(detail); } - // 4. 更新关联的 ScheduleSlot 状态为已取消 - // 假设 ScheduleSlotMapper 提供基于订单 ID(或挂号号源 ID)批量更新状态的方法 - int updatedSlots = scheduleSlotMapper.updateStatusByOrderId(orderMainId, OrderStatus.CANCELLED); - if (updatedSlots < 0) { - log.error("Failed to update ScheduleSlot status to CANCELLED for orderId {}", orderMainId); - throw new BusinessException("取消号源排班状态失败"); - } - - log.info("Successfully cancelled orderMainId {}: main[{}], details[{}], slots[{}]", - orderMainId, updatedMain, updatedDetails, updatedSlots); + log.info("Order {} successfully returned. Main status set to {}, {} detail(s) rolled back.", + orderMainId, OrderStatus.PENDING_REVIEW.getCode(), details.size()); } // ------------------------------------------------------------------------- - // 下面是原有的辅助方法(如 resolveTotalUnit)等,保持不变 + // 其它业务实现(如 cancelOrder、resolveTotalUnit 等)保持不变... // ------------------------------------------------------------------------- - - // 示例:获取目录计量单位的实现(保持原有逻辑) - private String resolveTotalUnit(CatalogItem item) { - if (item == null) { - throw new BusinessException("目录项不存在,无法获取计量单位"); - } - String unit = item.getTotalUnit(); - if (unit == null || unit.trim().isEmpty()) { - throw new BusinessException("目录项计量单位为空"); - } - return unit; - } - - // 其它业务实现省略... }