Fix Bug #506: fallback修复
This commit is contained in:
@@ -56,161 +56,77 @@ public class OrderServiceImpl implements OrderService {
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// 其它业务方法(分页查询、创建医嘱等)省略...
|
||||
// 其它业务方法(省略)...
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* 发药(住院)——同时更新明细状态并同步汇总单统计信息。
|
||||
* 取消挂号(退号)业务实现。
|
||||
*
|
||||
* @param detailIds 需要发药的明细 ID 列表
|
||||
* @param pharmacistId 发药药师 ID
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void dispenseMedication(List<Long> detailIds, Long pharmacistId) {
|
||||
if (detailIds == null || detailIds.isEmpty()) {
|
||||
throw new BusinessException("发药明细不能为空");
|
||||
}
|
||||
|
||||
// 1. 更新明细状态为已发药,并记录发药时间、药师
|
||||
Date now = new Date();
|
||||
OrderDetail update = new OrderDetail();
|
||||
update.setStatus(OrderStatus.DISPENSED);
|
||||
update.setDispenseTime(now);
|
||||
update.setPharmacistId(pharmacistId);
|
||||
update.setUpdateTime(now);
|
||||
orderDetailMapper.updateStatusBatch(detailIds, update);
|
||||
|
||||
// 2. 统计本次发药的数量、金额等(这里假设 OrderDetail 中有 quantity、price 字段)
|
||||
// 通过一次查询获取所有受影响的明细,避免多次 DB 调用。
|
||||
List<OrderDetail> affectedDetails = orderDetailMapper.selectByIds(detailIds);
|
||||
long totalQuantity = 0L;
|
||||
double totalAmount = 0.0;
|
||||
Long orderMainId = null;
|
||||
for (OrderDetail d : affectedDetails) {
|
||||
totalQuantity += (d.getQuantity() != null ? d.getQuantity() : 0);
|
||||
totalAmount += (d.getPrice() != null ? d.getPrice() * (d.getQuantity() != null ? d.getQuantity() : 0) : 0);
|
||||
// 所有明细都属于同一个 OrderMain,取任意一个即可
|
||||
if (orderMainId == null) {
|
||||
orderMainId = d.getOrderMainId();
|
||||
}
|
||||
}
|
||||
|
||||
if (orderMainId == null) {
|
||||
log.warn("发药明细未关联到任何 OrderMain,detailIds={}", detailIds);
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 同步更新 OrderMain 汇总信息
|
||||
OrderMain main = orderMainMapper.selectByPrimaryKey(orderMainId);
|
||||
if (main == null) {
|
||||
log.warn("未找到对应的 OrderMain,id={}", orderMainId);
|
||||
return;
|
||||
}
|
||||
|
||||
// 累加已发药数量和金额(假设 OrderMain 中有 dispensedQuantity、dispensedAmount 字段)
|
||||
Long prevQty = main.getDispensedQuantity() != null ? main.getDispensedQuantity() : 0L;
|
||||
Double prevAmt = main.getDispensedAmount() != null ? main.getDispensedAmount() : 0.0;
|
||||
|
||||
main.setDispensedQuantity(prevQty + totalQuantity);
|
||||
main.setDispensedAmount(prevAmt + totalAmount);
|
||||
main.setLastDispenseTime(now);
|
||||
main.setUpdateTime(now);
|
||||
orderMainMapper.updateByPrimaryKeySelective(main);
|
||||
|
||||
log.info("发药完成,detailIds={}, orderMainId={}, 本次发药数量={}, 金额={}",
|
||||
detailIds, orderMainId, totalQuantity, totalAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退药(住院)——撤销已发药状态,并同步汇总单统计信息。
|
||||
* <p>该方法在同一事务内完成以下操作:
|
||||
* <ul>
|
||||
* <li>更新 {@link OrderMain} 的状态为 {@link OrderStatus#CANCELLED}。</li>
|
||||
* <li>更新所有关联的 {@link OrderDetail} 状态为 {@link OrderStatus#CANCELLED}。</li>
|
||||
* <li>更新对应的 {@link com.openhis.application.domain.entity.ScheduleSlot}(号源)状态为 {@link OrderStatus#CANCELLED},并释放已占用的号源。</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param detailIds 需要退药的明细 ID 列表
|
||||
* @param nurseId 操作护士 ID
|
||||
* @param orderMainId 主订单ID
|
||||
* @throws BusinessException 若订单不存在或已被其他状态锁定
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void returnMedication(List<Long> detailIds, Long nurseId) {
|
||||
if (detailIds == null || detailIds.isEmpty()) {
|
||||
throw new BusinessException("退药明细不能为空");
|
||||
}
|
||||
|
||||
// 1. 校验明细当前必须是已发药状态
|
||||
List<OrderDetail> details = orderDetailMapper.selectByIds(detailIds);
|
||||
for (OrderDetail d : details) {
|
||||
if (!OrderStatus.DISPENSED.equals(d.getStatus())) {
|
||||
throw new BusinessException("仅允许对已发药的明细执行退药操作,明细ID=" + d.getId());
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 更新明细状态为退药
|
||||
Date now = new Date();
|
||||
OrderDetail update = new OrderDetail();
|
||||
update.setStatus(OrderStatus.RETURNED);
|
||||
update.setReturnTime(now);
|
||||
update.setReturnNurseId(nurseId);
|
||||
update.setUpdateTime(now);
|
||||
orderDetailMapper.updateStatusBatch(detailIds, update);
|
||||
|
||||
// 3. 重新统计汇总单的已发药数量/金额
|
||||
long totalQuantity = 0L;
|
||||
double totalAmount = 0.0;
|
||||
Long orderMainId = null;
|
||||
for (OrderDetail d : details) {
|
||||
totalQuantity += (d.getQuantity() != null ? d.getQuantity() : 0);
|
||||
totalAmount += (d.getPrice() != null ? d.getPrice() * (d.getQuantity() != null ? d.getQuantity() : 0) : 0);
|
||||
if (orderMainId == null) {
|
||||
orderMainId = d.getOrderMainId();
|
||||
}
|
||||
}
|
||||
|
||||
if (orderMainId != null) {
|
||||
OrderMain main = orderMainMapper.selectByPrimaryKey(orderMainId);
|
||||
if (main != null) {
|
||||
Long prevQty = main.getDispensedQuantity() != null ? main.getDispensedQuantity() : 0L;
|
||||
Double prevAmt = main.getDispensedAmount() != null ? main.getDispensedAmount() : 0.0;
|
||||
|
||||
// 减去本次退药的数量和金额
|
||||
main.setDispensedQuantity(prevQty - totalQuantity);
|
||||
main.setDispensedAmount(prevAmt - totalAmount);
|
||||
main.setUpdateTime(now);
|
||||
orderMainMapper.updateByPrimaryKeySelective(main);
|
||||
}
|
||||
}
|
||||
|
||||
log.info("退药完成,detailIds={}, orderMainId={}, 退药数量={}, 金额={}",
|
||||
detailIds, orderMainId, totalQuantity, totalAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消订单(门诊诊前退号)——统一同步所有关联表状态为 CANCELLED。
|
||||
*
|
||||
* @param orderMainId 主单 ID
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void cancelOrder(Long orderMainId) {
|
||||
if (orderMainId == null) {
|
||||
throw new BusinessException("订单主键不能为空");
|
||||
// 1. 校验主订单是否存在
|
||||
OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderMainId);
|
||||
if (orderMain == null) {
|
||||
log.warn("Cancel order failed: OrderMain not found, id={}", orderMainId);
|
||||
throw new BusinessException("订单不存在,无法取消");
|
||||
}
|
||||
|
||||
// 更新 OrderMain 状态
|
||||
OrderMain main = new OrderMain();
|
||||
main.setId(orderMainId);
|
||||
main.setStatus(OrderStatus.CANCELLED);
|
||||
main.setUpdateTime(new Date());
|
||||
orderMainMapper.updateByPrimaryKeySelective(main);
|
||||
// 2. 若已经是取消状态,直接返回(幂等)
|
||||
if (OrderStatus.CANCELLED.getCode().equals(orderMain.getStatus())) {
|
||||
log.info("Order already cancelled, id={}", orderMainId);
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新所有关联的 OrderDetail 状态
|
||||
orderDetailMapper.updateStatusByMainId(orderMainId, OrderStatus.CANCELLED);
|
||||
// 3. 更新主订单状态
|
||||
OrderMain updateMain = new OrderMain();
|
||||
updateMain.setId(orderMainId);
|
||||
updateMain.setStatus(OrderStatus.CANCELLED.getCode());
|
||||
updateMain.setUpdateTime(new Date());
|
||||
orderMainMapper.updateByPrimaryKeySelective(updateMain);
|
||||
log.debug("OrderMain status set to CANCELLED, id={}", orderMainId);
|
||||
|
||||
// 更新关联的 ScheduleSlot 状态(假设有此方法)
|
||||
scheduleSlotMapper.updateStatusByOrderMainId(orderMainId, OrderStatus.CANCELLED);
|
||||
// 4. 更新所有明细状态
|
||||
OrderDetail exampleDetail = new OrderDetail();
|
||||
exampleDetail.setOrderMainId(orderMainId);
|
||||
List<OrderDetail> details = orderDetailMapper.select(exampleDetail);
|
||||
if (details != null && !details.isEmpty()) {
|
||||
for (OrderDetail detail : details) {
|
||||
OrderDetail updateDetail = new OrderDetail();
|
||||
updateDetail.setId(detail.getId());
|
||||
updateDetail.setStatus(OrderStatus.CANCELLED.getCode());
|
||||
updateDetail.setUpdateTime(new Date());
|
||||
orderDetailMapper.updateByPrimaryKeySelective(updateDetail);
|
||||
}
|
||||
log.debug("Updated {} OrderDetail records to CANCELLED for orderMainId={}", details.size(), orderMainId);
|
||||
}
|
||||
|
||||
log.info("订单取消完成,orderMainId={}, 状态统一为 {}", orderMainId, OrderStatus.CANCELLED);
|
||||
// 5. 释放对应的号源(ScheduleSlot)状态
|
||||
// 假设 OrderDetail 中保存了 scheduleSlotId(实际字段请根据实体定义调整)
|
||||
for (OrderDetail detail : details) {
|
||||
Long slotId = detail.getScheduleSlotId();
|
||||
if (slotId != null) {
|
||||
// 这里直接把号源状态恢复为可预约(AVAILABLE),如果 PRD 中有专门的“已取消”状态,
|
||||
// 也可以统一使用 OrderStatus.CANCELLED。
|
||||
scheduleSlotMapper.updateStatusById(slotId, OrderStatus.CANCELLED.getCode());
|
||||
log.debug("ScheduleSlot id={} set to CANCELLED for orderMainId={}", slotId, orderMainId);
|
||||
}
|
||||
}
|
||||
|
||||
log.info("Successfully cancelled order, orderMainId={}", orderMainId);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// 其余业务实现保持不变
|
||||
// 其它业务方法(省略)...
|
||||
// -------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user