Fix Bug #503: fallback修复

This commit is contained in:
2026-05-27 03:45:33 +08:00
parent de06643dc7
commit 230db2502f

View File

@@ -48,77 +48,95 @@ public class OrderServiceImpl implements OrderService {
this.scheduleSlotMapper = scheduleSlotMapper; this.scheduleSlotMapper = scheduleSlotMapper;
} }
// ... 现有的 listQueue、listQueueHistory、listPending 实现保持不变 ...
@Override
public OrderMain getOrderById(Long orderId) {
return orderMainMapper.selectByPrimaryKey(orderId);
}
/** /**
* 发药业务(住院)——新增方法,用于在发药明细状态更新后同步更新汇总单统计信息 * 发药操作(住院/门诊均使用此方法)
* 完成明细状态更新后,同步更新对应的发药汇总单统计信息,确保明细与汇总数据一致。
* *
* @param orderId 医嘱主表ID * @param detailId 发药明细ID
* @param detailIds 需要发药的明细ID列表
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void dispenseMedication(Long orderId, List<Long> detailIds) { @Override
// 1. 校验医嘱主表状态 public void dispenseMedication(Long detailId) {
OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderId); // 1. 查询明细,校验状态
if (orderMain == null) { OrderDetail detail = orderDetailMapper.selectByPrimaryKey(detailId);
throw new BusinessException("医嘱不存在"); if (detail == null) {
throw new BusinessException("发药明细不存在");
} }
if (orderMain.getStatus() != OrderStatus.WAITING && orderMain.getStatus() != OrderStatus.IN_PROGRESS) { if (!OrderStatus.PENDING_DISPENSE.getCode().equals(detail.getStatus())) {
throw new BusinessException("医嘱状态不允许发药"); throw new BusinessException("当前明细状态不允许发药");
} }
// 2. 更新明细状态为已发药 // 2. 更新明细状态为已发药
int updated = orderDetailMapper.updateStatusByIds(detailIds, OrderStatus.DISPENSED.getCode()); detail.setStatus(OrderStatus.DISPENSED.getCode());
if (updated != detailIds.size()) { int updated = orderDetailMapper.updateByPrimaryKeySelective(detail);
throw new BusinessException("部分明细状态更新失败,发药中止"); if (updated != 1) {
throw new BusinessException("发药明细状态更新失败");
} }
log.info("发药明细 {} 状态更新为已发药", detailId);
// 3. 重新计算汇总单的发药数量、金额等 // 3. 同步更新汇总单统计信息
List<OrderDetail> dispensedDetails = orderDetailMapper.selectByIds(detailIds); syncOrderMainStatistics(detail.getOrderMainId());
int totalQty = dispensedDetails.stream().mapToInt(OrderDetail::getQuantity).sum();
double totalAmount = dispensedDetails.stream()
.mapToDouble(d -> d.getQuantity() * d.getUnitPrice())
.sum();
// 4. 更新汇总单统计字段(假设字段为 dispensedQty、dispensedAmount
orderMain.setDispensedQty(orderMain.getDispensedQty() + totalQty);
orderMain.setDispensedAmount(orderMain.getDispensedAmount() + totalAmount);
// 若所有明细均已发药,则更新主表状态为已发药
int remaining = orderDetailMapper.countByOrderIdAndStatus(orderId, OrderStatus.WAITING.getCode());
if (remaining == 0) {
orderMain.setStatus(OrderStatus.DISPENSED.getCode());
}
orderMainMapper.updateByPrimaryKeySelective(orderMain);
} }
@Override /**
* 退药操作。退药时需要回滚明细状态并同步更新汇总单统计信息。
*
* @param detailId 退药明细ID
*/
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void returnOrder(Long orderId) { @Override
// 1. 查询医嘱主记录 public void returnMedication(Long detailId) {
OrderMain order = orderMainMapper.selectByPrimaryKey(orderId); // 1. 查询明细,校验状态只能在已发药状态下退药
if (order == null) { OrderDetail detail = orderDetailMapper.selectByPrimaryKey(detailId);
throw new BusinessException("医嘱不存在"); if (detail == null) {
throw new BusinessException("退药明细不存在");
}
if (!OrderStatus.DISPENSED.getCode().equals(detail.getStatus())) {
throw new BusinessException("只有已发药状态的明细才能退药");
} }
// 2. 判断当前状态是否允许退回 // 2. 更新明细状态为已退药
if (order.getStatus() != OrderStatus.WAITING.getCode() detail.setStatus(OrderStatus.RETURNED.getCode());
&& order.getStatus() != OrderStatus.IN_PROGRESS.getCode()) { int updated = orderDetailMapper.updateByPrimaryKeySelective(detail);
throw new BusinessException("医嘱已发药或已完成,不能退回"); if (updated != 1) {
throw new BusinessException("退药明细状态更新失败");
} }
log.info("退药明细 {} 状态更新为已退药", detailId);
// 3. 将所有明细状态回退为未发药WAITING // 3. 同步更新汇总单统计信息
orderDetailMapper.updateStatusByOrderId(orderId, OrderStatus.WAITING.getCode()); syncOrderMainStatistics(detail.getOrderMainId());
// 4. 重置汇总单的发药统计
order.setDispensedQty(0);
order.setDispensedAmount(0.0);
orderMainMapper.updateByPrimaryKeySelective(order);
} }
// 其余业务方法保持不变... /**
* 根据明细所属的 OrderMainId 重新计算并更新发药数量、金额等统计字段。
* 该方法在发药、退药等会改变统计数据的业务后统一调用,确保汇总单数据与明细保持强一致。
*
* @param orderMainId 汇总单ID
*/
private void syncOrderMainStatistics(Long orderMainId) {
// 统计已发药(含已退药)明细的数量和金额
List<OrderDetail> dispensedDetails = orderDetailMapper.selectByOrderMainIdAndStatus(
orderMainId,
Arrays.asList(OrderStatus.DISPENSED.getCode(), OrderStatus.RETURNED.getCode())
);
int totalDispensedQty = 0;
double totalDispensedAmount = 0.0;
for (OrderDetail d : dispensedDetails) {
totalDispensedQty += (d.getQuantity() != null ? d.getQuantity() : 0);
totalDispensedAmount += (d.getAmount() != null ? d.getAmount() : 0.0);
}
OrderMain orderMain = new OrderMain();
orderMain.setId(orderMainId);
orderMain.setDispensedQuantity(totalDispensedQty);
orderMain.setDispensedAmount(totalDispensedAmount);
orderMainMapper.updateByPrimaryKeySelective(orderMain);
log.debug("同步汇总单 {} 发药统计:数量={}, 金额={}", orderMainId, totalDispensedQty, totalDispensedAmount);
}
// 下面保留原有的业务方法(如创建医嘱、查询等),未作改动,仅展示占位
// ...
} }