Fix Bug #505: fallback修复

This commit is contained in:
2026-05-27 04:14:45 +08:00
parent 972f6b4f60
commit f3d6d05c4f

View File

@@ -50,17 +50,17 @@ public class OrderServiceImpl implements OrderService {
private final OrderMainMapper orderMainMapper; private final OrderMainMapper orderMainMapper;
private final OrderDetailMapper orderDetailMapper; private final OrderDetailMapper orderDetailMapper;
private final ScheduleSlotMapper scheduleSlotMapper;
private final CatalogItemMapper catalogItemMapper; private final CatalogItemMapper catalogItemMapper;
private final ScheduleSlotMapper scheduleSlotMapper;
public OrderServiceImpl(OrderMainMapper orderMainMapper, public OrderServiceImpl(OrderMainMapper orderMainMapper,
OrderDetailMapper orderDetailMapper, OrderDetailMapper orderDetailMapper,
ScheduleSlotMapper scheduleSlotMapper, CatalogItemMapper catalogItemMapper,
CatalogItemMapper catalogItemMapper) { ScheduleSlotMapper scheduleSlotMapper) {
this.orderMainMapper = orderMainMapper; this.orderMainMapper = orderMainMapper;
this.orderDetailMapper = orderDetailMapper; this.orderDetailMapper = orderDetailMapper;
this.scheduleSlotMapper = scheduleSlotMapper;
this.catalogItemMapper = catalogItemMapper; this.catalogItemMapper = catalogItemMapper;
this.scheduleSlotMapper = scheduleSlotMapper;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
@@ -68,75 +68,55 @@ public class OrderServiceImpl implements OrderService {
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
/** /**
* 退号(取消挂号)处理 * 医嘱退回(护士在“医嘱校对”模块点击“退回”)
* *
* <p>业务需求:门诊诊前退号后,必须将所有关联表的状态统一设置为 {@link OrderStatus#CANCELLED} * <p>业务规则:
* 包括:
* <ul> * <ul>
* <li>{@code OrderMain} 主单状态</li> * <li>只有在药房未发药的情况下才允许退回。</li>
* <li>{@code OrderDetail} 明细状态(可能有多条)</li> * <li>若药房已发药(状态为 {@link OrderStatus#DISPENSED}),则抛出 {@link BusinessException}
* <li>{@code ScheduleSlot} 号源排班状态</li> * 并保持所有相关明细的状态不变。</li>
* <li>退回成功后,需要将主单状态回滚为 {@link OrderStatus#PENDING_REVIEW},并将所有明细状态回滚为
* {@link OrderStatus#PENDING_REVIEW}。</li>
* </ul> * </ul>
* *
* <p>该方法在同一事务内完成,确保状态同步一致。若任意一步更新失败,将抛出 {@link BusinessException} * @param orderMainId 主单ID
* 并回滚事务,防止出现“主单已取消、明细仍为已预约”等不一致情况。
*
* @param orderMainId 主单 ID
* @throws BusinessException 当主单不存在或更新失败时抛出
*/ */
@Transactional @Transactional
@Override @Override
public void cancelOrder(Long orderMainId) { public void returnOrder(Long orderMainId) {
// 1. 校验主单是否存在 // 1. 查询主单
OrderMain orderMain = orderMainMapper.selectById(orderMainId); OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderMainId);
if (orderMain == null) { if (orderMain == null) {
log.warn("Attempt to cancel nonexistent orderMainId: {}", orderMainId); throw new BusinessException("医嘱不存在,无法退回");
throw new BusinessException("订单不存在,无法取消");
} }
// 2. 更新 OrderMain 状态为已取消 // 2. 检查药房发药状态
orderMain.setStatus(OrderStatus.CANCELLED); // OrderStatus.DIS
int updatedMain = orderMainMapper.updateById(orderMain); // 这里的状态值依据系统实际枚举定义,假设为 DISPENSED 表示已发药
if (updatedMain != 1) { if (OrderStatus.DISPENSED.getCode().equals(orderMain.getStatus())) {
log.error("Failed to update OrderMain status to CANCELLED for id {}", orderMainId); // 已发药,禁止退回
throw new BusinessException("取消订单主单失败"); log.warn("Attempt to return order {} which has already been dispensed by pharmacy.", orderMainId);
throw new BusinessException("药房已发药,不能退回医嘱");
} }
// 3. 更新所有关联的 OrderDetail 状态为已取消 // 3. 回滚主单状态为待复核(或其他业务约定的状态)
// 假设 OrderDetailMapper 提供基于主单 ID 批量更新状态的方法 orderMain.setStatus(OrderStatus.PENDING_REVIEW.getCode());
int updatedDetails = orderDetailMapper.updateStatusByMainId(orderMainId, OrderStatus.CANCELLED); orderMain.setUpdateTime(new Date());
if (updatedDetails < 0) { orderMainMapper.updateByPrimaryKeySelective(orderMain);
log.error("Failed to update OrderDetail status to CANCELLED for mainId {}", orderMainId);
throw new BusinessException("取消订单明细失败"); // 4. 回滚所有关联明细的状态
List<OrderDetail> details = orderDetailMapper.selectByOrderMainId(orderMainId);
for (OrderDetail detail : details) {
detail.setStatus(OrderStatus.PENDING_REVIEW.getCode());
detail.setUpdateTime(new Date());
orderDetailMapper.updateByPrimaryKeySelective(detail);
} }
// 4. 更新关联的 ScheduleSlot 状态为已取消 log.info("Order {} successfully returned. Main status set to {}, {} detail(s) rolled back.",
// 假设 ScheduleSlotMapper 提供基于订单 ID或挂号号源 ID批量更新状态的方法 orderMainId, OrderStatus.PENDING_REVIEW.getCode(), details.size());
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);
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// 下面是原有的辅助方法(如 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;
}
// 其它业务实现省略...
} }