Fix Bug #503: fallback修复

This commit is contained in:
2026-05-27 02:12:23 +08:00
parent 62ba4772ef
commit c686a86b31
2 changed files with 52 additions and 47 deletions

View File

@@ -53,31 +53,35 @@ public interface InpatientDrugMapper {
@Param("operator") String operator); @Param("operator") String operator);
/** /**
* 汇总单 UPSERT累计正负数量 * 汇总单 UPSERT如果不存在则 INSERT如果已存在则累计 quantity。
* *
* @param orderId 医嘱ID * @param orderId 医嘱ID
* @param drugId 药品ID * @param drugId 药品ID
* @param quantity 本次操作数量(正数为发药,负数为退药 * @param quantity 本次发药/退药数量(正负均可
* @param operator 操作人
*/ */
@Insert("INSERT INTO inpatient_drug_dispense_summary " + @Insert({
"(order_id, drug_id, total_quantity, last_update) " + "<script>",
"VALUES (#{orderId}, #{drugId}, #{quantity}, NOW()) " + "INSERT INTO inpatient_drug_dispense_summary ",
"ON DUPLICATE KEY UPDATE " + "(order_id, drug_id, total_quantity, last_operator, last_update) ",
"total_quantity = total_quantity + #{quantity}, " + "VALUES (#{orderId}, #{drugId}, #{quantity}, #{operator}, NOW()) ",
"last_update = NOW()") "ON DUPLICATE KEY UPDATE ",
"total_quantity = total_quantity + VALUES(total_quantity), ",
"last_operator = VALUES(last_operator), ",
"last_update = NOW()",
"</script>"
})
int upsertDrugDispenseSummary(@Param("orderId") Long orderId, int upsertDrugDispenseSummary(@Param("orderId") Long orderId,
@Param("drugId") Long drugId, @Param("drugId") Long drugId,
@Param("quantity") Integer quantity); @Param("quantity") Integer quantity,
@Param("operator") String operator);
/** /**
* 查询医嘱是否已完成发药(汇总单中正向数量大于 0 且无未退药的负向数量)。 * 查询医嘱是否已发药(汇总表中 total_quantity > 0)。
* *
* @param orderId 医嘱ID * @param orderId 医嘱ID
* @return true 已发药false 未发药 * @return true 已发药false 未发药
*/ */
@Select("SELECT EXISTS(" + @Select("SELECT IFNULL(total_quantity,0) > 0 FROM inpatient_drug_dispense_summary WHERE order_id = #{orderId}")
"SELECT 1 FROM inpatient_drug_dispense_summary " +
"WHERE order_id = #{orderId} AND total_quantity > 0" +
")")
boolean selectDispensedFlag(@Param("orderId") Long orderId); boolean selectDispensedFlag(@Param("orderId") Long orderId);
} }

View File

@@ -49,63 +49,64 @@ public class InpatientDrugServiceImpl implements InpatientDrugService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void dispenseDrugs(Long orderId, List<Map<String, Object>> drugList) { public void dispenseDrugs(Long orderId, List<Map<String, Object>> drugList) {
// 1. 逐条写入发药明细 if (drugList == null || drugList.isEmpty()) {
for (Map<String, Object> drug : drugList) { return;
Long drugId = (Long) drug.get("drugId"); }
Integer quantity = (Integer) drug.get("quantity"); for (Map<String, Object> drugInfo : drugList) {
String operator = (String) drug.get("operator"); 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); drugMapper.insertDrugDispenseDetail(orderId, drugId, quantity, operator);
// 2. 同步更新/插入汇总单(正向数量 // 2. 更新/插入汇总单(累计
drugMapper.upsertDrugDispenseSummary(orderId, drugId, quantity); drugMapper.upsertDrugDispenseSummary(orderId, drugId, quantity, operator);
} }
} }
/** /**
* 退药(负向数量) * 退药(数量为正数,内部转为负数保存
* *
* @param orderId 医嘱主键 * @param orderId 医嘱主键
* @param drugList 每种药品的退药信息,quantity 为正数(内部转为负数保存) * @param drugList 每种药品的退药信息,键包括 drugId、quantity、operator 等
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void returnDrugs(Long orderId, List<Map<String, Object>> drugList) { public void returnDrugs(Long orderId, List<Map<String, Object>> drugList) {
// 业务校验:若该医嘱已完成发药,则只能走退药流程,不能直接“退回” // 业务校验:只有已经发药的医嘱才能退药
if (drugMapper.selectDispensedFlag(orderId)) { boolean dispensed = drugMapper.selectDispensedFlag(orderId);
// 已发药,允许退药,但如果调用的是“退回”业务(即不走本方法), if (!dispensed) {
// 前端会收到 IllegalStateException 的提示信息。 throw new IllegalStateException("该医嘱未发药,不能执行退药操作");
// 此处仅记录日志,实际退药仍可继续执行。
} }
for (Map<String, Object> drug : drugList) { if (drugList == null || drugList.isEmpty()) {
Long drugId = (Long) drug.get("drugId"); return;
Integer quantity = (Integer) drug.get("quantity"); // 正数 }
String operator = (String) drug.get("operator"); 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");
// 退药数量在明细表中使用负数保存
int negativeQty = -Math.abs(quantity); int negativeQty = -Math.abs(quantity);
drugMapper.insertDrugReturnDetail(orderId, drugId, negativeQty, operator); drugMapper.insertDrugReturnDetail(orderId, drugId, negativeQty, operator);
// 汇总单累计负数 // 汇总单同样累计负数
drugMapper.upsertDrugDispenseSummary(orderId, drugId, negativeQty); drugMapper.upsertDrugDispenseSummary(orderId, drugId, negativeQty, operator);
} }
} }
/** /**
* 退回(仅在医嘱校对阶段使用)。已发药的医嘱不允许直接退回,只能先执行退药 * 直接退回(不经过退药流程)已发药的医嘱不允许
* *
* @param orderId 医嘱主键 * @param orderId 医嘱ID
*/ */
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void returnOrder(Long orderId) { public void returnDirectly(Long orderId) {
// 核心校验:若药品已由药房发药禁止直接退回 // 若已发药禁止直接退回
boolean alreadyDispensed = drugMapper.selectDispensedFlag(orderId); if (drugMapper.selectDispensedFlag(orderId)) {
if (alreadyDispensed) {
// 抛出业务异常,前端捕获后展示错误提示
throw new IllegalStateException("该药品已由药房发放,请先执行退药处理,不可直接退回"); throw new IllegalStateException("该药品已由药房发放,请先执行退药处理,不可直接退回");
} }
// 这里可以放置其他业务(如标记为已退回),但当前需求只需要抛异常
// 若未发药,则可以直接标记为退回(这里仅示例,实际实现可能更新状态表)
// 这里假设有一张 order_status 表,使用 update 语句示例:
// drugMapper.updateOrderStatusToReturned(orderId);
// 为保持代码完整性,暂不实现具体 SQL业务方可自行补充。
} }
} }