订单状态定时处理功能

需求分析:

主要针对两种情况

1、下单后一直处于”未支付“状态

2、用户收货后未点完成按钮,订单一直处于“派送中”状态

解决:

情况1:

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

情况2:

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

使用技术:

SpingTask框架,该框架底层是使用JDK提供的定时任务工具类Timer和TimerTask,通过线程池利用线程来运行每个定时任务,因此不要随意乱用定时任务,会造成线程资源耗尽性能过慢

大致流程:

1、在启动类上添加@EnableScheduling

2、创建自定义定时任务类,添加到IOC容器

3、在定时任务方法上方添加@Scheduled ( cron = "这里设置cron表达式" )

首先来看下处理两种情况需要共有的Mapper

    <update id="updateStatusByIds">
        update orders
        <set>
            <if test="status != null">
                status = #{status}
            </if>
        </set>
        where id in
        <foreach collection="ordersArrayList" item="orderId" separator="," open="(" close=")">
            #{orderId}
        </foreach>
    </update>

    <select id="selectByStatusAndOrderTime" resultType="com.sky.entity.Orders">
        select * from orders
        <where>
            <if test="status != null">
                status = #{status}
            </if>
            <if test="checkTime != null">
                and order_time &lt;= #{checkTime}
            </if>
        </where>
    </select>

说明:

selectByStatusAndOrderTime 的功能是通过订单状态和传入的时间查找超时的订单

updateStatusByIds 的功能是将符合条件的订单状态修改

注意 :

order_time & lt ; =  #{checkTime}表示 order_time <= #{checkTime}

&gt 则表示 >

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

 /**
     * 将超时未支付订单状态改为取消
     * 1、每分钟检查一次
     * 2、检测订单状态为未支付且超过下单时间15分钟的订单
     * 3、将符合条件的订单状态修改为已取消
     */
    @Scheduled(cron = "0 * * * * ?")
    public void cancelOrder(){
        //获取到15分钟前的时间
        LocalDateTime checkTime = LocalDateTime.now().minusMinutes(15);
        //根据订单状态和15分钟前时间查询未支付且超时了的订单
        List<Orders> ordersList = orderMapper.selectByStatusAndOrderTime(Orders.PENDING_PAYMENT,checkTime);
        //将这些订单的id统一存入一个集合
        if(ordersList != null && ordersList.size() > 0){
            ArrayList<Long> ordersArrayList = new ArrayList<>();
            for (Orders orders : ordersList) {
                ordersArrayList.add(orders.getId());
            }
            //通过ids将这些订单状态修改为取消
            orderMapper.updateStatusByIds(ordersArrayList,Orders.CANCELLED);
            log.info("处理了{}份超时订单",ordersList.size());
        }else{
            log.info("没有超时订单");
        }
    }

这里不做过多说明,注解中有详细解释

处理前一天派送中的订单

  /**
     * 每天凌晨1点检查一次,将在配送中的订单状态改为已完成
     * 获取到前一天的所有状态为配送中的订单
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void completeOrder(){
        LocalDateTime yesterday = LocalDateTime.now().minusHours(1);
        List<Orders> orders = orderMapper.selectByStatusAndOrderTime(Orders.DELIVERY_IN_PROGRESS, yesterday);
        if(orders != null && orders.size()>0) {
            ArrayList<Long> ids = new ArrayList<>();
            for (Orders order : orders) {
                ids.add(order.getId());
            }
            orderMapper.updateStatusByIds(ids, Orders.COMPLETED);
            log.info("处理了{}份前一天配送的订单",orders.size());
        }
        log.info("前一天配送的订单已全部完成");
    }

同样的这里使用到的逻辑和上一个类似,只是条件和cron表达式变化了一下

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值