Fix Bug #505: fallback修复
This commit is contained in:
@@ -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 non‑existent 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 其它业务实现省略...
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user