Skip to content

订单状态定时处理


需求分析

用户下单后可能存在的情况

下单后未支付,订单一直处于待支付状态

用户收货后管理端未点击完成按钮,订单一直处于派送中状态

对于上面两种情况需要通过定时任务来修改订单状态,具体逻辑为

通过定时任务每分钟检查一次是否存在支付超时订单(下单后超过 15 分钟仍未支付则判定为支付超时订单),如果存在则修改订单状态为已取消

通过定时任务每天凌晨 1 点检查一次是否存在派送中的订单,如果存在则修改订单状态为已完成

代码实现

OrderTask

自定义定时任务类 OrderTask(待完善)

java
package com.sky.task;

/**
 * 自定义定时任务,实现订单状态定时处理
 */
@Component
@Slf4j
public class OrderTask {

    @Autowired
    private OrderMapper orderMapper;

    /**
     * 处理支付超时订单
     */
    @Scheduled(cron = "0 * * * * ?")
    public void processTimeoutOrder(){
        log.info("处理支付超时订单:{}", new Date());
    }

    /**
     * 处理“派送中”状态的订单
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void processDeliveryOrder(){
        log.info("处理派送中订单:{}", new Date());
    }

}

OrderMapper

在 OrderMapper 接口中扩展方法

java
/**
 * 根据状态和下单时间查询订单
 * @param status
 * @param orderTime
 */
@Select("select * from orders where status = #{status} and order_time < #{orderTime}")
List<Orders> getByStatusAndOrdertimeLT(Integer status, LocalDateTime orderTime);

完善定时任务类

(1)processTimeoutOrder

java
/**
 * 处理支付超时订单
 */
@Scheduled(cron = "0 * * * * ?")
public void processTimeoutOrder(){
    log.info("处理支付超时订单:{}", new Date());

    LocalDateTime time = LocalDateTime.now().plusMinutes(-15);

    // select * from orders where status = 1 and order_time < 当前时间-15分钟
    List<Orders> ordersList = orderMapper.getByStatusAndOrdertimeLT(Orders.PENDING_PAYMENT, time);
    if(ordersList != null && ordersList.size() > 0){
        ordersList.forEach(order -> {
            order.setStatus(Orders.CANCELLED);
            order.setCancelReason("支付超时,自动取消");
            order.setCancelTime(LocalDateTime.now());
            orderMapper.update(order);
        });
    }
}

(2)processDeliveryOrder

java
/**
 * 处理“派送中”状态的订单
 */
@Scheduled(cron = "0 0 1 * * ?")
public void processDeliveryOrder(){
    log.info("处理派送中订单:{}", new Date());
    // select * from orders where status = 4 and order_time < 当前时间-1小时
    LocalDateTime time = LocalDateTime.now().plusMinutes(-60);
    List<Orders> ordersList = orderMapper.getByStatusAndOrdertimeLT(Orders.DELIVERY_IN_PROGRESS, time);

    if(ordersList != null && ordersList.size() > 0){
        ordersList.forEach(order -> {
            order.setStatus(Orders.COMPLETED);
            orderMapper.update(order);
        });
    }
}