Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
2e6608483b
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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")
|
||||
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
* 微信支付通知回调接口
|
||||
* <br>通知接口不能鉴权
|
||||
*
|
||||
* @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();
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@ -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 执行......");
|
||||
|
||||
|
||||
@ -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
|
||||
Loading…
x
Reference in New Issue
Block a user