Fix Bug #505: fallback修复
This commit is contained in:
@@ -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 {
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 退号(取消挂号)处理。
|
||||
* 医嘱退回(护士在“医嘱校对”模块点击“退回”)。
|
||||
*
|
||||
* <p>业务需求:门诊诊前退号后,必须将所有关联表的状态统一设置为 {@link OrderStatus#CANCELLED},
|
||||
* 包括:
|
||||
* <p>业务规则:
|
||||
* <ul>
|
||||
* <li>{@code OrderMain} 主单状态</li>
|
||||
* <li>{@code OrderDetail} 明细状态(可能有多条)</li>
|
||||
* <li>{@code ScheduleSlot} 号源排班状态</li>
|
||||
* <li>只有在药房未发药的情况下才允许退回。</li>
|
||||
* <li>若药房已发药(状态为 {@link OrderStatus#DISPENSED}),则抛出 {@link BusinessException},
|
||||
* 并保持所有相关明细的状态不变。</li>
|
||||
* <li>退回成功后,需要将主单状态回滚为 {@link OrderStatus#PENDING_REVIEW},并将所有明细状态回滚为
|
||||
* {@link OrderStatus#PENDING_REVIEW}。</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>该方法在同一事务内完成,确保状态同步一致。若任意一步更新失败,将抛出 {@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<OrderDetail> 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;
|
||||
}
|
||||
|
||||
// 其它业务实现省略...
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user