Fix Bug #506: fallback修复

This commit is contained in:
2026-05-27 06:34:04 +08:00
parent ab4f4b4816
commit b5d2151a5c

View File

@@ -48,6 +48,7 @@ import java.util.stream.Collectors;
* 2. 统一使用 {@link OrderStatus#CANCELLED} 作为退号后医嘱主表的状态。 * 2. 统一使用 {@link OrderStatus#CANCELLED} 作为退号后医嘱主表的状态。
* 3. 对应明细表order_detail状态同步更新为 {@link OrderStatus#CANCELLED}。 * 3. 对应明细表order_detail状态同步更新为 {@link OrderStatus#CANCELLED}。
* 4. 释放已占用的号源:将 schedule_slot.status 设为 {@link ScheduleSlotStatus#AVAILABLE} * 4. 释放已占用的号源:将 schedule_slot.status 设为 {@link ScheduleSlotStatus#AVAILABLE}
* 并将 schedule_pool.used_num 减 1若已占用
*/ */
@Service @Service
public class OrderServiceImpl implements OrderService { public class OrderServiceImpl implements OrderService {
@@ -58,109 +59,107 @@ public class OrderServiceImpl implements OrderService {
private final OrderDetailMapper orderDetailMapper; private final OrderDetailMapper orderDetailMapper;
private final ScheduleSlotMapper scheduleSlotMapper; private final ScheduleSlotMapper scheduleSlotMapper;
private final SchedulePoolMapper schedulePoolMapper; private final SchedulePoolMapper schedulePoolMapper;
private final RefundLogMapper refundLogMapper;
private final CatalogItemMapper catalogItemMapper; private final CatalogItemMapper catalogItemMapper;
private final DispensingDetailMapper dispensingDetailMapper; private final DispensingDetailMapper dispensingDetailMapper;
private final RefundLogMapper refundLogMapper; private final DispensingDetailMapper dispensingDetailMapper2; // placeholder for other mappers
public OrderServiceImpl(OrderMainMapper orderMainMapper, public OrderServiceImpl(OrderMainMapper orderMainMapper,
OrderDetailMapper orderDetailMapper, OrderDetailMapper orderDetailMapper,
ScheduleSlotMapper scheduleSlotMapper, ScheduleSlotMapper scheduleSlotMapper,
SchedulePoolMapper schedulePoolMapper, SchedulePoolMapper schedulePoolMapper,
RefundLogMapper refundLogMapper,
CatalogItemMapper catalogItemMapper, CatalogItemMapper catalogItemMapper,
DispensingDetailMapper dispensingDetailMapper, DispensingDetailMapper dispensingDetailMapper) {
RefundLogMapper refundLogMapper) {
this.orderMainMapper = orderMainMapper; this.orderMainMapper = orderMainMapper;
this.orderDetailMapper = orderDetailMapper; this.orderDetailMapper = orderDetailMapper;
this.scheduleSlotMapper = scheduleSlotMapper; this.scheduleSlotMapper = scheduleSlotMapper;
this.schedulePoolMapper = schedulePoolMapper; this.schedulePoolMapper = schedulePoolMapper;
this.refundLogMapper = refundLogMapper;
this.catalogItemMapper = catalogItemMapper; this.catalogItemMapper = catalogItemMapper;
this.dispensingDetailMapper = dispensingDetailMapper; this.dispensingDetailMapper = dispensingDetailMapper;
this.refundLogMapper = refundLogMapper; this.dispensingDetailMapper2 = dispensingDetailMapper; // keep compilation happy
} }
@Override // -------------------------------------------------------------------------
public Page<OrderVerifyDto> getOrderVerifyList(int pageNum, int pageSize, String status) { // 其它业务方法(省略)...
PageHelper.startPage(pageNum, pageSize); // -------------------------------------------------------------------------
List<OrderMain> orderMains = orderMainMapper.selectByStatus(status);
return PageHelper.endPage().toPage(orderMains.stream()
.map(this::convertToOrderVerifyDto)
.collect(Collectors.toList()));
}
/** /**
* 修复 Bug #561医嘱录入后总量单位显示为 null 的问题 * 诊前退号(退款)处理。
* 根因:原转换逻辑未关联 CatalogItem 获取 usageUnit导致前端拼接时 unit 为 null。 *
* 修复:通过 catalogItemId 查询诊疗目录,显式映射 usageUnit 到 DTO 的 totalAmountUnit 字段。 * 该方法在同一个事务内完成以下操作:
* 1. 更新 order_main 状态为 CANCELLED
* 2. 更新所有关联的 order_detail 状态为 CANCELLED
* 3. 记录退款日志;
* 4. 释放已占用的号源schedule_slot、schedule_pool
* 5. 如有已发药记录,回滚发药状态(本项目中暂不涉及)。
*
* @param orderMainId 主订单 ID
* @param refundAmount 退款金额
* @param operator 操作员姓名
*/ */
private OrderVerifyDto convertToOrderVerifyDto(OrderMain main) {
OrderVerifyDto dto = new OrderVerifyDto();
dto.setId(main.getId());
dto.setOrderNo(main.getOrderNo());
dto.setPatientName(main.getPatientName());
dto.setBedNo(main.getBedNo());
dto.setStartTime(main.getStartTime());
dto.setStopTime(main.getStopTime());
dto.setOrderingDoctor(main.getOrderingDoctor());
dto.setStoppingDoctor(main.getStoppingDoctor());
dto.setStatus(main.getStatus());
dto.setTotalCost(main.getTotalCost());
dto.setDiagnosis(main.getDiagnosis());
// 关联明细与目录获取单位信息
if (main.getDetailId() != null) {
OrderDetail detail = orderDetailMapper.selectById(main.getDetailId());
if (detail != null) {
dto.setSingleDose(detail.getSingleDose());
dto.setTotalAmount(String.valueOf(detail.getTotalAmount()));
dto.setFrequencyRoute(detail.getFrequency() + "/" + detail.getRoute());
dto.setDrugName(detail.getItemName());
dto.setSkinTest(detail.getSkinTest());
// 修复 #561从诊疗目录获取使用单位
if (detail.getCatalogItemId() != null) {
CatalogItem catalogItem = catalogItemMapper.selectById(detail.getCatalogItemId());
if (catalogItem != null && StringUtils.hasText(catalogItem.getUsageUnit())) {
dto.setTotalAmountUnit(catalogItem.getUsageUnit());
} else {
dto.setTotalAmountUnit(""); // 兜底默认值,避免前端显示 null
}
}
}
}
return dto;
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void cancelOrder(Long orderId, String reason) { public void refundOrder(Long orderMainId, Double refundAmount, String operator) {
OrderMain main = orderMainMapper.selectById(orderId); // 1. 查询主订单
if (main == null) { OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderMainId);
throw new BusinessException("医嘱不存在"); if (orderMain == null) {
throw new BusinessException("订单不存在");
} }
if (!OrderStatus.PENDING.equals(main.getStatus())) { if (orderMain.getStatus() == OrderStatus.CANCELLED) {
throw new BusinessException("仅可取消待执行状态的医嘱"); throw new BusinessException("订单已退号,无需重复操作");
} }
main.setStatus(OrderStatus.CANCELLED); // 2. 更新主订单状态
main.setCancelReason(reason); orderMain.setStatus(OrderStatus.CANCELLED);
main.setCancelTime(new Date()); orderMain.setUpdateTime(new Date());
orderMainMapper.updateById(main); orderMainMapper.updateByPrimaryKeySelective(orderMain);
if (main.getDetailId() != null) { // 3. 更新明细状态
OrderDetail detail = orderDetailMapper.selectById(main.getDetailId()); OrderDetail queryDetail = new OrderDetail();
if (detail != null) { queryDetail.setOrderMainId(orderMainId);
detail.setStatus(OrderStatus.CANCELLED); List<OrderDetail> details = orderDetailMapper.select(queryDetail);
orderDetailMapper.updateById(detail); if (details != null && !details.isEmpty()) {
} details.forEach(d -> d.setStatus(OrderStatus.CANCELLED));
orderDetailMapper.batchUpdateStatus(details);
} }
// 释放号源 // 4. 记录退款日志
if (main.getScheduleSlotId() != null) { RefundLog refundLog = new RefundLog();
ScheduleSlot slot = scheduleSlotMapper.selectById(main.getScheduleSlotId()); refundLog.setOrderMainId(orderMainId);
if (slot != null) { refundLog.setRefundAmount(refundAmount);
refundLog.setOperator(operator);
refundLog.setRefundTime(new Date());
refundLogMapper.insert(refundLog);
// 5. 释放号源(如果已经占用)
// 这里假设 order_detail 中保存了 schedule_slot_id 与 schedule_pool_id
for (OrderDetail detail : details) {
if (detail.getScheduleSlotId() != null) {
// 释放 slot
ScheduleSlot slot = scheduleSlotMapper.selectByPrimaryKey(detail.getScheduleSlotId());
if (slot != null && slot.getStatus() != ScheduleSlotStatus.AVAILABLE) {
slot.setStatus(ScheduleSlotStatus.AVAILABLE); slot.setStatus(ScheduleSlotStatus.AVAILABLE);
scheduleSlotMapper.updateById(slot); slot.setUpdateTime(new Date());
scheduleSlotMapper.updateByPrimaryKeySelective(slot);
}
}
if (detail.getSchedulePoolId() != null) {
// 释放 pool 使用计数
SchedulePool pool = schedulePoolMapper.selectByPrimaryKey(detail.getSchedulePoolId());
if (pool != null && pool.getUsedNum() != null && pool.getUsedNum() > 0) {
pool.setUsedNum(pool.getUsedNum() - 1);
pool.setUpdateTime(new Date());
schedulePoolMapper.updateByPrimaryKeySelective(pool);
} }
} }
} }
logger.info("订单[{}]已成功退号,退款金额: {}, 操作员: {}", orderMainId, refundAmount, operator);
}
// -------------------------------------------------------------------------
// 其它业务实现(省略)...
// -------------------------------------------------------------------------
} }