71 lines
2.6 KiB
Java
71 lines
2.6 KiB
Java
package com.openhis.web.inpatient.service.impl;
|
||
|
||
import com.openhis.web.inpatient.mapper.DispenseMapper;
|
||
import org.springframework.stereotype.Service;
|
||
import org.springframework.transaction.annotation.Transactional;
|
||
|
||
import java.util.Map;
|
||
|
||
/**
|
||
* 住院发退药业务实现
|
||
*
|
||
* 修复 Bug #503:
|
||
* 住院发药时,发药明细(his_inpatient_dispense_detail)与发药汇总单
|
||
* (his_inpatient_dispense_summary)的数据写入时机不一致,导致先写入明细后
|
||
* 触发汇总单生成的异步任务未能及时感知,出现业务脱节风险。
|
||
*
|
||
* 解决思路:
|
||
* 1. 将明细写入、汇总单生成、汇总单状态更新全部放在同一个事务中完成;
|
||
* 2. 在写入明细后立即调用 {@link DispenseMapper#updateSummaryAfterDetail(Long, Integer)}
|
||
* 通过 SQL 直接在同事务内完成汇总统计,避免异步延迟;
|
||
* 3. 对外统一返回业务成功/失败结构,保持与其它接口风格一致。
|
||
*/
|
||
@Service
|
||
public class DispenseServiceImpl {
|
||
|
||
private final DispenseMapper dispenseMapper;
|
||
|
||
public DispenseServiceImpl(DispenseMapper dispenseMapper) {
|
||
this.dispenseMapper = dispenseMapper;
|
||
}
|
||
|
||
/**
|
||
* 发药(包括明细写入与汇总单同步更新)。
|
||
*
|
||
* @param dispenseId 发药单主键
|
||
* @param quantity 本次发药数量
|
||
* @return 业务结果映射,key 为 code(0 成功,1 失败),msg 为提示信息
|
||
*/
|
||
@Transactional(rollbackFor = Exception.class)
|
||
public Map<String, Object> dispense(Long dispenseId, Integer quantity) {
|
||
// 1. 写入发药明细
|
||
dispenseMapper.insertDetail(dispenseId, quantity);
|
||
|
||
// 2. 同步更新汇总单统计(在同事务内完成,确保时机一致)
|
||
dispenseMapper.updateSummaryAfterDetail(dispenseId, quantity);
|
||
|
||
// 3. 返回统一结构
|
||
return Map.of("code", 0, "msg", "发药成功");
|
||
}
|
||
|
||
/**
|
||
* 退药(明细与汇总同步回滚)。
|
||
*
|
||
* @param dispenseId 发药单主键
|
||
* @param quantity 本次退药数量
|
||
* @return 业务结果映射
|
||
*/
|
||
@Transactional(rollbackFor = Exception.class)
|
||
public Map<String, Object> returnDrug(Long dispenseId, Integer quantity) {
|
||
// 1. 写入退药明细(负数表示退药)
|
||
int returnQty = -Math.abs(quantity);
|
||
dispenseMapper.insertDetail(dispenseId, returnQty);
|
||
|
||
// 2. 同步更新汇总单统计(在同事务内完成,确保时机一致)
|
||
dispenseMapper.updateSummaryAfterDetail(dispenseId, returnQty);
|
||
|
||
// 3. 返回统一结构
|
||
return Map.of("code", 0, "msg", "退药成功");
|
||
}
|
||
}
|