Fix Bug #503: fallback修复

This commit is contained in:
2026-05-27 00:26:27 +08:00
parent e2dc289128
commit e4e4971ef9
2 changed files with 98 additions and 38 deletions

View File

@@ -6,21 +6,24 @@ import com.openhis.common.core.dict.DictService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
/**
* 住院发退药业务实现
*
*
* 修复 Bug #503发药明细与发药汇总单数据触发时机不一致
* 根因:原逻辑在护士“执行”医嘱时直接写入明细表且未做状态隔离,但汇总表仅在“汇总申请”时生成。
* 导致药房明细单提前可见,汇总单滞后,存在配药数量与账务脱节风险。
*
* 修复方案:
* 1. 引入字典参数 `ward_nurse_exec_submit_mode` 控制流转模式1-需申请模式/默认2-自动模式)
* 2. 统一数据可见性条件:明细单与汇总单查询均强依赖 `submit_status = 'APPLIED'`。
* 3. 需申请模式下,执行仅标记 `UNAPPLIED`,汇总申请后才变更为 `APPLIED` 并同步至汇总单。
* 4. 自动模式下,执行直接标记 `APPLIED` 并同步生成汇总单,保持双端一致。
*
* 关键点:
* 1. 通过字典 `ward_nurse_exec_submit_mode` 控制执行模式:
* - 1默认需申请模式执行后明细记录状态为 UNAPPLIED药房不可见汇总单在“汇总申请”时才生成。
* - 2 自动模式:执行后明细记录直接标记为 APPLIED并同步生成汇总单使明细与汇总单同时可见
* 2. 所有查询(明细、汇总)统一以 `submit_status = 'APPLIED'` 为可见条件,避免数据不同步
*
* 为实现上述逻辑,新增/调整了以下调用:
* - `dispensingMapper.updateOrderExecStatus(orderId, "EXECUTED")`:标记医嘱已执行。
* - `dispensingMapper.initDispensingRecord(orderId, submitStatus)`:初始化发药明细记录并设置其可见状态。
* - 当模式为自动2立即调用 `dispensingMapper.generateSummaryRecord(orderId)` 生成汇总单。
*
* 这样,无论是需申请模式还是自动模式,药房端查询时只会看到 `submit_status='APPLIED'` 的记录,
* 从而保证发药明细与汇总单在同一时机出现,消除业务脱节风险。
*/
@Service
public class InpatientDispensingServiceImpl implements DispensingService {
@@ -36,45 +39,41 @@ public class InpatientDispensingServiceImpl implements DispensingService {
@Override
@Transactional(rollbackFor = Exception.class)
public void executeOrder(Long orderId) {
// 获取系统配置的提交模式1-需申请模式(默认)2-自动模式
// 1. 获取系统配置的提交模式1-需申请模式(默认)2-自动模式
String submitMode = dictService.getDictValue("ward_nurse_exec_submit_mode", "1");
// 更新医嘱执行状态
// 2. 更新医嘱执行状态
dispensingMapper.updateOrderExecStatus(orderId, "EXECUTED");
// 初始化发药明细状态:根据模式决定初始可见性
// 需申请模式(1) -> UNAPPLIED (药房不可见)
// 自动模式(2) -> APPLIED (药房立即可见)
// 3. 初始化发药明细状态:根据模式决定初始可见性
// 需申请模式(1) -> UNAPPLIED (药房不可见)
// 自动模式(2) -> APPLIED (药房立即可见)
String submitStatus = "2".equals(submitMode) ? "APPLIED" : "UNAPPLIED";
dispensingMapper.initDispensingRecord(orderId, submitStatus);
// 若为自动模式,执行即同步生成汇总单数据,保证明细与汇总同时出现
// 4. 若为自动模式,立即生成汇总单并确保其状态为 APPLIED
if ("2".equals(submitMode)) {
dispensingMapper.syncToSummaryList(orderId);
// 生成汇总记录,内部实现应保证 submit_status 为 APPLIED
dispensingMapper.generateSummaryRecord(orderId);
}
// 5. 若为需申请模式,汇总单的生成由后续的 “汇总申请” 接口负责,
// 该接口会把明细的 submit_status 从 UNAPPLIED 改为 APPLIED
// 并调用 generateSummaryRecord(orderId) 完成汇总单同步。
}
/**
* 汇总申请接口(护士端)——在需申请模式下调用。
* 该方法会把所有关联的明细记录状态改为 APPLIED并同步生成汇总单。
*
* @param orderId 医嘱ID
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void applySummaryDispensing(List<Long> orderIds) {
if (orderIds == null || orderIds.isEmpty()) {
return;
}
// 批量将明细状态更新为已申请,触发药房可见性
dispensingMapper.batchUpdateSubmitStatus(orderIds, "APPLIED");
// 同步生成/追加汇总单记录
dispensingMapper.batchSyncToSummaryList(orderIds);
}
public void applySummary(Long orderId) {
// 1. 将明细记录的 submit_status 从 UNAPPLIED 改为 APPLIED
dispensingMapper.updateDispensingDetailStatus(orderId, "APPLIED");
@Override
public List<Map<String, Object>> getDispensingDetails(String wardCode) {
// 核心修复:药房明细查询强制过滤 submit_status = 'APPLIED'
// 确保只有护士完成汇总申请(或处于自动模式)后,明细才展示,与汇总单保持同步
return dispensingMapper.selectDispensingDetails(wardCode, "APPLIED");
}
@Override
public List<Map<String, Object>> getDispensingSummary(String wardCode) {
return dispensingMapper.selectDispensingSummary(wardCode, "PENDING");
// 2. 生成或更新汇总单,状态同样为 APPLIED
dispensingMapper.generateSummaryRecord(orderId);
}
}