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;
}
// ... 现有的 listQueue、listQueueHistory、listPending 实现保持不变 ...
@Override
public OrderMain getOrderById(Long orderId) {
return orderMainMapper.selectByPrimaryKey(orderId);
}
/**
* 发药业务(住院)——新增方法,用于在发药明细状态更新后同步更新汇总单统计信息
* 发药操作(住院/门诊均使用此方法)
* 完成明细状态更新后,同步更新对应的发药汇总单统计信息,确保明细与汇总数据一致。
*
* @param orderId 医嘱主表ID
* @param detailIds 需要发药的明细ID列表
* @param detailId 发药明细ID
*/
@Transactional(rollbackFor = Exception.class)
public void dispenseMedication(Long orderId, List<Long> detailIds) {
// 1. 校验医嘱主表状态
OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderId);
if (orderMain == null) {
throw new BusinessException("医嘱不存在");
@Override
public void dispenseMedication(Long detailId) {
// 1. 查询明细,校验状态
OrderDetail detail = orderDetailMapper.selectByPrimaryKey(detailId);
if (detail == null) {
throw new BusinessException("发药明细不存在");
}
if (orderMain.getStatus() != OrderStatus.WAITING && orderMain.getStatus() != OrderStatus.IN_PROGRESS) {
throw new BusinessException("医嘱状态不允许发药");
if (!OrderStatus.PENDING_DISPENSE.getCode().equals(detail.getStatus())) {
throw new BusinessException("当前明细状态不允许发药");
}
// 2. 更新明细状态为已发药
int updated = orderDetailMapper.updateStatusByIds(detailIds, OrderStatus.DISPENSED.getCode());
if (updated != detailIds.size()) {
throw new BusinessException("部分明细状态更新失败,发药中止");
detail.setStatus(OrderStatus.DISPENSED.getCode());
int updated = orderDetailMapper.updateByPrimaryKeySelective(detail);
if (updated != 1) {
throw new BusinessException("发药明细状态更新失败");
}
log.info("发药明细 {} 状态更新为已发药", detailId);
// 3. 重新计算汇总单的发药数量、金额等
List<OrderDetail> dispensedDetails = orderDetailMapper.selectByIds(detailIds);
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);
// 3. 同步更新汇总单统计信息
syncOrderMainStatistics(detail.getOrderMainId());
}
@Override
/**
* 退药操作。退药时需要回滚明细状态并同步更新汇总单统计信息。
*
* @param detailId 退药明细ID
*/
@Transactional(rollbackFor = Exception.class)
public void returnOrder(Long orderId) {
// 1. 查询医嘱主记录
OrderMain order = orderMainMapper.selectByPrimaryKey(orderId);
if (order == null) {
throw new BusinessException("医嘱不存在");
@Override
public void returnMedication(Long detailId) {
// 1. 查询明细,校验状态只能在已发药状态下退药
OrderDetail detail = orderDetailMapper.selectByPrimaryKey(detailId);
if (detail == null) {
throw new BusinessException("退药明细不存在");
}
if (!OrderStatus.DISPENSED.getCode().equals(detail.getStatus())) {
throw new BusinessException("只有已发药状态的明细才能退药");
}
// 2. 判断当前状态是否允许退回
if (order.getStatus() != OrderStatus.WAITING.getCode()
&& order.getStatus() != OrderStatus.IN_PROGRESS.getCode()) {
throw new BusinessException("医嘱已发药或已完成,不能退回");
// 2. 更新明细状态为已退药
detail.setStatus(OrderStatus.RETURNED.getCode());
int updated = orderDetailMapper.updateByPrimaryKeySelective(detail);
if (updated != 1) {
throw new BusinessException("退药明细状态更新失败");
}
log.info("退药明细 {} 状态更新为已退药", detailId);
// 3. 将所有明细状态回退为未发药WAITING
orderDetailMapper.updateStatusByOrderId(orderId, OrderStatus.WAITING.getCode());
// 4. 重置汇总单的发药统计
order.setDispensedQty(0);
order.setDispensedAmount(0.0);
orderMainMapper.updateByPrimaryKeySelective(order);
// 3. 同步更新汇总单统计信息
syncOrderMainStatistics(detail.getOrderMainId());
}
// 其余业务方法保持不变...
/**
* 根据明细所属的 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);
}
// 下面保留原有的业务方法(如创建医嘱、查询等),未作改动,仅展示占位
// ...
}