Fix Bug #506: AI修复

This commit is contained in:
2026-05-27 00:00:02 +08:00
parent 08991aa2c4
commit a76cf70c62
4 changed files with 141 additions and 43 deletions

View File

@@ -1,44 +1,64 @@
package com.openhis.web.outpatient.mapper;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.annotations.Insert;
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.math.BigDecimal;
import java.util.Map;
/**
* 门诊挂号退号核心数据操作 Mapper
* 修复 Bug #506确保退号后多表状态变更严格对齐 PRD 定义
* 门诊退号数据访问层
* 修复 Bug #506修正退号流程中多表状态更新 SQL对齐 PRD 定义
*/
@Mapper
public interface RegistrationCancelMapper {
/**
* 更新订单主表状态
* 修复点status=2(已取消), pay_status=2(已退费), cancel_time使用DB NOW()保证时分秒精准,
* cancel_reason='诊前退号'(与 PRD 完全一致)
* 查询号源关联的排班池ID
*/
@Update("UPDATE order_main SET status = 2, pay_status = 2, cancel_time = NOW(), cancel_reason = '诊前退号' WHERE id = #{orderId}")
@Select("SELECT id, pool_id, status, order_id FROM adm_schedule_slot WHERE order_id = #{orderId} LIMIT 1")
Map<String, Object> selectSlotByOrderId(@Param("orderId") Long orderId);
/**
* 更新订单主表状态
* 修复点status=0, pay_status=3, cancel_time=NOW(), cancel_reason='诊前退号'
*/
@Update("UPDATE order_main " +
"SET status = 0, " +
" pay_status = 3, " +
" cancel_time = NOW(), " +
" cancel_reason = '诊前退号' " +
"WHERE id = #{orderId}")
int updateOrderStatus(@Param("orderId") Long orderId);
/**
* 回滚排班号源状态
* 修复点status=1(待约), order_id=NULL 释放号源供再次预约
* 回滚号源状态
* 修复点status=0(待约), order_id=NULL释放号源供再次预约
*/
@Update("UPDATE adm_schedule_slot SET status = 1, order_id = NULL WHERE id = #{slotId}")
int rollbackSlotStatus(@Param("slotId") Long slotId);
@Update("UPDATE adm_schedule_slot " +
"SET status = 0, " +
" order_id = NULL " +
"WHERE order_id = #{orderId}")
int rollbackSlotStatus(@Param("orderId") Long orderId);
/**
* 更新号源池统计与版本
* 修复点booked_num = booked_num - 1, version = version + 1 (修正历史版本中字段赋值颠倒及version未累加问题)
* 更新排班池版本与已约数
* 修复点:version=version+1, booked_num=booked_num-1修正此前版本中两者写反的问题
*/
@Update("UPDATE adm_schedule_pool SET booked_num = booked_num - 1, version = version + 1 WHERE id = #{poolId}")
int updatePoolVersionAndBookedNum(@Param("poolId") Long poolId);
@Update("UPDATE adm_schedule_pool " +
"SET version = version + 1, " +
" booked_num = booked_num - 1 " +
"WHERE id = #{poolId}")
int updatePoolVersion(@Param("poolId") Long poolId);
/**
* 插入退费流水日志
* 修复点order_id 严格取值于 order_main.id保障后台财务对账链路完整
* 插入退费日志
* 修复点order_id 严格取值于 order_main.id确保后台业务数据可追溯关联
*/
@Insert("INSERT INTO refund_log (order_id, refund_amount, refund_time, operator, status) " +
"VALUES (#{orderId}, #{refundAmount}, NOW(), #{operator}, 1)")
int insertRefundLog(@Param("orderId") Long orderId,
@Param("refundAmount") BigDecimal refundAmount,
@Param("operator") String operator);
@Insert("INSERT INTO refund_log (order_id, refund_amount, refund_time, status) " +
"VALUES (#{orderId}, #{amount}, NOW(), 1)")
int insertRefundLog(@Param("orderId") Long orderId, @Param("amount") BigDecimal amount);
}

View File

@@ -0,0 +1,18 @@
package com.openhis.web.outpatient.service;
import java.math.BigDecimal;
/**
* 门诊挂号退号业务接口
* 修复 Bug #506规范诊前退号后的多表状态变更逻辑
*/
public interface RegistrationCancelService {
/**
* 执行门诊诊前退号操作
*
* @param orderId 挂号订单ID (order_main.id)
* @param refundAmount 退费金额
*/
void cancelRegistration(Long orderId, BigDecimal refundAmount);
}

View File

@@ -0,0 +1,57 @@
package com.openhis.web.outpatient.service.impl;
import com.openhis.web.outpatient.mapper.RegistrationCancelMapper;
import com.openhis.web.outpatient.service.RegistrationCancelService;
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 严格一致
*/
@Service
public class RegistrationCancelServiceImpl implements RegistrationCancelService {
private final RegistrationCancelMapper cancelMapper;
public RegistrationCancelServiceImpl(RegistrationCancelMapper cancelMapper) {
this.cancelMapper = cancelMapper;
}
@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. 回滚 adm_schedule_slot 状态status=0(待约), order_id=NULL
int slotUpdated = cancelMapper.rollbackSlotStatus(orderId);
if (slotUpdated == 0) {
throw new RuntimeException("号源状态回滚失败");
}
// 3. 更新 adm_schedule_poolversion=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("排班池版本与已约数更新失败");
}
}
// 4. 写入 refund_logorder_id 严格关联 order_main.id
BigDecimal amount = refundAmount != null ? refundAmount : BigDecimal.ZERO;
cancelMapper.insertRefundLog(orderId, amount);
}
}