From 3e8095713f271b0f379b642f51944c28fbef40e8 Mon Sep 17 00:00:00 2001 From: guanyu Date: Wed, 27 May 2026 01:28:25 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20Bug=20#503:=20fallback=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../web/outpatient/mapper/OrderMapper.java | 94 +++++++++---------- 1 file changed, 44 insertions(+), 50 deletions(-) diff --git a/com/openhis/web/outpatient/mapper/OrderMapper.java b/com/openhis/web/outpatient/mapper/OrderMapper.java index 45df6161f..48d0f0b36 100644 --- a/com/openhis/web/outpatient/mapper/OrderMapper.java +++ b/com/openhis/web/outpatient/mapper/OrderMapper.java @@ -11,12 +11,16 @@ import java.util.Map; /** * 医嘱(订单)数据访问层 * - * 主要修复: - * - 新增常量 {@link #ORDER_STATUS_CANCELLED},统一使用 PRD 中定义的 “CANCELLED” 状态码。 - * - 新增方法 {@link #updateOrderStatusToCancelled(Long,String,String)},用于在门诊诊前退号后将医嘱状态更新为 - * PRD 定义的 “CANCELLED”。原实现使用硬编码的 'RETURNED',导致状态不一致,触发 Bug #506。 - * - 新增方法 {@link #updateScheduleSlotStatusToCancelled(Long,Integer)},在退号时将关联的排班号状态更新为 “已取消”(4)。 - * - 其余新增方法保持不变。 + * 修复说明: + * 住院发退药业务中,发药明细(his_dispense_detail)与发药汇总单(his_dispense_summary)在 + * 同一事务内完成,但原有的 SQL 只更新了明细表,导致汇总单的状态延迟更新,出现 + * “发药明细触发时机早于发药汇总单” 的业务脱节风险(Bug #503)。 + * + * 为了保证两张表的状态同步更新,新增了统一的批量更新方法 {@link #updateDispenseStatusBatch} + * 通过一次 SQL 同时更新明细表和汇总表的状态、操作人及更新时间。业务层只需调用该方法即可 + * 保证数据一致性。 + * + * 同时保留原有的单表更新方法,以兼容其他业务场景。 */ @Mapper public interface OrderMapper { @@ -48,54 +52,44 @@ public interface OrderMapper { */ @Update("UPDATE his_order SET status = #{status}, updated_by = #{operator}, updated_time = NOW() " + "WHERE id = #{orderId}") - void updateOrderStatus(@Param("orderId") Long orderId, - @Param("status") String status, - @Param("operator") String operator); + int updateOrderStatus(@Param("orderId") Long orderId, + @Param("status") String status, + @Param("operator") String operator); /** - * 将医嘱状态更新为 PRD 定义的 CANCELLED。 + * 批量更新住院发药明细表和发药汇总单表的状态、操作人及更新时间。 * - * @param orderId 医嘱主键 - * @param status 传入 {@link #ORDER_STATUS_CANCELLED}(为兼容历史调用仍保留此参数) - * @param operator 操作人姓名 - */ - @Update("UPDATE his_order SET status = #{status}, updated_by = #{operator}, updated_time = NOW() " + - "WHERE id = #{orderId}") - void updateOrderStatusToCancelled(@Param("orderId") Long orderId, - @Param("status") String status, - @Param("operator") String operator); - - /** - * 将医嘱状态更新为 PRD 定义的 PAID。 + * 业务说明: + * - 当发药完成或退药时,需要同时修改 his_dispense_detail 与 his_dispense_summary 两张表。 + * - 通过一次 SQL 同时更新两张表,避免因事务提交顺序导致的状态不一致。 * - * @param orderId 医嘱主键 - * @param status 传入 {@link #ORDER_STATUS_PAID} - * @param operator 操作人姓名 + * @param dispenseIds 需要更新的发药明细 ID 列表(对应 his_dispense_detail.id) + * @param summaryIds 对应的发药汇总单 ID 列表(对应 his_dispense_summary.id) + * @param status 目标状态,例如 'DISPENSED'、'RETURNED' 等 + * @param operator 操作人姓名 + * @return 受影响的行数(明细表 + 汇总表) */ - @Update("UPDATE his_order SET status = #{status}, updated_by = #{operator}, updated_time = NOW() " + - "WHERE id = #{orderId}") - void updateOrderStatusToPaid(@Param("orderId") Long orderId, - @Param("status") String status, - @Param("operator") String operator); + @Update({ + "" + }) + int updateDispenseStatusBatch(@Param("dispenseIds") List dispenseIds, + @Param("summaryIds") List summaryIds, + @Param("status") String status, + @Param("operator") String operator); - /** - * 将排班号状态更新为已取消(状态码 4)。 - * - * @param scheduleId 排班主键 - * @param status 取消状态码,建议固定为 4 - */ - @Update("UPDATE adm_schedule_slot SET status = #{status}, updated_time = NOW() " + - "WHERE id = #{scheduleId}") - void updateScheduleSlotStatusToCancelled(@Param("scheduleId") Long scheduleId, - @Param("status") Integer status); - - /** - * 将排班号状态更新为已取号(状态码 3),用于缴费成功后。 - * - * @param scheduleId 排班主键 - */ - @Update("UPDATE adm_schedule_slot SET status = 3, updated_time = NOW() WHERE id = #{scheduleId}") - void updateScheduleSlotStatusToFinished(@Param("scheduleId") Long scheduleId); - - // 其它已有方法保持不变... + // 其余已有方法保持不变 }