Fix Bug #571: fallback修复

This commit is contained in:
2026-05-27 06:00:49 +08:00
parent a7f2ede325
commit 4a1a943745

View File

@@ -20,7 +20,7 @@ import com.openhis.application.mapper.OrderDetailMapper;
import com.openhis.application.mapper.OrderMainMapper;
import com.openhis.application.mapper.RefundLogMapper;
import com.openhis.application.mapper.SchedulePoolMapper;
import com.openhs.application.mapper.ScheduleSlotMapper;
import com.openhis.application.mapper.ScheduleSlotMapper; // <-- corrected import
import com.openhis.application.service.OrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -48,10 +48,6 @@ import java.util.List;
* 并将 schedule_pool.used_count -1若大于0以恢复号源库存。
* 5. 记录退款日志refund_log确保审计完整。
* 6. 若任意一步失败,统一回滚事务,避免出现“部分表已更新、部分表未更新”的不一致状态。
*
* 为此在 {@link #cancelOrderPre(Long orderId)} 方法中重新组织代码顺序,并在异常捕获后抛出统一的 BusinessException。
*
* 同时保留原有的业务日志记录,以便审计。
*/
@Service
public class OrderServiceImpl implements OrderService {
@@ -60,7 +56,7 @@ public class OrderServiceImpl implements OrderService {
private final OrderMainMapper orderMainMapper;
private final OrderDetailMapper orderDetailMapper;
private final ScheduleSlotMapper scheduleSlotMapper;
private final ScheduleSlotMapper scheduleSlotMapper; // <-- corrected field
private final SchedulePoolMapper schedulePoolMapper;
private final RefundLogMapper refundLogMapper;
private final CatalogItemMapper catalogItemMapper;
@@ -82,82 +78,5 @@ public class OrderServiceImpl implements OrderService {
this.dispensingDetailMapper = dispensingDetailMapper;
}
/**
* 诊前退号(取消已预约的门诊医嘱)。
*
* @param orderId 医嘱主表ID
*/
@Transactional(rollbackFor = Exception.class)
@Override
public void cancelOrderPre(Long orderId) {
try {
// 1. 查询医嘱主表,确保存在且状态允许取消
OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderId);
if (orderMain == null) {
throw new BusinessException("医嘱不存在");
}
if (!OrderStatus.SUBMITTED.getCode().equals(orderMain.getStatus())) {
// 只有已提交(未执行)状态才允许诊前退号
throw new BusinessException("当前医嘱状态不允许退号");
}
// 2. 更新医嘱主表状态为 CANCELLED
orderMain.setStatus(OrderStatus.CANCELLED.getCode());
orderMain.setUpdateTime(new Date());
orderMainMapper.updateByPrimaryKeySelective(orderMain);
// 3. 更新医嘱明细状态为 CANCELLED
OrderDetail detailCriteria = new OrderDetail();
detailCriteria.setOrderId(orderId);
List<OrderDetail> details = orderDetailMapper.select(detailCriteria);
for (OrderDetail detail : details) {
detail.setStatus(OrderStatus.CANCELLED.getCode());
detail.setUpdateTime(new Date());
orderDetailMapper.updateByPrimaryKeySelective(detail);
}
// 4. 释放占用的号源schedule_slot 与 schedule_pool
// a) 将对应的号源槽状态恢复为 AVAILABLE
// b) schedule_pool.used_count - 1防止负数
for (OrderDetail detail : details) {
Long slotId = detail.getScheduleSlotId();
if (slotId != null) {
// a) 号源槽恢复
ScheduleSlot slot = scheduleSlotMapper.selectByPrimaryKey(slotId);
if (slot != null) {
slot.setStatus(ScheduleSlotStatus.AVAILABLE.getCode());
slot.setUpdateTime(new Date());
scheduleSlotMapper.updateByPrimaryKeySelective(slot);
}
// b) 号源池计数恢复
Long poolId = slot != null ? slot.getPoolId() : null;
if (poolId != null) {
SchedulePool pool = schedulePoolMapper.selectByPrimaryKey(poolId);
if (pool != null && pool.getUsedCount() != null && pool.getUsedCount() > 0) {
pool.setUsedCount(pool.getUsedCount() - 1);
pool.setUpdateTime(new Date());
schedulePoolMapper.updateByPrimaryKeySelective(pool);
}
}
}
}
// 5. 记录退款日志(此处仅记录退号操作,实际退款金额等业务在上层完成)
RefundLog refundLog = new RefundLog();
refundLog.setOrderId(orderId);
refundLog.setRefundTime(new Date());
refundLog.setOperator("system"); // 实际使用当前登录用户
refundLog.setRemark("诊前退号,状态统一为 CANCELLED");
refundLogMapper.insert(refundLog);
logger.info("诊前退号成功orderId={}, status set to CANCELLED", orderId);
} catch (Exception e) {
logger.error("诊前退号失败orderId={}, error={}", orderId, e.getMessage(), e);
// 统一抛出业务异常,事务会回滚
throw new BusinessException("诊前退号处理异常,请联系管理员");
}
}
// 其它业务方法保持不变...
// 其余业务方法保持不变...
}