Xxl-Job实现订单30分钟未支付自动取消

数据库

配置文件

yaml 复制代码
xxl:
  job:
    admin:
      addresses: http://localhost:8080/xxl-job-admin/
      accessToken: default_token
      timeout: 30
    cookie: XXL_JOB_LOGIN_IDENTITY=
    executor:
      appname: springboot3
      address:
      ip:
      port: 9989
      logPath:
      logretentiondays: 10

配置xxlJob任务参数

java 复制代码
import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Component
@PropertySource("classpath:xxl-job-info.properties")
@ConfigurationProperties(prefix = "xxl-job-info")
@Data
@ToString
public class XxlJobInfoVO {
    private String jobGroup;
    private String jobDesc;
    private String author;
    private String scheduleType;
    private String glueType;
    private String executorHandler;
    private String executorRouteStrategy;
    private String misfireStrategy;
    private String executorBlockStrategy;
    private String executorTimeout;
    private String executorFailRetryCount;
    private String glueRemark;
    private String triggerStatus;

}

xxl-job-info.properties

yaml 复制代码
# \u5B9A\u65F6\u5668\u7EC4
#这里需要根据自己的执行器改
xxl-job-info.jobGroup=5
# \u63CF\u8FF0
xxl-job-info.jobDesc=\u667A\u6167\u533B\u517B\u5EB7\u8BA2\u5355\u5B9A\u65F6\u53D6\u6D88\u652F\u4ED8
# \u521B\u5EFA\u8005
xxl-job-info.author=stx
# \u5B9A\u65F6\u5668\u7C7B\u578B
xxl-job-info.scheduleType=CRON
# glue\u7C7B\u578B
xxl-job-info.glueType=BEAN
# \u6267\u884C\u5668\u4EFB\u52A1handler
xxl-job-info.executorHandler=cancelPay
# \u6267\u884C\u5668\u8DEF\u7531\u7B56\u7565
xxl-job-info.executorRouteStrategy=FIRST
# \u8C03\u5EA6\u8FC7\u671F\u7B56\u7565
xxl-job-info.misfireStrategy=DO_NOTHING
# \u963B\u585E\u5904\u7406\u7B56\u7565
xxl-job-info.executorBlockStrategy=SERIAL_EXECUTION
# \u4EFB\u52A1\u6267\u884C\u8D85\u65F6\u65F6\u95F4\uFF0C\u5355\u4F4D\u79D2
xxl-job-info.executorTimeout=0
# \u5931\u8D25\u91CD\u8BD5\u6B21\u6570
xxl-job-info.executorFailRetryCount=0
# GLUE\u5907\u6CE8
xxl-job-info.glueRemark=GLUE\u4EE3\u7801\u521D\u59CB\u5316
# \u8C03\u5EA6\u72B6\u6001\uFF1A0-\u505C\u6B62\uFF0C1-\u8FD0\u884C
xxl-job-info.triggerStatus=1

CancelPayUtil

java 复制代码
@Component
//@RestController
public class CancelPayUtil {

    @Value("${xxl.job.cookie}")
    private String cookie;

    @Value("${xxl.job.admin.addresses}")
    private String xxlJobAdminAddr;

    @Autowired
    private XxlJobInfoVO xxlJobInfoVO;

    //@GetMapping("/removeCancelJob")
    public Boolean removeCancelJob(String jobId) {

        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        //设置为form方式
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.add("Cookie", cookie);
        MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
        map.add("id",jobId);
        HttpEntity<MultiValueMap<String, String>> requestb = new HttpEntity<MultiValueMap<String, String>>(map, headers);
        ResponseEntity<String> response = restTemplate.postForEntity(xxlJobAdminAddr + "/jobinfo/remove", requestb, String.class);
        String regionString = response.getBody();//获取请求体
        JSONObject jsonObject = JSONObject.parseObject(regionString,JSONObject.class);//将请求体转化为json格式
        String code = jsonObject.getString("code");
        if (!("200".equals(code))) {
            throw new IllegalArgumentException("xxl-job定时任务删除失败");
        }

        return true;

    }

    //@GetMapping("/uploadCancelJob")
    public String uploadCancelJob(String cron, String orderId) {
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        //设置为form方式
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.add("Cookie", cookie);
        MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
        map.add("jobGroup", xxlJobInfoVO.getJobGroup());
        map.add("jobDesc", xxlJobInfoVO.getJobDesc());
        map.add("author", xxlJobInfoVO.getAuthor());
        map.add("alarmEmail", "");
        map.add("scheduleType", xxlJobInfoVO.getScheduleType());
        map.add("scheduleConf", cron);
        map.add("cronGen_display", cron);
        map.add("schedule_conf_CRON", cron);
        map.add("schedule_conf_FIX_RATE", "");
        map.add("schedule_conf_FIX_DELAY", "");
        map.add("glueType", xxlJobInfoVO.getGlueType());
        map.add("executorHandler", xxlJobInfoVO.getExecutorHandler());
        map.add("executorParam", orderId);
        map.add("executorRouteStrategy", xxlJobInfoVO.getExecutorRouteStrategy());
        map.add("childJobId", "");
        map.add("misfireStrategy", xxlJobInfoVO.getMisfireStrategy());
        map.add("executorBlockStrategy", xxlJobInfoVO.getExecutorBlockStrategy());
        map.add("executorTimeout", xxlJobInfoVO.getExecutorTimeout());
        map.add("executorFailRetryCount", xxlJobInfoVO.getExecutorFailRetryCount());
        map.add("glueRemark", xxlJobInfoVO.getGlueRemark());
        map.add("glueSource", "");
        map.add("triggerStatus", xxlJobInfoVO.getTriggerStatus());
        HttpEntity<MultiValueMap<String, String>> requestb = new HttpEntity<MultiValueMap<String, String>>(map, headers);
        ResponseEntity<String> response = restTemplate.postForEntity(xxlJobAdminAddr + "/jobinfo/add", requestb, String.class);
        String regionString = response.getBody();//获取请求体
        JSONObject jsonObject = JSONObject.parseObject(regionString,JSONObject.class);//将请求体转化为json格式
        String code = jsonObject.getString("code");
        String jobId = jsonObject.getString("content");
        if (!("200".equals(code))) {
            throw new IllegalArgumentException("xxl-job定时任务创建失败");
        }
        return jobId;
    }
}

