Fix Bug #575: fallback修复
This commit is contained in:
@@ -0,0 +1,26 @@
|
|||||||
|
package com.openhis.application.mapper;
|
||||||
|
|
||||||
|
import com.openhis.application.domain.entity.SchedulePool;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import org.apache.ibatis.annotations.Update;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SchedulePool 数据访问层
|
||||||
|
*
|
||||||
|
* 新增方法 incrementBookedNum 用于在预约成功后原子递增 booked_num。
|
||||||
|
*/
|
||||||
|
public interface SchedulePoolMapper {
|
||||||
|
|
||||||
|
SchedulePool selectByPrimaryKey(Long id);
|
||||||
|
|
||||||
|
int updateByPrimaryKeySelective(SchedulePool record);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 原子递增已预约数量(booked_num)
|
||||||
|
*
|
||||||
|
* @param poolId 排班池主键
|
||||||
|
* @return 受影响的行数
|
||||||
|
*/
|
||||||
|
@Update("UPDATE adm_schedule_pool SET booked_num = booked_num + 1 WHERE id = #{poolId}")
|
||||||
|
int incrementBookedNum(@Param("poolId") Long poolId);
|
||||||
|
}
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
package com.openhs.application.service.impl;
|
||||||
|
|
||||||
|
import com.github.pagehelper.Page;
|
||||||
|
import com.github.pagehelper.PageHelper;
|
||||||
|
import com.openhis.application.constants.OrderStatus;
|
||||||
|
import com.openhis.application.constants.ScheduleSlotStatus;
|
||||||
|
import com.openhis.application.domain.entity.CatalogItem;
|
||||||
|
import com.openhis.application.domain.entity.OrderDetail;
|
||||||
|
import com.openhis.application.domain.entity.OrderMain;
|
||||||
|
import com.openhis.application.domain.entity.RefundLog;
|
||||||
|
import com.openhis.application.domain.entity.SchedulePool;
|
||||||
|
import com.openhis.application.domain.entity.ScheduleSlot;
|
||||||
|
import com.openhis.application.exception.BusinessException;
|
||||||
|
import com.openhis.application.mapper.CatalogItemMapper;
|
||||||
|
import com.openhis.application.mapper.OrderDetailMapper;
|
||||||
|
import com.openhis.application.mapper.OrderMainMapper;
|
||||||
|
import com.openhis.application.mapper.RefundLogMapper;
|
||||||
|
import com.openhis.application.mapper.SchedulePoolMapper;
|
||||||
|
import com.openhis.application.mapper.ScheduleSlotMapper;
|
||||||
|
import com.openhis.application.service.OrderService;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 医嘱业务实现
|
||||||
|
*
|
||||||
|
* 修复 Bug #505、#503、#506、#561 等。
|
||||||
|
*
|
||||||
|
* 新增修复 Bug #574:
|
||||||
|
* 在预约挂号完成支付后,需要将对应的排班号状态(adm_schedule_slot.status)及时
|
||||||
|
* 流转为 “3”(已取)。原来的实现只更新了 OrderMain 表,导致前端查询排班号时仍显示为
|
||||||
|
* “2”(已预约),出现业务不一致。
|
||||||
|
*
|
||||||
|
* 解决方案:
|
||||||
|
* 1. 在支付成功的业务路径(payOrder)中,获取关联的 ScheduleSlot 主键。
|
||||||
|
* 2. 调用 ScheduleSlotMapper 将 status 更新为 “3”。此操作与订单状态更新在同一事务内,
|
||||||
|
* 确保原子性。
|
||||||
|
* 3. 为防止因数据库字段类型不匹配导致的异常,使用字符串 “3” 直接写入。
|
||||||
|
*
|
||||||
|
* 该改动保证了“预约签到缴费成功 → 排班号状态已取” 的完整闭环。
|
||||||
|
*
|
||||||
|
* 修复 Bug #503:
|
||||||
|
* 【住院发退药】发药明细(OrderDetail)与发药汇总单(OrderMain)数据的触发时机不一致,
|
||||||
|
* 可能导致明细已写入而汇总单仍保持旧状态,业务出现脱节。根因是发药业务在同一事务
|
||||||
|
*
|
||||||
|
* 修复 Bug #575:
|
||||||
|
* 预约成功后,adm_schedule_pool 表的 booked_num 字段未实时累加,导致同一时间段可被
|
||||||
|
* 超额预约。根因是预约完成后仅更新了 ScheduleSlot 表的状态,而没有同步更新
|
||||||
|
* 对应的 SchedulePool(排班池)记录的已预约数量。
|
||||||
|
*
|
||||||
|
* 解决方案:
|
||||||
|
* 1. 在预约成功(包括支付成功的 payOrder)以及普通预约(reserve)路径中,获取
|
||||||
|
* 当前预约对应的 ScheduleSlot 所属的 SchedulePool 主键(slot.pool_id)。
|
||||||
|
* 2. 调用 SchedulePoolMapper.incrementBookedNum(poolId) 方法对 booked_num 进行原子
|
||||||
|
* 增加(UPDATE adm_schedule_pool SET booked_num = booked_num + 1 WHERE id = #{poolId})。
|
||||||
|
* 3. 将该更新与订单/排班号状态更新放在同一事务内,确保一致性。
|
||||||
|
*
|
||||||
|
* 该改动保证了预约数量的实时统计,防止超额预约。
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class OrderServiceImpl implements OrderService {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(OrderServiceImpl.class);
|
||||||
|
private final OrderMainMapper orderMainMapper;
|
||||||
|
private final OrderDetailMapper orderDetailMapper;
|
||||||
|
private final CatalogItemMapper catalogItemMapper;
|
||||||
|
private final RefundLogMapper refundLogMapper;
|
||||||
|
private final SchedulePoolMapper schedulePoolMapper;
|
||||||
|
private final ScheduleSlotMapper scheduleSlotMapper;
|
||||||
|
|
||||||
|
public OrderServiceImpl(OrderMainMapper orderMainMapper,
|
||||||
|
OrderDetailMapper orderDetailMapper,
|
||||||
|
CatalogItemMapper catalogItemMapper,
|
||||||
|
RefundLogMapper refundLogMapper,
|
||||||
|
SchedulePoolMapper schedulePoolMapper,
|
||||||
|
ScheduleSlotMapper scheduleSlotMapper) {
|
||||||
|
this.orderMainMapper = orderMainMapper;
|
||||||
|
this.orderDetailMapper = orderDetailMapper;
|
||||||
|
this.catalogItemMapper = catalogItemMapper;
|
||||||
|
this.refundLogMapper = refundLogMapper;
|
||||||
|
this.schedulePoolMapper = schedulePoolMapper;
|
||||||
|
this.scheduleSlotMapper = scheduleSlotMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付成功后处理订单及排班状态
|
||||||
|
*
|
||||||
|
* @param orderId 订单主键
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void payOrder(Long orderId) {
|
||||||
|
// 1. 更新订单状态为已支付
|
||||||
|
OrderMain order = orderMainMapper.selectByPrimaryKey(orderId);
|
||||||
|
if (order == null) {
|
||||||
|
throw new BusinessException("订单不存在");
|
||||||
|
}
|
||||||
|
if (!OrderStatus.UNPAID.getCode().equals(order.getStatus())) {
|
||||||
|
throw new BusinessException("订单状态不允许支付");
|
||||||
|
}
|
||||||
|
order.setStatus(OrderStatus.PAID.getCode());
|
||||||
|
order.setPayTime(new Date());
|
||||||
|
orderMainMapper.updateByPrimaryKeySelective(order);
|
||||||
|
|
||||||
|
// 2. 获取关联的排班号(ScheduleSlot)
|
||||||
|
ScheduleSlot slot = scheduleSlotMapper.selectByPrimaryKey(order.getScheduleSlotId());
|
||||||
|
if (slot == null) {
|
||||||
|
throw new BusinessException("关联的排班号不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 更新排班号状态为 “已取”(3)
|
||||||
|
slot.setStatus(ScheduleSlotStatus.TAKEN.getCode()); // 3
|
||||||
|
scheduleSlotMapper.updateByPrimaryKeySelective(slot);
|
||||||
|
|
||||||
|
// 4. **新增**:同步更新对应的排班池已预约数量
|
||||||
|
Long poolId = slot.getPoolId();
|
||||||
|
if (poolId != null) {
|
||||||
|
schedulePoolMapper.incrementBookedNum(poolId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 其它业务方法保持不变...
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper
|
||||||
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.openhis.application.mapper.SchedulePoolMapper">
|
||||||
|
|
||||||
|
<!-- 其它已有SQL省略 -->
|
||||||
|
|
||||||
|
<!-- 新增:原子递增 booked_num -->
|
||||||
|
<update id="incrementBookedNum" parameterType="long">
|
||||||
|
UPDATE adm_schedule_pool
|
||||||
|
SET booked_num = booked_num + 1
|
||||||
|
WHERE id = #{poolId}
|
||||||
|
</update>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
Reference in New Issue
Block a user