55 lines
2.2 KiB
Java
55 lines
2.2 KiB
Java
package com.openhis.web.inpatient.mapper;
|
||
|
||
import org.apache.ibatis.annotations.*;
|
||
|
||
import java.util.Map;
|
||
|
||
/**
|
||
* 发药汇总单 Mapper
|
||
*
|
||
* 新增:
|
||
* 1. {@code recalculateSummaryByPrescriptionId}:基于明细表重新计算汇总信息,并使用 FOR UPDATE 锁定行。
|
||
* 2. {@code insertInitialSummary}:在首次发药时插入空的汇总记录,防止后续更新失败。
|
||
*/
|
||
@Mapper
|
||
public interface DispensingSummaryMapper {
|
||
|
||
/**
|
||
* 重新计算指定处方的发药汇总信息。
|
||
*
|
||
* 该 SQL 会:
|
||
* - 对 his_dispensing_detail 按 prescription_id 汇总数量、金额等。
|
||
* - 使用 SELECT ... FOR UPDATE 锁定对应的 his_dispensing_summary 行,确保并发安全。
|
||
* - 更新汇总表的 total_quantity、total_amount、status 等字段。
|
||
*
|
||
* @param prescriptionId 处方主键
|
||
* @return 更新的记录数(通常为 1)
|
||
*/
|
||
@Update({
|
||
"<script>",
|
||
"UPDATE his_dispensing_summary s",
|
||
"SET",
|
||
" s.total_quantity = (SELECT IFNULL(SUM(d.quantity),0) FROM his_dispensing_detail d WHERE d.prescription_id = #{prescriptionId}),",
|
||
" s.total_amount = (SELECT IFNULL(SUM(d.amount),0) FROM his_dispensing_detail d WHERE d.prescription_id = #{prescriptionId}),",
|
||
" s.status = CASE",
|
||
" WHEN EXISTS (SELECT 1 FROM his_dispensing_detail d WHERE d.prescription_id = #{prescriptionId} AND d.type = 'RETURN')",
|
||
" THEN 'PARTIAL_RETURN'",
|
||
" ELSE 'DISPENSED'",
|
||
" END",
|
||
"WHERE s.prescription_id = #{prescriptionId}",
|
||
// 加锁,防止并发更新导致汇总不一致
|
||
"AND EXISTS (SELECT 1 FROM his_dispensing_summary s2 WHERE s2.id = s.id FOR UPDATE)",
|
||
"</script>"
|
||
})
|
||
int recalculateSummaryByPrescriptionId(@Param("prescriptionId") Long prescriptionId);
|
||
|
||
/**
|
||
* 首次发药时插入一条空的汇总记录。
|
||
*
|
||
* @param prescriptionId 处方主键
|
||
*/
|
||
@Insert("INSERT INTO his_dispensing_summary (prescription_id, total_quantity, total_amount, status) " +
|
||
"VALUES (#{prescriptionId}, 0, 0, 'INIT')")
|
||
void insertInitialSummary(@Param("prescriptionId") Long prescriptionId);
|
||
}
|