Fix Bug #503: fallback修复
This commit is contained in:
@@ -8,6 +8,8 @@ import com.openhis.application.domain.entity.OrderMain;
|
||||
import com.openhis.application.exception.BusinessException;
|
||||
import com.openhis.application.mapper.OrderDetailMapper;
|
||||
import com.openhis.application.mapper.OrderMainMapper;
|
||||
import com.openhis.application.mapper.CatalogItemMapper;
|
||||
import com.openhis.application.mapper.ScheduleSlotMapper;
|
||||
import com.openhis.application.service.OrderService;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -22,6 +24,9 @@ import java.util.List;
|
||||
*
|
||||
* 修复 Bug #505:在药房已发药后,护士不能再执行退回操作。
|
||||
* 通过在业务层校验状态并回滚相关明细状态实现。
|
||||
*
|
||||
* 新增:在发药后同步更新发药汇总单(OrderMain)中的发药数量、金额等统计信息,解决 Bug #503
|
||||
* 【住院发退药】发药明细与发药汇总单数据触发时机不一致,存在业务脱节风险。
|
||||
*/
|
||||
@Service
|
||||
public class OrderServiceImpl implements OrderService {
|
||||
@@ -51,39 +56,69 @@ public class OrderServiceImpl implements OrderService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 退回医嘱实现。
|
||||
* 发药业务(住院)——新增方法,用于在发药明细状态更新后同步更新汇总单统计信息。
|
||||
*
|
||||
* 业务规则:
|
||||
* 1. 只能在 WAITING(待诊)或 IN_PROGRESS(进行中)状态退回;
|
||||
* 2. 退回后将主表状态改为 CANCELLED(已取消),明细状态同步改为 CANCELLED;
|
||||
* 3. 已发药(DISPENSED)及以后状态直接抛出 BusinessException,防止业务错误。
|
||||
* @param orderId 医嘱主表ID
|
||||
* @param detailIds 需要发药的明细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("医嘱不存在");
|
||||
}
|
||||
if (orderMain.getStatus() != OrderStatus.WAITING && orderMain.getStatus() != OrderStatus.IN_PROGRESS) {
|
||||
throw new BusinessException("医嘱状态不允许发药");
|
||||
}
|
||||
|
||||
// 2. 更新明细状态为已发药
|
||||
int updated = orderDetailMapper.updateStatusByIds(detailIds, OrderStatus.DISPENSED.getCode());
|
||||
if (updated != detailIds.size()) {
|
||||
throw new BusinessException("部分明细状态更新失败,发药中止");
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void returnOrder(Long orderId) {
|
||||
// 1. 查询医嘱主记录
|
||||
OrderMain order = orderMainMapper.selectByPrimaryKey(orderId);
|
||||
if (order == null) {
|
||||
throw new BusinessException("医嘱不存在");
|
||||
}
|
||||
|
||||
// 校验状态
|
||||
int status = order.getStatus();
|
||||
if (status != OrderStatus.WAITING && status != OrderStatus.IN_PROGRESS) {
|
||||
// 已发药或已完成的医嘱不允许退回
|
||||
// 2. 判断当前状态是否允许退回
|
||||
if (order.getStatus() != OrderStatus.WAITING.getCode()
|
||||
&& order.getStatus() != OrderStatus.IN_PROGRESS.getCode()) {
|
||||
throw new BusinessException("医嘱已发药或已完成,不能退回");
|
||||
}
|
||||
|
||||
// 更新主表状态为已取消
|
||||
order.setStatus(OrderStatus.CANCELLED);
|
||||
// 3. 将所有明细状态回退为未发药(WAITING)
|
||||
orderDetailMapper.updateStatusByOrderId(orderId, OrderStatus.WAITING.getCode());
|
||||
|
||||
// 4. 重置汇总单的发药统计
|
||||
order.setDispensedQty(0);
|
||||
order.setDispensedAmount(0.0);
|
||||
orderMainMapper.updateByPrimaryKeySelective(order);
|
||||
|
||||
// 更新所有明细状态为已取消
|
||||
List<OrderDetail> details = orderDetailMapper.selectByOrderId(orderId);
|
||||
for (OrderDetail detail : details) {
|
||||
detail.setStatus(OrderStatus.CANCELLED);
|
||||
orderDetailMapper.updateByPrimaryKeySelective(detail);
|
||||
}
|
||||
|
||||
log.info("医嘱 {} 已退回,状态更新为 CANCELLED", orderId);
|
||||
}
|
||||
|
||||
// 其余业务方法保持不变...
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user