news 2026/5/29 5:55:45

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Xxl-Job实现订单30分钟未支付自动取消

数据库

配置文件

xxl:job:admin:addresses:http://localhost:8080/xxl-job-admin/accessToken:default_tokentimeout:30cookie:XXL_JOB_LOGIN_IDENTITY=executor:appname:springboot3address:ip:port:9989logPath:logretentiondays:10

配置xxlJob任务参数

importlombok.Data;importlombok.ToString;importorg.springframework.boot.context.properties.ConfigurationProperties;importorg.springframework.context.annotation.PropertySource;importorg.springframework.stereotype.Component;@Component@PropertySource("classpath:xxl-job-info.properties")@ConfigurationProperties(prefix="xxl-job-info")@Data@ToStringpublicclassXxlJobInfoVO{privateStringjobGroup;privateStringjobDesc;privateStringauthor;privateStringscheduleType;privateStringglueType;privateStringexecutorHandler;privateStringexecutorRouteStrategy;privateStringmisfireStrategy;privateStringexecutorBlockStrategy;privateStringexecutorTimeout;privateStringexecutorFailRetryCount;privateStringglueRemark;privateStringtriggerStatus;}

xxl-job-info.properties

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

CancelPayUtil

@Component//@RestControllerpublicclassCancelPayUtil{@Value("${xxl.job.cookie}")privateStringcookie;@Value("${xxl.job.admin.addresses}")privateStringxxlJobAdminAddr;@AutowiredprivateXxlJobInfoVOxxlJobInfoVO;//@GetMapping("/removeCancelJob")publicBooleanremoveCancelJob(StringjobId){RestTemplaterestTemplate=newRestTemplate();HttpHeadersheaders=newHttpHeaders();//设置为form方式headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);headers.add("Cookie",cookie);MultiValueMap<String,String>map=newLinkedMultiValueMap<String,String>();map.add("id",jobId);HttpEntity<MultiValueMap<String,String>>requestb=newHttpEntity<MultiValueMap<String,String>>(map,headers);ResponseEntity<String>response=restTemplate.postForEntity(xxlJobAdminAddr+"/jobinfo/remove",requestb,String.class);StringregionString=response.getBody();//获取请求体JSONObjectjsonObject=JSONObject.parseObject(regionString,JSONObject.class);//将请求体转化为json格式Stringcode=jsonObject.getString("code");if(!("200".equals(code))){thrownewIllegalArgumentException("xxl-job定时任务删除失败");}returntrue;}//@GetMapping("/uploadCancelJob")publicStringuploadCancelJob(Stringcron,StringorderId){RestTemplaterestTemplate=newRestTemplate();HttpHeadersheaders=newHttpHeaders();//设置为form方式headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);headers.add("Cookie",cookie);MultiValueMap<String,String>map=newLinkedMultiValueMap<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=newHttpEntity<MultiValueMap<String,String>>(map,headers);ResponseEntity<String>response=restTemplate.postForEntity(xxlJobAdminAddr+"/jobinfo/add",requestb,String.class);StringregionString=response.getBody();//获取请求体JSONObjectjsonObject=JSONObject.parseObject(regionString,JSONObject.class);//将请求体转化为json格式Stringcode=jsonObject.getString("code");StringjobId=jsonObject.getString("content");if(!("200".equals(code))){thrownewIllegalArgumentException("xxl-job定时任务创建失败");}returnjobId;}}

DateUtils

