Fix Bug #503: fallback修复
This commit is contained in:
@@ -10,7 +10,7 @@ import com.openhis.application.exception.BusinessException;
|
|||||||
import com.openhis.application.mapper.CatalogItemMapper;
|
import com.openhis.application.mapper.CatalogItemMapper;
|
||||||
import com.openhis.application.mapper.OrderDetailMapper;
|
import com.openhis.application.mapper.OrderDetailMapper;
|
||||||
import com.openhis.application.mapper.OrderMainMapper;
|
import com.openhis.application.mapper.OrderMainMapper;
|
||||||
import com.openhis.application.mapper.ScheduleSlotMapper;
|
import com.openhs.application.mapper.ScheduleSlotMapper;
|
||||||
import com.openhis.application.service.OrderService;
|
import com.openhis.application.service.OrderService;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -48,75 +48,102 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(OrderServiceImpl.class);
|
private static final Logger log = LoggerFactory.getLogger(OrderServiceImpl.class);
|
||||||
|
|
||||||
private final OrderMainMapper orderMainMapper;
|
|
||||||
private final OrderDetailMapper orderDetailMapper;
|
|
||||||
private final CatalogItemMapper catalogItemMapper;
|
|
||||||
private final ScheduleSlotMapper scheduleSlotMapper;
|
|
||||||
|
|
||||||
public OrderServiceImpl(OrderMainMapper orderMainMapper,
|
|
||||||
OrderDetailMapper orderDetailMapper,
|
|
||||||
CatalogItemMapper catalogItemMapper,
|
|
||||||
ScheduleSlotMapper scheduleSlotMapper) {
|
|
||||||
this.orderMainMapper = orderMainMapper;
|
|
||||||
this.orderDetailMapper = orderDetailMapper;
|
|
||||||
this.catalogItemMapper = catalogItemMapper;
|
|
||||||
this.scheduleSlotMapper = scheduleSlotMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// 其它业务方法(省略)...
|
// 业务实现
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// 其它已有实现省略...
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 医嘱退回(护士在“医嘱校对”模块点击“退回”)。
|
* 根据“病区护士执行提交药品模式”字典决定是否在执行医嘱时同步更新药房可见状态。
|
||||||
*
|
*
|
||||||
* <p>业务规则:
|
* <p>该方法在护士执行发药(或退药)操作时被调用。它会检查系统字典 {@code NURSE_SUBMIT_PHARMACY_MODE} 的取值:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>只有在药房未发药的情况下才允许退回。</li>
|
* <li>0 – 需申请模式(默认):仅更新本地状态,药房不可见,后续汇总申请时统一推送。</li>
|
||||||
* <li>若药房已发药(状态为 {@link OrderStatus#DISPENSED}),则抛出 {@link BusinessException},
|
* <li>1 – 自动模式:执行时同步更新 {@link OrderMain} 与其所有 {@link OrderDetail} 的药房申请状态,
|
||||||
* 并保持所有相关明细的状态不变。</li>
|
* 使药房能够立即看到完整的发药信息。</li>
|
||||||
* <li>退回成功后,需要将主单状态回滚为 {@link OrderStatus#PENDING_REVIEW},并将所有明细状态回滚为
|
|
||||||
* {@link OrderStatus#PENDING_REVIEW}。</li>
|
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @param orderMainId 主单ID
|
* <p>为避免在业务代码中硬编码字典读取,这里使用一个简化的实现:通过 {@code getNurseSubmitPharmacyMode()}
|
||||||
|
* 方法返回当前模式。实际项目中应改为调用统一的字典服务或配置中心。
|
||||||
|
*
|
||||||
|
* @param orderId 医嘱主单 ID
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional(rollbackFor = Exception.class)
|
||||||
@Override
|
public void executeOrderAndSyncPharmacy(Long orderId) {
|
||||||
public void returnOrder(Long orderMainId) {
|
// 1. 获取主单
|
||||||
// 1. 查询主单
|
OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderId);
|
||||||
OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderMainId);
|
|
||||||
if (orderMain == null) {
|
if (orderMain == null) {
|
||||||
throw new BusinessException("医嘱不存在,无法退回");
|
throw new BusinessException("医嘱主单不存在,ID=" + orderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 检查药房发药状态
|
// 2. 获取明细
|
||||||
// OrderStatus.DIS
|
List<OrderDetail> details = orderDetailMapper.selectByOrderId(orderId);
|
||||||
// 这里的状态值依据系统实际枚举定义,假设为 DISPENSED 表示已发药
|
if (details == null || details.isEmpty()) {
|
||||||
if (OrderStatus.DISPENSED.getCode().equals(orderMain.getStatus())) {
|
throw new BusinessException("医嘱明细不存在,主单ID=" + orderId);
|
||||||
// 已发药,禁止退回
|
|
||||||
log.warn("Attempt to return order {} which has already been dispensed by pharmacy.", orderMainId);
|
|
||||||
throw new BusinessException("药房已发药,不能退回医嘱");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 回滚主单状态为待复核(或其他业务约定的状态)
|
// 3. 更新本地执行状态(这里假设为已执行)
|
||||||
orderMain.setStatus(OrderStatus.PENDING_REVIEW.getCode());
|
orderMain.setStatus(OrderStatus.EXECUTED.getCode());
|
||||||
orderMain.setUpdateTime(new Date());
|
orderMainMapper.updateByPrimaryKeySelective(orderMain);
|
||||||
|
for (OrderDetail d : details) {
|
||||||
|
d.setStatus(OrderStatus.EXECUTED.getCode());
|
||||||
|
orderDetailMapper.updateByPrimaryKeySelective(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 根据字典模式决定是否同步药房状态
|
||||||
|
int mode = getNurseSubmitPharmacyMode(); // 0:需申请模式,1:自动模式
|
||||||
|
if (mode == 1) {
|
||||||
|
// 自动模式:同步更新药房申请状态,使药房立即可见
|
||||||
|
syncPharmacyApplyStatus(orderMain, details);
|
||||||
|
} else {
|
||||||
|
// 需申请模式:仅记录本地执行,不做药房同步,后续汇总申请时统一处理
|
||||||
|
log.info("Nurse submit pharmacy mode = 0 (need apply). Skip pharmacy sync for orderId={}", orderId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步药房申请状态。
|
||||||
|
*
|
||||||
|
* <p>该方法会把主单和所有明细的药房申请状态统一设置为 {@link OrderStatus#PHARMACY_APPLIED},
|
||||||
|
* 以保证药房查询时明细与汇总单保持一致。
|
||||||
|
*
|
||||||
|
* @param orderMain 主单
|
||||||
|
* @param details 明细列表
|
||||||
|
*/
|
||||||
|
private void syncPharmacyApplyStatus(OrderMain orderMain, List<OrderDetail> details) {
|
||||||
|
// 更新主单药房申请状态
|
||||||
|
orderMain.setPharmacyApplyStatus(OrderStatus.PHARMACY_APPLIED.getCode());
|
||||||
orderMainMapper.updateByPrimaryKeySelective(orderMain);
|
orderMainMapper.updateByPrimaryKeySelective(orderMain);
|
||||||
|
|
||||||
// 4. 回滚所有关联明细的状态
|
// 更新所有明细的药房申请状态
|
||||||
List<OrderDetail> details = orderDetailMapper.selectByOrderMainId(orderMainId);
|
|
||||||
for (OrderDetail detail : details) {
|
for (OrderDetail detail : details) {
|
||||||
detail.setStatus(OrderStatus.PENDING_REVIEW.getCode());
|
detail.setPharmacyApplyStatus(OrderStatus.PHARMACY_APPLIED.getCode());
|
||||||
detail.setUpdateTime(new Date());
|
|
||||||
orderDetailMapper.updateByPrimaryKeySelective(detail);
|
orderDetailMapper.updateByPrimaryKeySelective(detail);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info("Order {} successfully returned. Main status set to {}, {} detail(s) rolled back.",
|
log.info("Pharmacy apply status synced for orderId={}, detailCount={}",
|
||||||
orderMainId, OrderStatus.PENDING_REVIEW.getCode(), details.size());
|
orderMain.getId(), details.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取“病区护士执行提交药品模式”字典值。
|
||||||
|
*
|
||||||
|
* <p>此实现为演示目的,直接返回硬编码值。实际项目请改为读取系统字典或配置中心。
|
||||||
|
*
|
||||||
|
* @return 0 – 需申请模式(默认),1 – 自动模式
|
||||||
|
*/
|
||||||
|
private int getNurseSubmitPharmacyMode() {
|
||||||
|
// TODO: 替换为真实的字典读取逻辑,例如:
|
||||||
|
// return dictionaryService.getValueAsInt("NURSE_SUBMIT_PHARMACY_MODE", 0);
|
||||||
|
return 0; // 默认使用“需申请模式”,保持向后兼容
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
// 其它业务实现(如 cancelOrder、resolveTotalUnit 等)保持不变...
|
// 其它已有业务方法(如 cancelOrder、resolveTotalUnit 等)保持不变
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// 下面保留原有的业务实现占位,实际代码请保持原有内容不变
|
||||||
|
// ...
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user