diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientDrugMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientDrugMapper.java
index 89a93e6e8..75a15aa35 100644
--- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientDrugMapper.java
+++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/inpatient/mapper/InpatientDrugMapper.java
@@ -7,74 +7,77 @@ import java.util.Map;
/**
* 住院药品发放/退药数据访问层
*
- * 修复 Bug #503:
- * 引入 apply_status 字段控制数据可见性。
- * 护士执行医嘱时 apply_status=0(药房不可见);
- * 护士提交汇总申请时 apply_status=1(药房明细/汇总同步可见)。
- * 通过事务保证状态变更与汇总单生成的原子性,彻底消除业务脱节风险。
+ * 新增:
+ * 1. insertDrugDispenseDetail – 插入发药明细(正向数量)。
+ * 2. insertDrugReturnDetail – 插入退药明细(负向数量)。
+ * 3. upsertDrugDispenseSummary – 汇总单 UPSERT(INSERT … ON DUPLICATE KEY UPDATE),
+ * 用于累计正负数量,保持明细与汇总的一致性。
+ *
+ * 通过上述三条 SQL,业务层在同一事务内先写明细再写汇总,彻底消除
+ * “发药明细与汇总单触发时机不一致” 的风险。
*/
@Mapper
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, apply_status) " +
- "VALUES (#{orderId}, #{drugId}, #{quantity}, #{operator}, NOW(), 0)")
+ "(order_id, drug_id, quantity, operator, dispense_time) " +
+ "VALUES (#{orderId}, #{drugId}, #{quantity}, #{operator}, NOW())")
int insertDrugDispenseDetail(@Param("orderId") Long orderId,
@Param("drugId") Long drugId,
@Param("quantity") Integer quantity,
@Param("operator") String operator);
/**
- * 插入退药明细记录(默认未申请状态)
+ * 插入退药明细记录(数量使用负数保存)
+ *
+ * @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, apply_status) " +
- "VALUES (#{orderId}, #{drugId}, #{quantity}, #{operator}, NOW(), 1, 0)")
+ "(order_id, drug_id, quantity, operator, dispense_time, is_return) " +
+ "VALUES (#{orderId}, #{drugId}, #{quantity}, #{operator}, NOW(), 1)")
int insertDrugReturnDetail(@Param("orderId") Long orderId,
@Param("drugId") Long drugId,
@Param("quantity") Integer quantity,
@Param("operator") String operator);
/**
- * 批量更新明细申请状态(触发药房可见)
+ * 汇总发药/退药数量(UPSERT)。
+ *
+ * 表结构示例(仅供参考):
+ * inpatient_drug_dispense_summary
+ * - id (PK, 自增)
+ * - order_id
+ * - drug_id
+ * - total_quantity (累计正负数量)
+ * - last_update_time
+ *
+ * 该 SQL 在不存在对应汇总记录时 INSERT,存在时 UPDATE total_quantity。
+ *
+ * @param orderId 医嘱ID
+ * @param drugId 药品ID
+ * @param quantity 本次操作的数量(正数为发药,负数为退药)
*/
- @Update("UPDATE inpatient_drug_dispense_detail SET apply_status = 1 WHERE id IN " +
- "#{id}")
- int batchUpdateDetailApplyStatus(@Param("detailIds") List detailIds);
-
- /**
- * 根据明细ID查询药品及数量(用于汇总计算)
- */
- @Select("SELECT id, drug_id, quantity FROM inpatient_drug_dispense_detail WHERE id IN " +
- "#{id}")
- List