publicclassDateUtils{publicstaticStringgetLocalDateTimeToCron(longminutes){LocalDateTimelocalDateTime=LocalDateTime.now();LocalDateTimeplusMinLocalDateTime=localDateTime.plusMinutes(minutes);StringcornExpress=plusMinLocalDateTime.format(DateTimeFormatter.ofPattern("ss mm HH dd MM ? yyyy"));returncornExpress;}publicstaticStringgetDateToCron(Longtime){// 示例/* 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); */SimpleDateFormatsdf=newSimpleDateFormat("ss mm HH dd MM ? yyyy");StringcronExpression=sdf.format(time);returncronExpression;}}

订单取消逻辑

@Slf4j@ComponentpublicclassOrderTimeOutJob{@ResourceprivateIOrderInfoServiceorderInfoService;@XxlJob("cancelPay")publicvoidjob(){log.info(">>>>>>>>进入xxl-job定时任务执行方法");StringorderNumber=XxlJobHelper.getJobParam();orderInfoService.update(Wrappers.<OrderInfo>lambdaUpdate().eq(OrderInfo::getOrderNumber,orderNumber).set(OrderInfo::getPayStatus,5));}}

定时任务创建逻辑

@RestController@RequestMapping("/orderInfo")@Slf4jpublicclassOrderInfoController{@ResourceprivateIOrderInfoServiceorderInfoService;@ResourceprivateCancelPayUtilcancelPayUtil;@ResourceprivateIOrderJobServiceorderJobService;@PostMapping("/saveOrderInfo")@Transactional(rollbackFor=Exception.class)publicBooleansaveOrderInfo(StringorderNumber){OrderInfoorderInfo=newOrderInfo();orderInfo.setOrderNumber(orderNumber);booleansaveResultBoolean=orderInfoService.save(orderInfo);StringlocalDateTimeToCron=DateUtils.getLocalDateTimeToCron(2);StringjobId=cancelPayUtil.uploadCancelJob(localDateTimeToCron,orderNumber);BooleanjobIsExist=jobId.isEmpty()||jobId.equals("")?false:true;if(jobIsExist){OrderJoborderJob=newOrderJob();orderJob.setOrderNumber(orderNumber);orderJob.setJobId(jobId);orderJobService.save(orderJob);}log.info(String.format("订单号: %s,订单取消时间: %s",orderNumber,localDateTimeToCron));returnsaveResultBoolean&&jobIsExist;}}

定时任务取消逻辑

@RestController@RequestMapping("/payInfo")@Slf4jpublicclassPayController{@ResourceprivateCancelPayUtilcancelPayUtil;@ResourceprivateIOrderJobServiceorderJobService;@RequestMapping("/payInfo")publicBooleanpayInfo(StringorderNumber){//业务逻辑...//支付成功,取消定时任务LambdaQueryWrapper<OrderJob>jobLambdaQueryWrapper=newLambdaQueryWrapper<OrderJob>().eq(OrderJob::getOrderNumber,orderNumber);OrderJoborderJob=orderJobService.getOne(jobLambdaQueryWrapper);returncancelPayUtil.removeCancelJob(orderJob.getJobId());}}
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/28 23:39:35

告别无脑 <div>:HTML 语义化标签入门

生活中的例子 01让屏幕阅读器&#xff08;盲人使用的工具&#xff09;能准确读出网页结构。生活中的例子 02让搜索引擎&#xff08;如 Google, 百度&#xff09;更好地理解你的网页内容&#xff0c;提升排名。生活中的例子 03让其他接手你代码的程序员一眼看懂网页布局&#xf…

作者头像 李华
网站建设 2026/5/28 13:35:03

go如何实现aop

Go 语言本身没有“类加载器”和“动态字节码增强”这一套基础设施&#xff0c;所以官方层面并不支持像 Java/Spring-AOP 那样的“全自动织入”。在 Go 里做 AOP&#xff0c;本质上是“手动织入”——把横切逻辑&#xff08;日志、权限、指标、重试等&#xff09;通过高阶函数、…

作者头像 李华
网站建设 2026/5/28 20:30:33

降低知网AIGC疑似度不用求人!1个降率网站+3条改写指令

2025年起&#xff0c;高校已明确要求毕业论文要检测AIGC率&#xff0c;AI率高于30%或40%就不能参加答辩&#xff0c;而部分学校、硕士论文更加严格&#xff0c;要求在20%以内。 这其中&#xff0c;大多数高校使用的AIGC检测系统是知网、万方、维普等主流查重系统&#xff0c;这…

作者头像 李华
网站建设 2026/5/28 13:07:38

视频直播点播平台EasyDSS视频直播功能特点与应用场景解析

在数字化时代&#xff0c;视频直播已成为企业通信、在线教育、娱乐互动等领域不可或缺的一部分。EasyDSS作为一款高效的视频直播点播平台&#xff0c;凭借其稳定的直播功能和灵活的部署方式&#xff0c;受到了开发者和企业的广泛关注。本文将深入探讨EasyDSS视频直播功能的技术…

作者头像 李华