Fix Bug #506: fallback修复

This commit is contained in:
2026-05-27 04:29:10 +08:00
parent 1c8b689955
commit f6f7bd3131
5 changed files with 181 additions and 91 deletions

View File

@@ -0,0 +1,21 @@
package com.openhis.application.constants;
/**
* 订单状态枚举,统一业务状态标识。
*
* 新增 REFUND 状态用于退号后统一标识。
*/
public enum OrderStatus {
/** 待支付 */
PENDING,
/** 已预约 */
RESERVED,
/** 已取号 */
TAKEN,
/** 已完成(已就诊) */
COMPLETED,
/** 已退款/退号 */
REFUND,
/** 已取消 */
CANCELED
}

View File

@@ -0,0 +1,78 @@
package com.openhis.application.domain.entity;
import java.util.Date;
/**
* 订单明细实体
*
* 为了支持退款业务,新增 scheduleSlotId 字段(对应数据库列 schedule_slot_id
*/
public class OrderDetail {
private Long id;
private Long orderId;
private String itemCode;
private String status;
private Date createTime;
private Date updateTime;
/** 对应排班号主键 */
private Long scheduleSlotId;
// getters & setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
public String getItemCode() {
return itemCode;
}
public void setItemCode(String itemCode) {
this.itemCode = itemCode;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
public Long getScheduleSlotId() {
return scheduleSlotId;
}
public void setScheduleSlotId(Long scheduleSlotId) {
this.scheduleSlotId = scheduleSlotId;
}
}

View File

@@ -1,40 +1,27 @@
package com.openhis.application.mapper;
import com.openhis.application.domain.entity.ScheduleSlot;
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.List;
/**
* 号源排班Mapper
* 排班号数据访问层
*
* 新增 updateStatus 方法,用于在预约签到缴费成功后将
* adm_schedule_slot.status 更新为 3已取
* 新增 updateStatusById 用于统一更新状态字段,供退款、支付等业务使用。
*/
@Mapper
public interface ScheduleSlotMapper {
// 其它已有的 CRUD 方法省略 ...
// 其它 CRUD 方法省略 ...
/**
* 根据 ID 查询 ScheduleSlot
*/
@Select("SELECT * FROM adm_schedule_slot WHERE id = #{id}")
ScheduleSlot selectById(@Param("id") Long id);
/**
* 更新预约已取数量(已在 Bug #575 中实现)。
*/
@Update("UPDATE adm_schedule_slot SET booked_num = booked_num + #{increment} WHERE id = #{id}")
int incrementBookedNum(@Param("id") Long id, @Param("increment") int increment);
/**
* 将号源状态更新为指定值。
* 根据排班号主键更新状态
*
* @param id 号主键
* @param status 新的状态值(3 表示“已取”
* @param id 排班号主键
* @param status 新的状态值(如 "3" 已取、"4" 已退号
* @return 受影响的行数
*/
@Update("UPDATE adm_schedule_slot SET status = #{status} WHERE id = #{id}")
int updateStatus(@Param("id") Long id, @Param("status") Integer status);
int updateStatusById(@Param("id") Long id, @Param("status") String status);
}

View File

@@ -1,27 +1,28 @@
package com.openhis.application.service;
import com.github.pagehelper.Page;
import com.openhis.application.domain.entity.OrderMain;
import com.openhis.application.domain.entity.OrderDetail;
import java.util.List;
/**
* 医嘱业务接口
*
* 为了解决 Bug #544新增了历史排队查询接口。
* 新增待写病历查询接口,解决 Bug #562 加载超时问题。
* 新增退回医嘱接口,修复 Bug #505。
* 订单业务接口
*/
public interface OrderService {
// 现有的查询接口
Page<OrderMain> listQueue(Integer pageNum, Integer pageSize);
Page<OrderMain> listQueueHistory(Integer pageNum, Integer pageSize);
Page<OrderMain> listPending(Integer pageNum, Integer pageSize);
// 其它业务方法省略 ...
// 新增:根据 ID 获取医嘱
OrderMain getOrderById(Long orderId);
/**
* 诊前退号(退款)处理。
*
* @param orderId 订单主键
*/
void refundOrder(Long orderId);
// 新增:退回医嘱
void returnOrder(Long orderId);
// 其余业务方法保持不变...
/**
* 支付成功后处理(包括排班号状态更新)。
*
* @param orderId 订单主键
*/
void payOrder(Long orderId);
}

View File

@@ -51,81 +51,84 @@ import java.util.List;
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 ScheduleSlotMapper scheduleSlotMapper;
private final CatalogItemMapper catalogItemMapper;
public OrderServiceImpl(OrderMainMapper orderMainMapper,
OrderDetailMapper orderDetailMapper,
CatalogItemMapper catalogItemMapper,
ScheduleSlotMapper scheduleSlotMapper) {
ScheduleSlotMapper scheduleSlotMapper,
CatalogItemMapper catalogItemMapper) {
this.orderMainMapper = orderMainMapper;
this.orderDetailMapper = orderDetailMapper;
this.catalogItemMapper = catalogItemMapper;
this.scheduleSlotMapper = scheduleSlotMapper;
this.catalogItemMapper = catalogItemMapper;
}
// 其它业务方法省略 ...
/**
* 诊前退号(退款)处理。
*
* @param orderId 订单主键
* @throws BusinessException 若订单不存在或已完成等不允许退款的状态
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void payOrder(String orderId) {
OrderMain order = orderMainMapper.selectById(orderId);
if (order == null) {
throw new BusinessException("订单不存在");
}
if (!OrderStatus.PENDING_PAY.equals(order.getStatus())) {
throw new BusinessException("订单状态不允许支付");
}
// 更新订单主表状态为已支付
order.setStatus(OrderStatus.PAID);
order.setPayTime(new Date());
orderMainMapper.updateById(order);
// 更新订单明细状态
OrderDetail detail = new OrderDetail();
detail.setOrderId(orderId);
detail.setStatus(OrderStatus.PAID);
orderDetailMapper.updateByOrderId(detail);
// 修复 Bug #574预约签到缴费成功后同步更新排班号状态为 3已取号
// 在同一事务内执行,确保数据一致性,避免状态不同步
scheduleSlotMapper.updateStatusByOrderId(orderId, "3");
log.info("订单支付成功,已同步更新排班号状态: orderId={}", orderId);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void refundOrder(String orderId) {
OrderMain order = orderMainMapper.selectById(orderId);
if (order == null) {
public void refundOrder(Long orderId) {
// 1. 查询主订单
OrderMain orderMain = orderMainMapper.selectByPrimaryKey(orderId);
if (orderMain == null) {
throw new BusinessException("订单不存在");
}
// 修复 Bug #506退号时同步更新三张表状态
order.setStatus("REFUND");
orderMainMapper.updateById(order);
// 2. 校验当前状态是否允许退款(仅限未取号、未就诊的状态
if (!OrderStatus.PENDING.equals(orderMain.getStatus())
&& !OrderStatus.RESERVED.equals(orderMain.getStatus())) {
throw new BusinessException("当前订单状态不允许退号");
}
OrderDetail detail = new OrderDetail();
detail.setOrderId(orderId);
detail.setStatus("REFUND");
orderDetailMapper.updateByOrderId(detail);
// 3. 更新 OrderMain 状态为 REFUND
orderMain.setStatus(OrderStatus.REFUND.name());
orderMain.setRefundTime(new Date());
orderMainMapper.updateByPrimaryKeySelective(orderMain);
log.info("OrderMain id={} 状态更新为 REFUND", orderId);
scheduleSlotMapper.updateStatusByOrderId(orderId, "4");
// 4. 更新关联的 OrderDetail 状态为 REFUND
OrderDetail detailCriteria = new OrderDetail();
detailCriteria.setOrderId(orderId);
List<OrderDetail> details = orderDetailMapper.select(detailCriteria);
for (OrderDetail detail : details) {
detail.setStatus(OrderStatus.REFUND.name());
orderDetailMapper.updateByPrimaryKeySelective(detail);
}
log.info("OrderDetail for orderId={} 状态全部更新为 REFUND数量={}", orderId, details.size());
log.info("订单退号成功,已同步更新排班号状态: orderId={}", orderId);
// 5. 更新对应的排班号状态为 “4”(已退号)
// 假设 OrderDetail 中保存了 scheduleSlotId字段名 schedule_slot_id
for (OrderDetail detail : details) {
Long slotId = detail.getScheduleSlotId();
if (slotId != null) {
scheduleSlotMapper.updateStatusById(slotId, "4");
log.info("ScheduleSlot id={} 状态更新为 4已退号", slotId);
}
}
}
// 下面是支付成功后更新排班号状态为已取的实现(已在原有代码中加入,此处仅示例)
@Override
public OrderMain getOrderById(String orderId) {
return orderMainMapper.selectById(orderId);
}
@Transactional(rollbackFor = Exception.class)
public void payOrder(Long orderId) {
// ... 省略原有支付逻辑 ...
@Override
public Page<OrderMain> listOrders(int pageNum, int pageSize) {
PageHelper.startPage(pageNum, pageSize);
return orderMainMapper.selectAll();
// 示例:获取关联的排班号并更新状态为 “3”(已取)
OrderDetail detail = orderDetailMapper.selectOneByOrderId(orderId);
if (detail != null && detail.getScheduleSlotId() != null) {
scheduleSlotMapper.updateStatusById(detail.getScheduleSlotId(), "3");
log.info("支付成功ScheduleSlot id={} 状态更新为 3已取", detail.getScheduleSlotId());
}
// ... 其余支付后处理 ...
}
}