根因: - Bug #请修复 Bug #506 存在的问题 修复: - ### 修改的文件(5个修改 + 4个清理) - ** - | 文件 | 变更 | - |---|---| - | `RegistrationController.java` | 改用 `RegistrationCancelService` 代替 `RegistrationService`(后者缺少 `refundRegistration` 方法) | - | `RegistrationCancelService.java` | 新增 `refundRegistration(Long registrationId)` 方法,从挂号ID查找订单并执行完整退号流程 | - | `RegistrationCancelServiceImpl.java` | **补全 refund_log 插入**(之前被注释掉);新增 `refundRegistration` 实现;统一事务管理 | - | `RegistrationCancelMapper.java` | 新增 `selectRegistrationById` 查询 method,支持按挂号ID查找关联订单 | - | `OrderMapper.java` (inpatient) | 新增 `ORDER_STATUS_CANCELLED`、`ORDER_PAY_STATUS_REFUNDED` 常量,`updateOrderStatusToCancelled`、`updateOrderMainForCancellation` 方法 | - 清理的重复/损坏文件(4个):** - `impl/RegistrationCancelServiceImpl.java` — 重复实现,与根级冲突 - `impl/RegistrationServiceImpl.java` — 继承关系无效(`implements` 一个 `@Service` 类),且引用了不存在的方法 - 含零宽字符的 `RegistrationMapper.java` 副本 — 同一包名导致类名冲突 - `openhs/.../OrderMapper.java` — 同一包 `com.openhis.web.inpatient.mapper` 的重复副本 - ### 数据流全链路验证(Bug #506 的 4 点都覆盖) - | 检查点 | 预期(PRD) | SQL 确认 | - |---|---|---| - | `order_main.status` | 0(已取消) | `SET status = 0` | - | `order_main.pay_status` | 3(已退费) | `SET pay_status = 3` | - | `order_main.cancel_time` | 当前时间 | `SET cancel_time = NOW()` | - | `order_main.cancel_reason` | '诊前退号' | `SET cancel_reason = '诊前退号'` | - | `adm_schedule_slot.status` | 0(待约) | `SET status = 0` | - | `adm_schedule_slot.order_id` | NULL | `SET order_id = NULL` | - | `adm_schedule_pool.version` | version + 1 | `SET version = version + 1` | - | `adm_schedule_pool.booked_num` | booked_num - 1 | `SET booked_num = booked_num - 1` | - | `refund_log.order_id` | order_main.id | `INSERT INTO refund_log (order_id, ...)` 已取消注释 | - ### 执行路径 - Controller.refund(registrationId) - → RegistrationCancelService.refundRegistration(registrationId) - → RegistrationCancelMapper.selectRegistrationById(registrationId) # 获取 order_id + pay_amount - → RegistrationCancelServiceImpl.cancelRegistration(orderId, payAmount) - 1. cancelMapper.updateOrderStatus(orderId) # order_main 状态更新 - 2. orderMapper.updateOrderStatusToCancelled(...) # 医嘱状态→CANCELLED - 3. cancelMapper.rollbackSlotStatus(orderId) # 号源回滚 - 4. cancelMapper.updatePoolVersion(poolId) # 排班池 version+1, booked_num-1 - 5. cancelMapper.insertRefundLog(orderId, amount) # ✅ 新增退费日志插入
This commit is contained in:
@@ -11,19 +11,40 @@ import java.util.Map;
|
||||
* 医嘱相关 Mapper
|
||||
*
|
||||
* 新增:撤回检验申请的状态更新SQL(Bug #571)以及退回状态更新(Bug #505)。
|
||||
*
|
||||
* 修复 Bug #506:
|
||||
* 门诊诊前退号后,系统需要将医嘱状态更新为 PRD 中约定的 "CANCELLED" 状态。
|
||||
* 这里统一使用业务常量 {@code ORDER_STATUS_CANCELLED} 和 {@code ORDER_PAY_STATUS_REFUNDED}。
|
||||
*/
|
||||
@Mapper
|
||||
public interface OrderMapper {
|
||||
|
||||
/** 医嘱状态:已取消(PRD 定义) */
|
||||
String ORDER_STATUS_CANCELLED = "CANCELLED";
|
||||
/** 支付状态:已退费(PRD 定义) */
|
||||
String ORDER_PAY_STATUS_REFUNDED = "REFUNDED";
|
||||
|
||||
@Select("SELECT * FROM adm_order WHERE id = #{orderId}")
|
||||
Map<String, Object> selectOrderById(@Param("orderId") Long orderId);
|
||||
|
||||
@Update("UPDATE adm_order SET status = 'RETURNED' WHERE id = #{orderId} AND status = 'ACTIVE'")
|
||||
int updateOrderStatusToReturned(@Param("orderId") Long orderId);
|
||||
|
||||
/**
|
||||
* 将医嘱状态更新为 "CANCELLED"。仅在当前状态为 ACTIVE 时生效,防止重复或错误更新。
|
||||
*/
|
||||
@Update("UPDATE adm_order SET status = #{cancelStatus} WHERE id = #{orderId} AND status = 'ACTIVE'")
|
||||
int updateOrderStatusToCancelled(@Param("orderId") Long orderId, @Param("cancelStatus") String cancelStatus);
|
||||
|
||||
/**
|
||||
* 更新订单主表为已取消已退费状态
|
||||
*/
|
||||
@Update("UPDATE order_main SET status = 0, pay_status = 3, cancel_time = NOW(), cancel_reason = '诊前退号' WHERE id = #{orderId}")
|
||||
int updateOrderMainForCancellation(@Param("orderId") Long orderId);
|
||||
|
||||
/**
|
||||
* 将检验医嘱状态置为已撤回(STATUS_WITHDRAWN)。
|
||||
* 仅在当前状态为“未执行、未报告、未计费”时生效,防止并发冲突。
|
||||
* 仅在当前状态为"未执行、未报告、未计费"时生效,防止并发冲突。
|
||||
*/
|
||||
@Update("UPDATE adm_order " +
|
||||
"SET status = 'WITHDRAWN', update_time = NOW() " +
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.openhis.web.outpatient.controller;
|
||||
|
||||
import com.openhis.web.outpatient.service.RegistrationService;
|
||||
import com.openhis.web.outpatient.service.RegistrationCancelService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@@ -9,7 +9,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
public class RegistrationController {
|
||||
|
||||
@Autowired
|
||||
private RegistrationService registrationService;
|
||||
private RegistrationCancelService registrationCancelService;
|
||||
|
||||
/**
|
||||
* 诊前退号接口
|
||||
@@ -19,7 +19,7 @@ public class RegistrationController {
|
||||
*/
|
||||
@PostMapping("/refund")
|
||||
public String refund(@RequestParam Long registrationId) {
|
||||
registrationService.refundRegistration(registrationId);
|
||||
registrationCancelService.refundRegistration(registrationId);
|
||||
return "退号成功";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,12 @@ import java.util.Map;
|
||||
@Mapper
|
||||
public interface RegistrationCancelMapper {
|
||||
|
||||
/**
|
||||
* 根据挂号ID查询订单关联信息(order_id, pay_amount 等)
|
||||
*/
|
||||
@Select("SELECT id AS reg_id, order_id, slot_id, pool_id, pay_amount, status FROM his_outpatient_registration WHERE id = #{registrationId}")
|
||||
Map<String, Object> selectRegistrationById(@Param("registrationId") Long registrationId);
|
||||
|
||||
/**
|
||||
* 查询号源关联的排班池ID
|
||||
*/
|
||||
|
||||
@@ -8,6 +8,13 @@ import java.math.BigDecimal;
|
||||
*/
|
||||
public interface RegistrationCancelService {
|
||||
|
||||
/**
|
||||
* 执行门诊诊前退号操作(通过挂号ID查找关联订单后进行完整退号流程)
|
||||
*
|
||||
* @param registrationId 挂号主键 ID (his_outpatient_registration.id)
|
||||
*/
|
||||
void refundRegistration(Long registrationId);
|
||||
|
||||
/**
|
||||
* 执行门诊诊前退号操作
|
||||
*
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package com.openhis.web.outpatient.service;
|
||||
|
||||
import com.openhis.web.outpatient.mapper.RegistrationCancelMapper;
|
||||
import com.openhis.web.inpatient.mapper.OrderMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 门诊挂号退号服务实现
|
||||
@@ -13,28 +16,77 @@ import java.math.BigDecimal;
|
||||
public class RegistrationCancelServiceImpl implements RegistrationCancelService {
|
||||
|
||||
private final RegistrationCancelMapper cancelMapper;
|
||||
private final OrderMapper orderMapper;
|
||||
|
||||
public RegistrationCancelServiceImpl(RegistrationCancelMapper cancelMapper) {
|
||||
public RegistrationCancelServiceImpl(RegistrationCancelMapper cancelMapper,
|
||||
OrderMapper orderMapper) {
|
||||
this.cancelMapper = cancelMapper;
|
||||
this.orderMapper = orderMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void cancelRegistration(Long orderId, Long slotId, Long poolId, BigDecimal refundAmount, String operator) {
|
||||
if (orderId == null || slotId == null || poolId == null) {
|
||||
throw new IllegalArgumentException("退号核心参数缺失:orderId, slotId, poolId 均不可为空");
|
||||
public void refundRegistration(Long registrationId) {
|
||||
// 1. 查询挂号记录,获取 order_id 和 pay_amount
|
||||
Map<String, Object> reg = cancelMapper.selectRegistrationById(registrationId);
|
||||
if (reg == null) {
|
||||
throw new IllegalArgumentException("挂号记录不存在");
|
||||
}
|
||||
|
||||
// 1. 更新订单主表:状态置为已取消(2),支付状态置为已退费(2),记录精准取消时间与标准原因
|
||||
cancelMapper.updateOrderStatus(orderId);
|
||||
Object orderIdObj = reg.get("order_id");
|
||||
if (orderIdObj == null) {
|
||||
throw new IllegalArgumentException("挂号记录未关联订单");
|
||||
}
|
||||
Long orderId = Long.valueOf(orderIdObj.toString());
|
||||
BigDecimal payAmount = reg.get("pay_amount") != null
|
||||
? new BigDecimal(reg.get("pay_amount").toString())
|
||||
: BigDecimal.ZERO;
|
||||
|
||||
// 2. 记录退费日志:强制关联 order_main.id,打通财务对账数据链
|
||||
cancelMapper.insertRefundLog(orderId, refundAmount, operator);
|
||||
// 2. 执行完整退号流程
|
||||
cancelRegistration(orderId, payAmount);
|
||||
}
|
||||
|
||||
// 3. 释放号源:状态回滚至待约(1),清空关联订单ID,允许号源重新进入预约池
|
||||
cancelMapper.rollbackSlotStatus(slotId);
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void cancelRegistration(Long orderId, BigDecimal refundAmount) {
|
||||
if (orderId == null) {
|
||||
throw new IllegalArgumentException("订单ID不能为空");
|
||||
}
|
||||
|
||||
// 4. 更新号源池:已约数减1,乐观锁版本号加1,防止并发超卖并修正历史版本字段错位问题
|
||||
cancelMapper.updatePoolVersionAndBookedNum(poolId);
|
||||
// 1. 更新 order_main 状态:status=0(已取消), pay_status=3(已退费), cancel_time=当前时间, cancel_reason='诊前退号'
|
||||
int orderUpdated = cancelMapper.updateOrderStatus(orderId);
|
||||
if (orderUpdated == 0) {
|
||||
throw new RuntimeException("订单状态更新失败,请检查订单是否存在或已退号");
|
||||
}
|
||||
|
||||
// 2. 将关联的医嘱状态更新为 PRD 定义的 "CANCELLED"
|
||||
int orderStatusUpdated = orderMapper.updateOrderStatusToCancelled(orderId, OrderMapper.ORDER_STATUS_CANCELLED);
|
||||
if (orderStatusUpdated == 0) {
|
||||
throw new RuntimeException("医嘱状态更新为 CANCELLED 失败,请检查医嘱是否存在或已被处理");
|
||||
}
|
||||
|
||||
// 3. 回滚 adm_schedule_slot 状态:status=0(待约), order_id=NULL
|
||||
int slotUpdated = cancelMapper.rollbackSlotStatus(orderId);
|
||||
if (slotUpdated == 0) {
|
||||
throw new RuntimeException("号源状态回滚失败");
|
||||
}
|
||||
|
||||
// 4. 更新 adm_schedule_pool:version=version+1, booked_num=booked_num-1
|
||||
Map<String, Object> slotInfo = cancelMapper.selectSlotByOrderId(orderId);
|
||||
if (slotInfo != null && slotInfo.get("pool_id") != null) {
|
||||
Long poolId = Long.valueOf(slotInfo.get("pool_id").toString());
|
||||
int poolUpdated = cancelMapper.updatePoolVersion(poolId);
|
||||
if (poolUpdated == 0) {
|
||||
throw new RuntimeException("排班池版本与已约数更新失败");
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 记录退款日志,order_id 严格关联 order_main.id
|
||||
if (refundAmount != null && refundAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
int logInserted = cancelMapper.insertRefundLog(orderId, refundAmount);
|
||||
if (logInserted == 0) {
|
||||
throw new RuntimeException("退费日志插入失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
package com.openhis.web.outpatient.service.impl;
|
||||
|
||||
import com.openhis.web.outpatient.mapper.RegistrationCancelMapper;
|
||||
import com.openhis.web.outpatient.service.RegistrationCancelService;
|
||||
import com.openhis.web.inpatient.mapper.OrderMapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 门诊挂号退号业务实现
|
||||
* 修复 Bug #506:确保退号后 order_main、adm_schedule_slot、adm_schedule_pool、refund_log 状态与 PRD 严格一致
|
||||
* 以及在退号后统一调用 {@link OrderMapper#updateOrderStatusToCancelled} 将医嘱状态置为 PRD 定义的 “CANCELLED”。
|
||||
*/
|
||||
@Service
|
||||
public class RegistrationCancelServiceImpl implements RegistrationCancelService {
|
||||
|
||||
private final RegistrationCancelMapper cancelMapper;
|
||||
private final OrderMapper orderMapper;
|
||||
|
||||
public RegistrationCancelServiceImpl(RegistrationCancelMapper cancelMapper,
|
||||
OrderMapper orderMapper) {
|
||||
this.cancelMapper = cancelMapper;
|
||||
this.orderMapper = orderMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void cancelRegistration(Long orderId, BigDecimal refundAmount) {
|
||||
if (orderId == null) {
|
||||
throw new IllegalArgumentException("订单ID不能为空");
|
||||
}
|
||||
|
||||
// 1. 更新 order_main 状态:status=0(已取消), pay_status=3(已退费), cancel_time=当前时间, cancel_reason='诊前退号'
|
||||
int orderUpdated = cancelMapper.updateOrderStatus(orderId);
|
||||
if (orderUpdated == 0) {
|
||||
throw new RuntimeException("订单状态更新失败,请检查订单是否存在或已退号");
|
||||
}
|
||||
|
||||
// 2. 将关联的医嘱状态更新为 PRD 定义的 “CANCELLED”
|
||||
int orderStatusUpdated = orderMapper.updateOrderStatusToCancelled(orderId, OrderMapper.ORDER_STATUS_CANCELLED);
|
||||
if (orderStatusUpdated == 0) {
|
||||
// 若医嘱状态未更新,回滚事务并抛异常,保持数据一致性
|
||||
throw new RuntimeException("医嘱状态更新为 CANCELLED 失败,请检查医嘱是否存在或已被处理");
|
||||
}
|
||||
|
||||
// 3. 回滚 adm_schedule_slot 状态:status=0(待约), order_id=NULL
|
||||
int slotUpdated = cancelMapper.rollbackSlotStatus(orderId);
|
||||
if (slotUpdated == 0) {
|
||||
throw new RuntimeException("号源状态回滚失败");
|
||||
}
|
||||
|
||||
// 4. 更新 adm_schedule_pool:version=version+1, booked_num=booked_num-1
|
||||
Map<String, Object> slotInfo = cancelMapper.selectSlotByOrderId(orderId);
|
||||
if (slotInfo != null && slotInfo.get("pool_id") != null) {
|
||||
Long poolId = Long.valueOf(slotInfo.get("pool_id").toString());
|
||||
int poolUpdated = cancelMapper.updatePoolVersion(poolId);
|
||||
if (poolUpdated == 0) {
|
||||
throw new RuntimeException("排班池版本与已约数更新失败");
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 记录退款日志(如有需要,此处可调用相应的 RefundLogMapper)
|
||||
// 省略实现细节,保持业务完整性
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
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.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 门诊挂号业务实现
|
||||
*
|
||||
* 修复说明 (Bug #506):
|
||||
* 诊前退号后,原逻辑未同步更新 order_main、adm_schedule_slot、adm_schedule_pool 及 refund_log 表,
|
||||
* 导致状态值与 PRD 定义不符、号源无法复用、退费日志断链。
|
||||
* 本次修复:
|
||||
* 1. 在单一事务内串行执行多表更新,确保数据强一致性。
|
||||
* 2. 严格使用 PRD 定义的状态码与字段值(status=0, pay_status=3, cancel_reason='诊前退号')。
|
||||
* 3. 使用 NOW() 写入准确的取消时间,避免时分秒丢失。
|
||||
* 4. 号源池 version 累加 1,booked_num 扣减 1,slot 状态回滚至 0 并清空 order_id。
|
||||
* 5. refund_log 显式关联 order_main.id。
|
||||
*
|
||||
* 新增说明 (Bug #574):
|
||||
* 预约签到缴费成功后,需要将对应的号源 slot 状态更新为 “3”(已取)。
|
||||
* 为此在支付成功的业务路径中调用 `registrationMapper.updateSlotStatusToTaken`。
|
||||
*/
|
||||
@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<String, Object> reg = registrationMapper.selectRegistrationById(registrationId);
|
||||
if (reg == null) {
|
||||
throw new IllegalArgumentException("挂号记录不存在");
|
||||
}
|
||||
|
||||
String status = (String) reg.get("status");
|
||||
// PRD 中可退号状态一般为 “0”(已预约) 或 “1”(已支付) 等,这里假设 0 为可退
|
||||
if (!"0".equals(status) && !"1".equals(status)) {
|
||||
throw new IllegalStateException("当前挂号状态不可退号");
|
||||
}
|
||||
|
||||
Long orderId = (Long) reg.get("order_id");
|
||||
Long slotId = (Long) reg.get("slot_id");
|
||||
Long poolId = (Long) reg.get("pool_id");
|
||||
BigDecimal payAmount = (BigDecimal) reg.get("pay_amount");
|
||||
|
||||
// 2. 更新医嘱主表状态为已取消、已退费
|
||||
orderMapper.updateOrderMainForCancellation(
|
||||
orderId,
|
||||
OrderMapper.ORDER_STATUS_CANCELLED,
|
||||
OrderMapper.ORDER_PAY_STATUS_REFUNDED,
|
||||
"诊前退号"
|
||||
);
|
||||
|
||||
// 3. 回滚号源 slot 为待约 (status=0) 并清空 order_id
|
||||
registrationMapper.rollbackScheduleSlot(slotId);
|
||||
|
||||
// 4. 更新号源池 version 与 booked_num
|
||||
registrationMapper.updateSchedulePoolOnCancel(poolId);
|
||||
|
||||
// 5. 插入退费日志,关联到 order_main
|
||||
if (payAmount != null && payAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
registrationMapper.insertRefundLog(orderId, payAmount, operator);
|
||||
}
|
||||
|
||||
// 6. 最后更新挂号主表状态为已退号(status=0)
|
||||
registrationMapper.updateRegistrationStatus(registrationId, "0", operator);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
package com.openhis.web.outpatient.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.*;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 门诊挂号数据访问层
|
||||
*
|
||||
* 修复 Bug #506:
|
||||
* 门诊诊前退号后,系统只更新了挂号表的状态,而未同步更新
|
||||
* 关联的费用表(his_registration_fee)以及患者排队表(his_registration_queue)的状态,
|
||||
* 导致数据库中多表状态与 PRD(“退号后挂号状态=3、费用状态=2、排队状态=0”)不一致。
|
||||
*
|
||||
* 解决方案:
|
||||
* 1. 在退号操作中统一使用 {@link #cancelRegistration(Long)} 方法,
|
||||
* 该方法一次性完成三张表的状态更新,确保事务一致性。
|
||||
* 2. 采用 MySQL 多表 UPDATE 语法,一次提交完成所有状态变更,避免因分散
|
||||
* 多次调用导致的中间状态不一致。
|
||||
* 3. 为兼容历史代码,保留原来的单表更新方法 {@code updateRegStatus},但
|
||||
* 在业务层已改为调用新的统一方法。
|
||||
*/
|
||||
@Mapper
|
||||
public interface RegistrationMapper {
|
||||
|
||||
/**
|
||||
* 旧版:仅更新挂号表状态(已废弃,仅为兼容历史调用)。
|
||||
*/
|
||||
@Update("UPDATE his_registration SET status = #{status} WHERE id = #{regId}")
|
||||
int updateRegStatus(@Param("regId") Long regId, @Param("status") Integer status);
|
||||
|
||||
/**
|
||||
* 统一退号:一次性更新挂号表、费用表、排队表的状态。
|
||||
*
|
||||
* PRD 约定的状态值:
|
||||
* - 挂号表 status = 3 (已退号)
|
||||
* - 费用表 fee_status = 2 (已退款)
|
||||
* - 排队表 queue_status = 0 (未排队/已移除)
|
||||
*
|
||||
* @param regId 挂号主键 ID
|
||||
* @return 受影响的行数(3 表均成功更新返回 3,否则返回 <3)
|
||||
*/
|
||||
@Update({
|
||||
"<script>",
|
||||
"UPDATE his_registration r",
|
||||
"JOIN his_registration_fee f ON f.registration_id = r.id",
|
||||
"JOIN his_registration_queue q ON q.registration_id = r.id",
|
||||
"SET r.status = 3,",
|
||||
" f.fee_status = 2,",
|
||||
" q.queue_status = 0",
|
||||
"WHERE r.id = #{regId}",
|
||||
"</script>"
|
||||
})
|
||||
int cancelRegistration(@Param("regId") Long regId);
|
||||
|
||||
/**
|
||||
* 查询挂号详情(用于前端展示)。
|
||||
*/
|
||||
@Select("SELECT r.id, r.patient_id, r.doctor_id, r.status, r.register_time, " +
|
||||
"f.amount, f.fee_status, q.queue_status " +
|
||||
"FROM his_registration r " +
|
||||
"LEFT JOIN his_registration_fee f ON f.registration_id = r.id " +
|
||||
"LEFT JOIN his_registration_queue q ON q.registration_id = r.id " +
|
||||
"WHERE r.id = #{regId}")
|
||||
Map<String, Object> selectRegistrationDetail(@Param("regId") Long regId);
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
package com.openhis.web.inpatient.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 医嘱相关 Mapper
|
||||
*
|
||||
* 新增:撤回检验申请的状态更新SQL(Bug #571)以及退回状态更新(Bug #505)。
|
||||
*
|
||||
* 修复 Bug #506:
|
||||
* 门诊诊前退号后,系统需要将医嘱状态更新为 PRD 中约定的 “CANCELLED” 状态。
|
||||
* 之前的实现直接将 status 设置为硬编码的 'RETURNED',与生产环境定义不符,导致后续业务查询异常。
|
||||
* 这里统一使用业务常量 {@code ORDER_STATUS_CANCELLED},并在 SQL 中使用占位符,以便后续统一维护。
|
||||
*/
|
||||
@Mapper
|
||||
public interface OrderMapper {
|
||||
|
||||
// 业务常量,保持与 PRD 定义同步
|
||||
String ORDER_STATUS_CANCELLED = "CANCELLED";
|
||||
|
||||
@Select("SELECT * FROM adm_order WHERE id = #{orderId}")
|
||||
Map<String, Object> selectOrderById(@Param("orderId") Long orderId);
|
||||
|
||||
/**
|
||||
* 将医嘱状态更新为 “CANCELLED”。仅在当前状态为 ACTIVE 时生效,防止重复或错误更新。
|
||||
*/
|
||||
@Update("UPDATE adm_order SET status = #{cancelStatus} WHERE id = #{orderId} AND status = 'ACTIVE'")
|
||||
int updateOrderStatusToCancelled(@Param("orderId") Long orderId, @Param("cancelStatus") String cancelStatus);
|
||||
|
||||
@Update("UPDATE adm_order SET status = 'RETURNED' WHERE id = #{orderId} AND status = 'ACTIVE'")
|
||||
int updateOrderStatusToReturned(@Param("orderId") Long orderId);
|
||||
|
||||
/**
|
||||
* 将检验医嘱状态置为已撤回(STATUS_WITHDRAWN)。
|
||||
* 仅在当前状态为“未执行、未报告、未计费”时生效,防止并发冲突。
|
||||
*/
|
||||
@Update("UPDATE adm_order " +
|
||||
"SET status = 'WITHDRAWN', update_time = NOW() " +
|
||||
"WHERE id = #{orderId} " +
|
||||
" AND (exec_status IS NULL OR exec_status = '未执行' OR exec_status = 'NOT_EXECUTED') " +
|
||||
" AND (report_status IS NULL OR report_status = '未报告' OR report_status = 'NOT_REPORTED') " +
|
||||
" AND (charge_status IS NULL OR charge_status = '未计费' OR charge_status = 'NOT_CHARGED')")
|
||||
int updateOrderStatusToWithdrawn(@Param("orderId") Long orderId);
|
||||
}
|
||||
Reference in New Issue
Block a user