DateUtils

java 复制代码
public class DateUtils {


    public static String getLocalDateTimeToCron(long minutes){

        LocalDateTime localDateTime = LocalDateTime.now();

        LocalDateTime  plusMinLocalDateTime = localDateTime.plusMinutes(minutes);

        String cornExpress = plusMinLocalDateTime.format(DateTimeFormatter.ofPattern("ss mm HH dd MM ? yyyy"));

        return cornExpress;
    }

    public static String getDateToCron(Long time){

        // 示例
        /*
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.MINUTE, 30);
        SimpleDateFormat sdf = new SimpleDateFormat("ss mm HH dd MM ? yyyy");
        String cronExpression = sdf.format(calendar.getTime());
        System.out.println("Corn表达式:" + cronExpression);
        */

        SimpleDateFormat sdf = new SimpleDateFormat("ss mm HH dd MM ? yyyy");
        String cronExpression = sdf.format(time);
        return cronExpression;
    }


}

订单取消逻辑

java 复制代码
@Slf4j
@Component
public class OrderTimeOutJob {


    @Resource
    private IOrderInfoService orderInfoService;


    @XxlJob("cancelPay")
    public void job() {
        log.info(">>>>>>>>进入xxl-job定时任务执行方法");

        String orderNumber = XxlJobHelper.getJobParam();

        orderInfoService.update(
                Wrappers.<OrderInfo>lambdaUpdate()
                        .eq(OrderInfo::getOrderNumber, orderNumber)
                        .set(OrderInfo::getPayStatus,5)

        );

    }

}

定时任务创建逻辑

java 复制代码
@RestController
@RequestMapping("/orderInfo")
@Slf4j
public class OrderInfoController {

    @Resource
    private IOrderInfoService orderInfoService;
    @Resource
    private CancelPayUtil cancelPayUtil;

    @Resource
    private IOrderJobService orderJobService;

    @PostMapping("/saveOrderInfo")
    @Transactional(rollbackFor = Exception.class)
    public Boolean saveOrderInfo(String orderNumber) {

        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setOrderNumber(orderNumber);

        boolean saveResultBoolean = orderInfoService.save(orderInfo);

        String localDateTimeToCron = DateUtils.getLocalDateTimeToCron(2);

        String jobId = cancelPayUtil.uploadCancelJob(localDateTimeToCron, orderNumber);

        Boolean jobIsExist = jobId.isEmpty() || jobId.equals("") ? false : true;

        if (jobIsExist){

            OrderJob orderJob = new OrderJob();
            orderJob.setOrderNumber(orderNumber);
            orderJob.setJobId(jobId);
            orderJobService.save(orderJob);
        }

        log.info(String.format("订单号: %s,订单取消时间: %s",orderNumber,localDateTimeToCron));

        return saveResultBoolean && jobIsExist;
    }



}

定时任务取消逻辑

java 复制代码
@RestController
@RequestMapping("/payInfo")
@Slf4j
public class PayController {


    @Resource
    private CancelPayUtil cancelPayUtil;
    @Resource
    private IOrderJobService orderJobService;

    @RequestMapping("/payInfo")
    public Boolean payInfo(String orderNumber) {


        //业务逻辑...

        //支付成功,取消定时任务
        LambdaQueryWrapper<OrderJob> jobLambdaQueryWrapper = new LambdaQueryWrapper<OrderJob>().eq(OrderJob::getOrderNumber, orderNumber);
        OrderJob orderJob = orderJobService.getOne(jobLambdaQueryWrapper);
        return cancelPayUtil.removeCancelJob(orderJob.getJobId());

    }


}
相关推荐
virus59451 小时前
悟空CRM mybatis-3.5.3-mapper.dtd错误解决方案
java·开发语言·mybatis
没差c2 小时前
springboot集成flyway
java·spring boot·后端
时艰.2 小时前
Java 并发编程之 CAS 与 Atomic 原子操作类
java·开发语言
编程彩机3 小时前
互联网大厂Java面试:从Java SE到大数据场景的技术深度解析
java·大数据·spring boot·面试·spark·java se·互联网大厂
笨蛋不要掉眼泪3 小时前
Spring Boot集成LangChain4j:与大模型对话的极速入门
java·人工智能·后端·spring·langchain
Yvonne爱编码3 小时前
JAVA数据结构 DAY3-List接口
java·开发语言·windows·python
像少年啦飞驰点、4 小时前
零基础入门 Spring Boot:从“Hello World”到可上线微服务的完整学习指南
java·spring boot·微服务·编程入门·后端开发
眼眸流转4 小时前
Java代码变更影响分析(一)
java·开发语言
Yvonne爱编码5 小时前
JAVA数据结构 DAY4-ArrayList
java·开发语言·数据结构
阿猿收手吧!5 小时前
【C++】C++原子操作:compare_exchange_weak详解
java·jvm·c++