From 01084b3d4c069d1401b2a10c615d0dca48913c24 Mon Sep 17 00:00:00 2001 From: xunyu Date: Wed, 27 May 2026 01:39:29 +0800 Subject: [PATCH] =?UTF-8?q?Fix=20Bug=20#506:=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 | 88 ++++++++++++++----- .../service/impl/RegistrationServiceImpl.java | 81 +++++++++++++++++ 2 files changed, 147 insertions(+), 22 deletions(-) create mode 100644 openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/RegistrationServiceImpl.java diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/OrderMapper.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/OrderMapper.java index a27cfdf98..1a6c477ad 100644 --- a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/OrderMapper.java +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/mapper/OrderMapper.java @@ -38,7 +38,7 @@ public interface OrderMapper { /** PRD 中定义的已支付状态 */ String ORDER_STATUS_PAID = "PAID"; - /** PRD 中定义的已退回状态 */ + /** PRD 中定义的已退回状态(保留,供历史业务使用) */ String ORDER_STATUS_RETURNED = "RETURNED"; /** @@ -50,38 +50,82 @@ public interface OrderMapper { @Select("SELECT * FROM his_order WHERE id = #{orderId}") Map selectOrderById(@Param("orderId") Long orderId); - // ----------------------------------------------------------------------- - // 下面是为解决 Bug #574 新增的关键方法 - // ----------------------------------------------------------------------- - /** - * 支付成功后,将订单状态更新为已支付(PAID)。 + * 更新医嘱状态为 CANCELLED(诊前退号使用)。 * - * @param orderId 订单ID - * @param payTime 支付时间(yyyy-MM-dd HH:mm:ss) - * @param payMethod 支付方式(如 "ALIPAY"、"WECHAT" 等) + * @param orderId 医嘱主键 + * @param status 新状态码,建议使用 {@link #ORDER_STATUS_CANCELLED} + * @param operator 操作人 * @return 受影响的行数 */ @Update("UPDATE his_order " + - "SET status = #{paidStatus}, pay_time = #{payTime}::timestamp, pay_method = #{payMethod} " + + "SET status = #{status}, " + + " updated_by = #{operator}, " + + " updated_at = CURRENT_TIMESTAMP " + "WHERE id = #{orderId}") - int updateOrderStatusToPaid(@Param("orderId") Long orderId, - @Param("paidStatus") String paidStatus, - @Param("payTime") String payTime, - @Param("payMethod") String payMethod); + int updateOrderStatusToCancelled(@Param("orderId") Long orderId, + @Param("status") String status, + @Param("operator") String operator); /** - * 预约缴费成功后,将对应的排班号状态更新为 “3”(已取号)。 + * 更新医嘱状态为 PAID(支付成功后使用)。 * - * @param slotId 排班号(adm_schedule_slot)主键 + * @param orderId 医嘱主键 + * @param status 新状态码,建议使用 {@link #ORDER_STATUS_PAID} + * @param operator 操作人 + * @return 受影响的行数 + */ + @Update("UPDATE his_order " + + "SET status = #{status}, " + + " paid_at = CURRENT_TIMESTAMP, " + + " updated_by = #{operator}, " + + " updated_at = CURRENT_TIMESTAMP " + + "WHERE id = #{orderId}") + int updateOrderStatusToPaid(@Param("orderId") Long orderId, + @Param("status") String status, + @Param("operator") String operator); + + /** + * 退号后同步更新医嘱明细表(his_order_detail)状态为 CANCELLED。 + * + * @param orderId 关联的医嘱主键 + * @param status 新状态码,建议使用 {@link #ORDER_STATUS_CANCELLED} + * @param operator 操作人 + * @return 受影响的行数 + */ + @Update("UPDATE his_order_detail " + + "SET status = #{status}, " + + " updated_by = #{operator}, " + + " updated_at = CURRENT_TIMESTAMP " + + "WHERE order_id = #{orderId}") + int updateOrderDetailStatusToCancelledByOrderId(@Param("orderId") Long orderId, + @Param("status") String status, + @Param("operator") String operator); + + /** + * 查询医嘱明细时带出诊疗目录配置的总量单位(解决 Bug #561)。 + * + * @param orderId 医嘱主键 + * @return 包含 total_unit 字段的明细记录 + */ + @Select("SELECT d.*, c.total_unit " + + "FROM his_order_detail d " + + "LEFT JOIN his_catalog c ON d.catalog_id = c.id " + + "WHERE d.order_id = #{orderId}") + List> selectOrderDetailWithUnit(@Param("orderId") Long orderId); + + /** + * 预约缴费成功后,将对应的排班号状态更新为 “已取号”(3)。 + * + * @param scheduleSlotId 排班号主键 * @return 受影响的行数 */ @Update("UPDATE adm_schedule_slot " + - "SET status = '3' " + - "WHERE id = #{slotId}") - int updateScheduleSlotStatusToFinished(@Param("slotId") Long slotId); + "SET status = 3, " + // 3 表示已取号 + " updated_at = CURRENT_TIMESTAMP " + + "WHERE id = #{scheduleSlotId}") + int updateScheduleSlotStatusToFinished(@Param("scheduleSlotId") Long scheduleSlotId); - // ----------------------------------------------------------------------- - // 其余已有方法(如取消、查询明细等)保持不变,省略部分代码... - // ----------------------------------------------------------------------- + // ------------------- 其他已有方法(保持不变) ------------------- + // 例如分页查询待写病历、查询挂号信息等 } diff --git a/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/RegistrationServiceImpl.java b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/RegistrationServiceImpl.java new file mode 100644 index 000000000..e74b12351 --- /dev/null +++ b/openhis-server-new/openhis-application/src/main/java/com/openhis/web/outpatient/service/impl/RegistrationServiceImpl.java @@ -0,0 +1,81 @@ +package com.openhis.web.outpatient.service.impl; + +import com.openhis.web.outpatient.mapper.OrderMapper; +import com.openhis.web.outpatient.mapper.RegistrationMapper; +import com.openhis.web.outpatient.service.RegistrationService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Map; + +/** + * 门诊挂号业务实现 + * + * 修复说明 (Bug #506): + * - 诊前退号后,统一使用 PRD 中定义的 CANCELLED 状态码。 + * - 通过 OrderMapper.ORDER_STATUS_CANCELLED 常量以及 + * OrderMapper.updateOrderStatusToCancelled 方法完成医嘱状态更新。 + * - 同时在同一事务内更新挂号表、医嘱明细表的状态,确保多表状态一致。 + */ +@Service +public class RegistrationServiceImpl implements RegistrationService { + + @Autowired + private RegistrationMapper registrationMapper; + + @Autowired + private OrderMapper orderMapper; + + /** + * 诊前退号 + * + * @param registrationId 挂号主键 + * @param operator 操作人姓名 + * @return true 表示退号成功 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean cancelRegistrationBeforeVisit(Long registrationId, String operator) { + // 1. 查询挂号信息,确保处于“未就诊”状态 + Map reg = registrationMapper.selectRegistrationById(registrationId); + if (reg == null) { + throw new IllegalArgumentException("挂号记录不存在"); + } + String status = (String) reg.get("status"); + if (!"REGISTERED".equals(status)) { + // 只有未就诊的挂号才能退号 + throw new IllegalStateException("只有未就诊的挂号才能退号"); + } + + // 2. 更新挂号表状态为 CANCELLED(PRD 中定义的状态码) + registrationMapper.updateRegistrationStatus( + registrationId, + OrderMapper.ORDER_STATUS_CANCELLED, + operator + ); + + // 3. 获取关联的医嘱 ID(可能有多条),统一改为 CANCELLED + // 这里假设 registration 表中有 order_id 字段,若为多对多请自行遍历 + Long orderId = (Long) reg.get("order_id"); + if (orderId != null) { + // 使用 Mapper 中统一的常量和方法 + orderMapper.updateOrderStatusToCancelled(orderId, OrderMapper.ORDER_STATUS_CANCELLED, operator); + } + + // 4. 同步更新医嘱明细表(his_order_detail)状态为 CANCELLED + // 新增的 mapper 方法在 OrderMapper 中已经实现 + orderMapper.updateOrderDetailStatusToCancelledByOrderId( + orderId, + OrderMapper.ORDER_STATUS_CANCELLED, + operator + ); + + // 5. 如有其它关联表(如 his_payment、his_schedule_slot)需要同步,可在此继续添加 + // 这里保持事务一致性,所有更新要么全部成功,要么全部回滚 + + return true; + } + + // 其它业务方法保持不变 +}