From 934470958b8ab925645e33490c1763f26bbc9a3a Mon Sep 17 00:00:00 2001 From: jkcdev Date: Tue, 6 May 2025 09:06:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=94=AF=E4=BB=98=E3=80=81?= =?UTF-8?q?=E9=80=80=E6=AC=BE=E9=80=9A=E7=9F=A5=E5=9B=9E=E8=B0=83=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E6=8E=A7=E5=88=B6=E5=99=A8=EF=BC=8C=E5=AE=9A=E6=97=B6?= =?UTF-8?q?=E4=BB=BB=E5=8A=A1=E8=BF=98=E7=94=A8=E5=A4=9A=E7=BA=BF=E7=A8=8B?= =?UTF-8?q?ThreadPoolTaskScheduler=E6=9B=BF=E6=8D=A2=E5=8E=9F=E6=9C=89@Sch?= =?UTF-8?q?edule=E6=B3=A8=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cdzy/payment/EbikePaymentApplication.java | 2 - .../payment/config/ScheduledTaskConfig.java | 48 ++++++++++++ .../com/cdzy/payment/config/WxPayConfig.java | 2 - .../EbikeWxPayNotifyController.java | 75 +++++++++++++++++++ .../controller/EbikeWxPaymentController.java | 54 ------------- .../payment/task/ScheduledTaskManager.java | 69 +++++++++++++++++ .../java/com/cdzy/payment/task/WsPayTask.java | 17 ++--- .../src/main/resources/application-dev.yml | 5 ++ 8 files changed, 203 insertions(+), 69 deletions(-) create mode 100644 ebike-payment/src/main/java/com/cdzy/payment/config/ScheduledTaskConfig.java create mode 100644 ebike-payment/src/main/java/com/cdzy/payment/controller/EbikeWxPayNotifyController.java create mode 100644 ebike-payment/src/main/java/com/cdzy/payment/task/ScheduledTaskManager.java diff --git a/ebike-payment/src/main/java/com/cdzy/payment/EbikePaymentApplication.java b/ebike-payment/src/main/java/com/cdzy/payment/EbikePaymentApplication.java index feceec6a..f4aaa2e2 100644 --- a/ebike-payment/src/main/java/com/cdzy/payment/EbikePaymentApplication.java +++ b/ebike-payment/src/main/java/com/cdzy/payment/EbikePaymentApplication.java @@ -14,8 +14,6 @@ import org.springframework.scheduling.annotation.EnableScheduling; */ @SpringBootApplication @MapperScan("com.cdzy.payment.mapper") -//引入Spring Task -@EnableScheduling public class EbikePaymentApplication { public static void main(String[] args) { SpringApplication.run(EbikePaymentApplication.class, args); diff --git a/ebike-payment/src/main/java/com/cdzy/payment/config/ScheduledTaskConfig.java b/ebike-payment/src/main/java/com/cdzy/payment/config/ScheduledTaskConfig.java new file mode 100644 index 00000000..59eed4d1 --- /dev/null +++ b/ebike-payment/src/main/java/com/cdzy/payment/config/ScheduledTaskConfig.java @@ -0,0 +1,48 @@ +package com.cdzy.payment.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; + +/** + * 作业调度配置 + * + * @author dingchao + * @date 2025/5/2 + * @modified by: + */ +@Data +@Configuration +@ConfigurationProperties(prefix = "task-scheduler-pool") +public class ScheduledTaskConfig { + /** + * 线程池大小 + */ + private int poolSize; + /** + * 线程名称前缀 + */ + private String threadNamePrefix; + /** + * 等待任务在关闭时完成 + */ + private boolean waitForTasksToCompleteOnShutdown; + /** + * 等待终止的秒数 + */ + private int awaitTerminationSeconds; + + + @Bean + public ThreadPoolTaskScheduler threadPoolTaskScheduler() { + ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler(); + taskScheduler.setPoolSize(poolSize); + taskScheduler.setThreadNamePrefix(threadNamePrefix); + taskScheduler.setWaitForTasksToCompleteOnShutdown(waitForTasksToCompleteOnShutdown); + taskScheduler.setAwaitTerminationSeconds(awaitTerminationSeconds); + taskScheduler.initialize(); + return taskScheduler; + } +} diff --git a/ebike-payment/src/main/java/com/cdzy/payment/config/WxPayConfig.java b/ebike-payment/src/main/java/com/cdzy/payment/config/WxPayConfig.java index e6d0ea68..c071b9c4 100644 --- a/ebike-payment/src/main/java/com/cdzy/payment/config/WxPayConfig.java +++ b/ebike-payment/src/main/java/com/cdzy/payment/config/WxPayConfig.java @@ -7,7 +7,6 @@ import com.wechat.pay.java.core.util.PemUtil; import com.wechat.pay.java.service.payments.jsapi.JsapiService; import com.wechat.pay.java.service.refund.RefundService; import lombok.Data; -import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -21,7 +20,6 @@ import java.security.PrivateKey; * @date 2025/4/24 * @modified by: */ -@Slf4j @Data @Configuration @ConfigurationProperties(prefix = "payment.wx-pay") diff --git a/ebike-payment/src/main/java/com/cdzy/payment/controller/EbikeWxPayNotifyController.java b/ebike-payment/src/main/java/com/cdzy/payment/controller/EbikeWxPayNotifyController.java new file mode 100644 index 00000000..86117fae --- /dev/null +++ b/ebike-payment/src/main/java/com/cdzy/payment/controller/EbikeWxPayNotifyController.java @@ -0,0 +1,75 @@ +package com.cdzy.payment.controller; + +import com.alibaba.fastjson2.JSONObject; +import com.cdzy.payment.model.dto.HandleNotifyResult; +import com.cdzy.payment.service.WxPayService; +import jakarta.annotation.Resource; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * 微信支付通知回调接口 + *
通知接口不能鉴权 + * + * @author dingchao + * @date 2025/5/6 + * @modified by: + */ +@RestController +@RequestMapping("/wxPayment/notify") +public class EbikeWxPayNotifyController { + + @Resource + private WxPayService wxPayService; + + /** + * 支付回调通知 + * + * @param request 支付回调请求 + * @param response 支付回调响应 + * @return 支付回调响应 + */ + @PostMapping("/pay") + public String payNotify(HttpServletRequest request, HttpServletResponse response) { + HandleNotifyResult r = wxPayService.handlePayNotify(request); + if(!r.isSuccess()) { + response.setStatus(500); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("code", "SYSTEM_ERROR"); + jsonObject.put("message", r.getMessage()); + return jsonObject.toJSONString(); + } + response.setStatus(200); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("code", "SUCCESS"); + jsonObject.put("message", "OK"); + return jsonObject.toJSONString(); + } + + /** + * 退款回调通知 + * + * @param request 退款回调请求 + * @param response 退款回调响应 + * @return 退款回调响应 + */ + @PostMapping("/refund") + public String refundNotify(HttpServletRequest request, HttpServletResponse response) { + HandleNotifyResult r = wxPayService.handleRefundNotify(request); + if(!r.isSuccess()) { + response.setStatus(500); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("code", "SYSTEM_ERROR"); + jsonObject.put("message", r.getMessage()); + return jsonObject.toJSONString(); + } + response.setStatus(200); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("code", "SUCCESS"); + jsonObject.put("message", "OK"); + return jsonObject.toJSONString(); + } +} diff --git a/ebike-payment/src/main/java/com/cdzy/payment/controller/EbikeWxPaymentController.java b/ebike-payment/src/main/java/com/cdzy/payment/controller/EbikeWxPaymentController.java index cd9dd9ed..39b2f200 100644 --- a/ebike-payment/src/main/java/com/cdzy/payment/controller/EbikeWxPaymentController.java +++ b/ebike-payment/src/main/java/com/cdzy/payment/controller/EbikeWxPaymentController.java @@ -17,9 +17,6 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; - /** * 用户订单微信支付 控制层。 * @@ -106,55 +103,4 @@ public class EbikeWxPaymentController { return r == null?JsonResult.failed(String.format("退款单号{%s}查询退款失败", outRefundNo)):JsonResult.success(r); } - - - // ================通知回调接口=============== - // TODO 通知接口不能鉴权 - /** - * 支付回调通知 - * - * @param request 支付回调请求 - * @param response 支付回调响应 - * @return 支付回调响应 - */ - @PostMapping("/pay/notify") - public String payNotify(HttpServletRequest request, HttpServletResponse response) { - HandleNotifyResult r = wxPayService.handlePayNotify(request); - if(!r.isSuccess()) { - response.setStatus(500); - JSONObject jsonObject = new JSONObject(); - jsonObject.put("code", "SYSTEM_ERROR"); - jsonObject.put("message", r.getMessage()); - return jsonObject.toJSONString(); - } - response.setStatus(200); - JSONObject jsonObject = new JSONObject(); - jsonObject.put("code", "SUCCESS"); - jsonObject.put("message", "OK"); - return jsonObject.toJSONString(); - } - - /** - * 退款回调通知 - * - * @param request 退款回调请求 - * @param response 退款回调响应 - * @return 退款回调响应 - */ - @PostMapping("/refund/notify") - public String refundNotify(HttpServletRequest request, HttpServletResponse response) { - HandleNotifyResult r = wxPayService.handleRefundNotify(request); - if(!r.isSuccess()) { - response.setStatus(500); - JSONObject jsonObject = new JSONObject(); - jsonObject.put("code", "SYSTEM_ERROR"); - jsonObject.put("message", r.getMessage()); - return jsonObject.toJSONString(); - } - response.setStatus(200); - JSONObject jsonObject = new JSONObject(); - jsonObject.put("code", "SUCCESS"); - jsonObject.put("message", "OK"); - return jsonObject.toJSONString(); - } } diff --git a/ebike-payment/src/main/java/com/cdzy/payment/task/ScheduledTaskManager.java b/ebike-payment/src/main/java/com/cdzy/payment/task/ScheduledTaskManager.java new file mode 100644 index 00000000..3fa11b05 --- /dev/null +++ b/ebike-payment/src/main/java/com/cdzy/payment/task/ScheduledTaskManager.java @@ -0,0 +1,69 @@ +package com.cdzy.payment.task; + +import jakarta.annotation.PostConstruct; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; +import org.springframework.scheduling.support.CronTrigger; +import org.springframework.stereotype.Component; + +/** + * 定时作业调度器。 + * + * @author dingchao + * @date 2025/5/2 + * @modified by: + */ +@Slf4j +@Component +public class ScheduledTaskManager { + // 每隔30秒执行1次 + private final static String CRON_EXPRESSION = "0/30 * * * *?"; + + // @Scheduled任务线程默认串行执行,需要考虑并发问题 + @Resource + private ThreadPoolTaskScheduler threadPoolTaskScheduler; + @Resource + private WsPayTask wxPayTask; + + @PostConstruct + public void init() { + // 启动定时任务 + // 1. 每隔30秒执行1次,查询创建未超过5分钟,并且未支付的订单 + threadPoolTaskScheduler.schedule(new Runnable() { + @Override + public void run() { + try { + wxPayTask.checkOrderStatus(); + }catch (Exception e) { + log.error("checkOrderStatus 执行异常", e); + } + } + }, new CronTrigger(CRON_EXPRESSION)); + + // 2. 每隔30秒执行1次,查询创建超过5分钟,并且未支付的订单 + threadPoolTaskScheduler.schedule(new Runnable() { + @Override + public void run() { + try { + wxPayTask.closeOrder(); + } catch (Exception e) { + log.error("closeOrder 执行异常", e); + } + } + }, new CronTrigger(CRON_EXPRESSION)); + + // 3. 每隔30秒执行1次,查询创建未超过5分钟,并且未成功的退款单 + threadPoolTaskScheduler.schedule(new Runnable() { + @Override + public void run() { + try { + wxPayTask.checkRefundStatus(); + } catch (Exception e) { + log.error("checkRefundStatus 执行异常", e); + } + } + }, new CronTrigger(CRON_EXPRESSION)); + } + +} diff --git a/ebike-payment/src/main/java/com/cdzy/payment/task/WsPayTask.java b/ebike-payment/src/main/java/com/cdzy/payment/task/WsPayTask.java index 05d3391c..3a0e0dc2 100644 --- a/ebike-payment/src/main/java/com/cdzy/payment/task/WsPayTask.java +++ b/ebike-payment/src/main/java/com/cdzy/payment/task/WsPayTask.java @@ -8,11 +8,9 @@ import com.cdzy.payment.service.EbikeRefundService; import com.cdzy.payment.service.WxPayService; import com.wechat.pay.java.service.payments.model.Transaction; import com.wechat.pay.java.service.refund.model.Refund; -import com.wechat.pay.java.service.refund.model.Status; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; import java.util.List; @@ -24,7 +22,7 @@ import java.util.List; * @modified by: */ @Slf4j -@Component +@Service public class WsPayTask { @Resource @@ -36,11 +34,10 @@ public class WsPayTask { @Resource private EbikeRefundService ebikeRefundService; - // TODO @Scheduled任务线程默认串行执行,需要考虑并发问题 + /** - * 每隔30秒执行1次,查询创建未超过5分钟,并且未支付的订单 + * 查询创建未超过5分钟,并且未支付的订单 */ - @Scheduled(cron = "0/30 * * * * ?") public void checkOrderStatus() throws Exception { log.info("checkOrderStatus 执行......"); // 1. 查询未支付的订单 @@ -57,9 +54,8 @@ public class WsPayTask { } /** - * 每隔30秒执行1次,查询创建超过5分钟,并且未支付的订单 + * 查询创建超过5分钟,并且未支付的订单 */ - @Scheduled(cron = "0/30 * * * * ?") public void closeOrder() throws Exception { log.info("closeOrder 执行......"); // 1. 查询未支付的超时订单 @@ -80,9 +76,8 @@ public class WsPayTask { } /** - * 每隔30秒执行1次,查询创建未超过5分钟,并且未成功的退款单 + * 查询创建未超过5分钟,并且未成功的退款单 */ - @Scheduled(cron = "0/30 * * * * ?") public void checkRefundStatus() throws Exception { log.info("checkRefundStatus 执行......"); diff --git a/ebike-payment/src/main/resources/application-dev.yml b/ebike-payment/src/main/resources/application-dev.yml index 5d484368..d50448d7 100644 --- a/ebike-payment/src/main/resources/application-dev.yml +++ b/ebike-payment/src/main/resources/application-dev.yml @@ -41,3 +41,8 @@ payment: pay-notify_url: http://192.168.2.156:10017/wxPayment/pay-notify refund-notify_url: http://192.168.2.156:10017/wxPayment/refund-notify expire-minutes: 5 +task-scheduler-pool: + poolSize: 100 + threadNamePrefix: task-scheduled- + waitForTasksToCompleteOnShutdown: true + awaitTerminationSeconds: 30 \ No newline at end of file