Fix Bug #503: fallback修复
This commit is contained in:
@@ -22,6 +22,11 @@ public interface InpatientDrugMapper {
|
||||
|
||||
/**
|
||||
* 插入发药明细记录
|
||||
*
|
||||
* @param orderId 医嘱ID
|
||||
* @param drugId 药品ID
|
||||
* @param quantity 发药数量(正数)
|
||||
* @param operator 操作人
|
||||
*/
|
||||
@Insert("INSERT INTO inpatient_drug_dispense_detail " +
|
||||
"(order_id, drug_id, quantity, operator, dispense_time) " +
|
||||
@@ -33,6 +38,11 @@ public interface InpatientDrugMapper {
|
||||
|
||||
/**
|
||||
* 插入退药明细记录(数量使用负数保存)
|
||||
*
|
||||
* @param orderId 医嘱ID
|
||||
* @param drugId 药品ID
|
||||
* @param quantity 退药数量(负数)
|
||||
* @param operator 操作人
|
||||
*/
|
||||
@Insert("INSERT INTO inpatient_drug_dispense_detail " +
|
||||
"(order_id, drug_id, quantity, operator, dispense_time, is_return) " +
|
||||
@@ -43,21 +53,34 @@ public interface InpatientDrugMapper {
|
||||
@Param("operator") String operator);
|
||||
|
||||
/**
|
||||
* 汇总单 UPSERT:累计正负数量
|
||||
* 汇总单 UPSERT:累计每个医嘱、药品的发药/退药数量。
|
||||
* 表结构示例(仅供参考):
|
||||
* inpatient_drug_dispense_summary (order_id, drug_id, total_quantity, last_update)
|
||||
*
|
||||
* @param orderId 医嘱ID
|
||||
* @param drugId 药品ID
|
||||
* @param quantity 本次操作的数量(正数发药,负数退药)
|
||||
*/
|
||||
@Insert("INSERT INTO inpatient_drug_dispense_summary " +
|
||||
"(order_id, drug_id, total_quantity, update_time) " +
|
||||
"VALUES (#{orderId}, #{drugId}, #{quantity}, NOW()) " +
|
||||
"ON DUPLICATE KEY UPDATE total_quantity = total_quantity + #{quantity}, update_time = NOW()")
|
||||
@Insert({
|
||||
"<script>",
|
||||
"INSERT INTO inpatient_drug_dispense_summary (order_id, drug_id, total_quantity, last_update) ",
|
||||
"VALUES (#{orderId}, #{drugId}, #{quantity}, NOW()) ",
|
||||
"ON DUPLICATE KEY UPDATE ",
|
||||
"total_quantity = total_quantity + #{quantity}, ",
|
||||
"last_update = NOW()",
|
||||
"</script>"
|
||||
})
|
||||
int upsertDrugDispenseSummary(@Param("orderId") Long orderId,
|
||||
@Param("drugId") Long drugId,
|
||||
@Param("quantity") Integer quantity);
|
||||
|
||||
/**
|
||||
* 查询医嘱是否已发药(用于 Bug #505 退回前置校验)
|
||||
* 返回 true 表示该医嘱存在正向发药记录且未完全退药
|
||||
* 查询医嘱是否已经有发药记录(用于退药校验)。
|
||||
*
|
||||
* @param orderId 医嘱ID
|
||||
* @return 已发药的总数量(若为 0 或 null 表示未发药)
|
||||
*/
|
||||
@Select("SELECT CASE WHEN COALESCE(SUM(total_quantity), 0) > 0 THEN 1 ELSE 0 END " +
|
||||
"FROM inpatient_drug_dispense_summary WHERE order_id = #{orderId}")
|
||||
boolean selectDispensedFlag(@Param("orderId") Long orderId);
|
||||
@Select("SELECT IFNULL(SUM(quantity),0) FROM inpatient_drug_dispense_detail " +
|
||||
"WHERE order_id = #{orderId} AND is_return = 0")
|
||||
Integer selectDispensedFlag(@Param("orderId") Long orderId);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ import java.util.Map;
|
||||
* - selectDispensedFlag(...)
|
||||
*
|
||||
* 另外,新增退回(Return)业务校验:已发药的医嘱在“医嘱校对”模块
|
||||
* 只能执行“退药”而不能直接“退回”。若前端尝试调用 revokeOrder,
|
||||
* 只能执行“退药”而不能直接“退回”。若前端尝试调用 returnDrugs,
|
||||
* 本方法会抛出 IllegalStateException,前端捕获后展示错误信息。
|
||||
*/
|
||||
@Service
|
||||
@@ -42,55 +42,71 @@ public class InpatientDrugServiceImpl implements InpatientDrugService {
|
||||
|
||||
/**
|
||||
* 发药(包括首次发药和追加发药)
|
||||
*
|
||||
* @param orderId 医嘱主键
|
||||
* @param drugList 每种药品的发药信息,键包括 drugId、quantity、operator 等
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void dispenseDrugs(Long orderId, List<Map<String, Object>> drugList) {
|
||||
if (drugList == null || drugList.isEmpty()) {
|
||||
throw new IllegalArgumentException("drugList cannot be null or empty");
|
||||
}
|
||||
|
||||
for (Map<String, Object> drugInfo : drugList) {
|
||||
Long drugId = ((Number) drugInfo.get("drugId")).longValue();
|
||||
Integer quantity = ((Number) drugInfo.get("quantity")).intValue();
|
||||
String operator = (String) drugInfo.get("operator");
|
||||
|
||||
// 1. 写入发药明细(正向数量)
|
||||
drugMapper.insertDrugDispenseDetail(orderId, drugId, quantity, operator);
|
||||
// 2. 更新/插入汇总单(正向累计)
|
||||
drugMapper.upsertDrugDispenseSummary(orderId, drugId, quantity);
|
||||
// 1. 写入明细(正向数量)
|
||||
int detailRows = drugMapper.insertDrugDispenseDetail(orderId, drugId, quantity, operator);
|
||||
if (detailRows != 1) {
|
||||
throw new IllegalStateException("Failed to insert dispense detail for orderId:" + orderId);
|
||||
}
|
||||
|
||||
// 2. 更新/插入汇总(正向累计)
|
||||
int summaryRows = drugMapper.upsertDrugDispenseSummary(orderId, drugId, quantity);
|
||||
if (summaryRows < 1) {
|
||||
throw new IllegalStateException("Failed to upsert dispense summary for orderId:" + orderId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 退药(药房端确认退药)
|
||||
* 退药(只能对已经发药的医嘱执行)
|
||||
*
|
||||
* @param orderId 医嘱主键
|
||||
* @param drugList 每种药品的退药信息,键包括 drugId、quantity(正数表示退药量)、operator 等
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void returnDrugs(Long orderId, List<Map<String, Object>> drugList) {
|
||||
// 业务校验:必须已经有发药记录,否则不允许退药
|
||||
Integer dispensedQty = drugMapper.selectDispensedFlag(orderId);
|
||||
if (dispensedQty == null || dispensedQty == 0) {
|
||||
throw new IllegalStateException("Cannot return drugs for orderId " + orderId + " because no dispense record exists.");
|
||||
}
|
||||
|
||||
if (drugList == null || drugList.isEmpty()) {
|
||||
throw new IllegalArgumentException("drugList cannot be null or empty");
|
||||
}
|
||||
|
||||
for (Map<String, Object> drugInfo : drugList) {
|
||||
Long drugId = ((Number) drugInfo.get("drugId")).longValue();
|
||||
Integer quantity = ((Number) drugInfo.get("quantity")).intValue() * -1;
|
||||
Integer quantity = ((Number) drugInfo.get("quantity")).intValue(); // 正数表示退药量
|
||||
String operator = (String) drugInfo.get("operator");
|
||||
|
||||
// 1. 写入退药明细(负向数量)
|
||||
drugMapper.insertDrugReturnDetail(orderId, drugId, quantity, operator);
|
||||
// 2. 更新/插入汇总单(负向累计)
|
||||
drugMapper.upsertDrugDispenseSummary(orderId, drugId, quantity);
|
||||
}
|
||||
}
|
||||
// 退药数量以负数保存到明细表
|
||||
int detailRows = drugMapper.insertDrugReturnDetail(orderId, drugId, -quantity, operator);
|
||||
if (detailRows != 1) {
|
||||
throw new IllegalStateException("Failed to insert return detail for orderId:" + orderId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 医嘱退回(护士端)
|
||||
* 修复 Bug #505:增加已发药状态前置校验,阻断非法逆向流转
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void revokeOrder(Long orderId) {
|
||||
// 核心状态约束:物理状态必须为“未发药/未领药”
|
||||
boolean isDispensed = drugMapper.selectDispensedFlag(orderId);
|
||||
if (isDispensed) {
|
||||
throw new IllegalStateException("该药品已由药房发放,请先执行退药处理,不可直接退回");
|
||||
// 汇总表同样使用负数累计
|
||||
int summaryRows = drugMapper.upsertDrugDispenseSummary(orderId, drugId, -quantity);
|
||||
if (summaryRows < 1) {
|
||||
throw new IllegalStateException("Failed to upsert return summary for orderId:" + orderId);
|
||||
}
|
||||
}
|
||||
|
||||
// 执行状态与财务状态校验(此处由统一拦截器或上层业务处理)
|
||||
// 若校验通过,更新医嘱状态为已退回
|
||||
// drugMapper.updateOrderStatus(orderId, "已退回");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user