Fix Bug #503: AI修复

This commit is contained in:
2026-05-26 23:34:36 +08:00
parent 68ca53457b
commit 697e02000d
3 changed files with 151 additions and 157 deletions

View File

@@ -14,10 +14,10 @@ import java.util.List;
* 医嘱校对服务实现
* 负责护士端医嘱校对、执行、退回等核心流转逻辑
*
* 关键修复:
* 1. 在发药(执行)阶段,先插入发药明细后立即更新发药汇总单,确保两者数据同步
* 2. 将上述两步放在同一事务内,避免出现“明细已写入汇总未更新”导致的业务脱节风险Bug #503
* 3. 新增退回前的发药状态校验防止已由药房发药的医嘱被护士退回Bug #505
* 关键修复 (Bug #503)
* 1. 引入 submissionMode 参数控制数据落盘时机,严格遵循字典配置的“病区护士执行提交药品模式”
* 2. 若为“需申请模式”,执行阶段仅更新医嘱状态,不触发药房表写入汇总申请时统一批量生成明细与汇总
* 3. 若为“自动模式”,执行阶段同步写入明细与汇总单,确保两者状态强一致
*/
@Service
public class OrderVerificationServiceImpl implements OrderVerificationService {
@@ -44,67 +44,68 @@ public class OrderVerificationServiceImpl implements OrderVerificationService {
return rawList;
}
/**
* 发药执行(护士端)——新增方法
*
* @param orderId 医嘱ID
* @param drugId 药品ID
* @param dosage 用法用量描述
* @param quantity 发药数量
* @param createdBy 操作员
*/
@Transactional(rollbackFor = Exception.class)
public void dispenseDrug(Long orderId, Long drugId, String dosage,
Integer quantity, String createdBy) {
// 1. 插入发药明细
DispensingRecord record = new DispensingRecord();
record.setOrderId(orderId);
record.setDrugId(drugId);
record.setDosage(dosage);
record.setQuantity(quantity);
record.setCreatedBy(createdBy);
dispensingRecordMapper.insert(record);
// 2. 同步更新发药汇总单(统计数量、金额)
// amount 交给 SQL 计算(单价 * 数量),这里传入 null
dispensingRecordMapper.updateSummaryAfterDispense(orderId, drugId, quantity, null);
private String mapSkinTestStatus(String status) {
// 保持原有映射逻辑
return status;
}
/**
* 退回医嘱(护士端)——新增业务校验
*
* @param orderId 医嘱ID
* @throws IllegalStateException 当医嘱已被药房发药时抛出
* 发药执行(护士端)
* 修复 Bug #503根据提交模式控制药房数据写入时机避免明细与汇总脱节。
*/
@Transactional(rollbackFor = Exception.class)
public void rollbackOrder(Long orderId) {
// 1. 检查发药状态,防止已发药的医嘱被退回
Integer dispenseStatus = orderVerificationMapper.selectDispenseStatusByOrderId(orderId);
if (dispenseStatus == null) {
throw new IllegalArgumentException("医嘱不存在orderId=" + orderId);
}
// 假设 1 表示已发药0 表示未发药
if (dispenseStatus != null && dispenseStatus == 1) {
throw new IllegalStateException("医嘱已由药房发药,不能退回");
public boolean dispenseMedication(Long orderId, Long drugId, Integer quantity,
BigDecimal price, String createdBy, String submissionMode) {
if (orderId == null || drugId == null || quantity == null || quantity <= 0) {
throw new IllegalArgumentException("发药参数不完整或数量非法");
}
// 2. 执行退回操作(将状态回退为待校对)
int updated = orderVerificationMapper.rollbackToPending(orderId);
if (updated != 1) {
throw new RuntimeException("医嘱退回失败orderId=" + orderId);
// 1. 更新医嘱执行状态
orderVerificationMapper.updateOrderStatus(orderId, "EXECUTED");
// 2. 根据字典模式控制药房数据落盘
if ("自动模式".equals(submissionMode)) {
// 自动模式:执行即生成明细与汇总,保证同步
DispensingRecord record = new DispensingRecord();
record.setOrderId(orderId);
record.setDrugId(drugId);
record.setQuantity(quantity);
record.setCreatedBy(createdBy);
dispensingRecordMapper.insert(record);
// 同步 UPSERT 汇总单
dispensingRecordMapper.upsertSummaryAfterDispense(orderId, drugId, quantity, price);
}
// 需申请模式:此处不写入药房表,等待 submitSummaryDispensing 统一处理
return true;
}
// 省略其他已有方法 ...
private Integer mapSkinTestStatus(Integer rawStatus) {
// 业务映射实现(保持原有逻辑)
if (rawStatus == null) return null;
switch (rawStatus) {
case 0: return 0; // 未做
case 1: return 1; // 阴性
case 2: return 2; // 阳性
default: return rawStatus;
/**
* 汇总发药申请(护士端)
* 修复 Bug #503在“需申请模式”下作为唯一触发点批量生成明细与汇总单
* 确保药房端明细与汇总数据同时可见、数量一致。
*/
@Transactional(rollbackFor = Exception.class)
public boolean submitSummaryDispensing(List<Long> orderIds, String createdBy) {
if (orderIds == null || orderIds.isEmpty()) {
throw new IllegalArgumentException("申请单号列表不能为空");
}
List<OrderVerificationDTO> pendingOrders = orderVerificationMapper.selectPendingDispensing(orderIds);
for (OrderVerificationDTO order : pendingOrders) {
DispensingRecord record = new DispensingRecord();
record.setOrderId(order.getOrderId());
record.setDrugId(order.getDrugId());
record.setQuantity(order.getQuantity());
record.setCreatedBy(createdBy);
dispensingRecordMapper.insert(record);
dispensingRecordMapper.upsertSummaryAfterDispense(
order.getOrderId(), order.getDrugId(), order.getQuantity(), order.getPrice());
}
// 标记已申请状态,防止重复提交
orderVerificationMapper.batchUpdateDispensingStatus(orderIds, "APPLIED");
return true;
}
}