利用Cron表达式生成器生成Cron表达式
1.处理超时订单
查询订单表把超时的订单查询出来,也就是订单的状态为待付款,下单的时间已经超过了15分钟。
//select * from orders where status = ? and order_time < (当前时间 - 15分钟)
遍历集合把数据库查出来的超时订单状态修改成已取消状态,设置取消原因为订单超时,自动取消,设置取消时间为当前时间。
<update id="update" parameterType="com.sky.entity.Orders">
update orders
<set>
<if test="cancelReason != null and cancelReason!='' "> cancel_reason=#{cancelReason}, </if>
<if test="rejectionReason != null and rejectionReason!='' "> rejection_reason=#{rejectionReason}, </if>
<if test="cancelTime != null"> cancel_time=#{cancelTime}, </if>
<if test="payStatus != null"> pay_status=#{payStatus}, </if>
<if test="payMethod != null"> pay_method=#{payMethod}, </if>
<if test="checkoutTime != null"> checkout_time=#{checkoutTime}, </if>
<if test="status != null"> status = #{status}, </if>
<if test="deliveryTime != null"> delivery_time = #{deliveryTime} </if>
</set>
where id = #{id}
</update>
2.处理一直处于派送中状态的订单
这个我们让它每天凌晨一点自动触发一次。
查询订单表把派送中的订单查询出来,也就是订单的状态为派送中,我们是查上一个工作日也就是当前时间减去一个小时,因为它是凌晨一点触发的。
//select * from orders where status = ? and order_time < (当前时间 - 60分钟)
遍历集合把数据库查出来的派送中订单状态修改成已完成状态。
package com.sky.task;
import com.sky.entity.Orders;
import com.sky.mapper.OrderMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.List;
/**
* 定时任务类,定时处理订单状态
*/
@Component
@Slf4j
public class OrderTask {
@Autowired
private OrderMapper orderMapper;
/**
* 处理超时订单的方法
*/
@Scheduled(cron = "0 * * * * ? ")//每分钟触发一次
public void processTimeoutOrder(){
log.info("定时处理超时订单:{}", LocalDateTime.now());
//select * from orders where status = ? and order_time < (当前时间 - 15分钟)
LocalDateTime time = LocalDateTime.now().plusMinutes(-15);
List<Orders> ordersList = orderMapper.getByStatusAndOrderTimeLT(Orders.PENDING_PAYMENT, time);
if (ordersList != null && ordersList.size() > 0){
for (Orders orders : ordersList) {
orders.setStatus(Orders.CANCELLED);
orders.setCancelReason("订单超时,自动取消");
orders.setCancelTime(LocalDateTime.now());
orderMapper.update(orders);
}
}
}
/**
* 处理一直处于派送中状态的订单
*/
@Scheduled(cron = "0 0 1 * * ?")//每天凌晨一点触发一次
public void processDeliveryOrder(){
log.info("定时处理处于派送中的订单:{}",LocalDateTime.now());
LocalDateTime time = LocalDateTime.now().plusMinutes(-60);
List<Orders> ordersList = orderMapper.getByStatusAndOrderTimeLT(Orders.DELIVERY_IN_PROGRESS, time);
if (ordersList != null && ordersList.size() > 0){
for (Orders orders : ordersList) {
orders.setStatus(Orders.COMPLETED);
orderMapper.update(orders);
}
}
}
}
·功能测试
·补充
LocalDateTime综合了LocalDate和LocalTime里面的方法,所以下面只用LocalDate和LocalTime来举例。
·这些方法返回的是一个新的实例引用,因为LocalDateTime、LocalDate、LocalTime都是不可变的。
方法名 说明
plusDays,plusWeeks,plusMonths,plusYears 向当前LocalDate对象添加几天、几周、几个月、几年
minusDay,minusWeeks,minusMonths,minusYears 从LocalDate对象减去几天、几周、几个月、几年
withDayOfMonth,withDayOfYear,withMonth,withYear 将月份天数、年份天数、月份、年份修改为指定的值并返回新的LocalDate对象
isBefore,isAfter 比较两个LocalDate