mirror of
https://gitee.com/dromara/dax-pay.git
synced 2025-09-07 21:17:42 +00:00
perf 消息通知功能调试和流水记录
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
package cn.bootx.platform.daxpay.service.code;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 消息通知发送类型
|
||||
* @author xxm
|
||||
* @since 2024/2/25
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum ClientNoticeSendTypeEnum {
|
||||
/** 自动发送 */
|
||||
AUTO("auto", "自动发送"),
|
||||
/** 手动发送 */
|
||||
MANUAL("manual", "手动发送");
|
||||
|
||||
private final String type;
|
||||
private final String name;
|
||||
|
||||
}
|
@@ -1,10 +1,14 @@
|
||||
package cn.bootx.platform.daxpay.service.common.context;
|
||||
|
||||
import cn.bootx.platform.daxpay.code.PayWayEnum;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderExtra;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 异步支付信息
|
||||
@@ -13,7 +17,7 @@ import java.time.LocalDateTime;
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class AsyncPayLocal {
|
||||
public class PayLocal {
|
||||
|
||||
/**
|
||||
* 异步支付方式
|
||||
@@ -36,4 +40,13 @@ public class AsyncPayLocal {
|
||||
/** 订单失效时间, */
|
||||
private LocalDateTime expiredTime;
|
||||
|
||||
/** 支付订单 */
|
||||
private PayOrder payOrder;
|
||||
|
||||
/** 支付订单扩展 */
|
||||
private PayOrderExtra payOrderExtra;
|
||||
|
||||
/** 通道支付订单 */
|
||||
private List<PayChannelOrder> payChannelOrders;
|
||||
|
||||
}
|
@@ -18,8 +18,8 @@ public class PaymentContext {
|
||||
/** 平台全局配置 */
|
||||
private final PlatformLocal platformInfo = new PlatformLocal();
|
||||
|
||||
/** 异步支付相关信息 */
|
||||
private final AsyncPayLocal asyncPayInfo = new AsyncPayLocal();
|
||||
/** 支付相关信息 */
|
||||
private final PayLocal payInfo = new PayLocal();
|
||||
|
||||
/** 退款相关信息 */
|
||||
private final RefundLocal refundInfo = new RefundLocal();
|
||||
|
@@ -6,7 +6,7 @@ import cn.bootx.platform.daxpay.param.channel.AliPayParam;
|
||||
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
|
||||
import cn.bootx.platform.daxpay.service.code.AliPayCode;
|
||||
import cn.bootx.platform.daxpay.service.code.AliPayWay;
|
||||
import cn.bootx.platform.daxpay.service.common.context.AsyncPayLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.context.PayLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.context.NoticeLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliPayConfig;
|
||||
@@ -66,7 +66,7 @@ public class AliPayService {
|
||||
Integer amount = payChannelParam.getAmount();
|
||||
String payBody = null;
|
||||
// 异步线程存储
|
||||
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();
|
||||
PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo();
|
||||
// wap支付
|
||||
if (Objects.equals(payChannelParam.getWay(), PayWayEnum.WAP.getCode())) {
|
||||
payBody = this.wapPay(amount, payOrder, alipayConfig);
|
||||
@@ -207,7 +207,7 @@ public class AliPayService {
|
||||
* 付款码支付
|
||||
*/
|
||||
public void barCode(int amount, PayOrder payOrder, AliPayParam aliPayParam, AliPayConfig alipayConfig) {
|
||||
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();
|
||||
PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo();
|
||||
|
||||
AlipayTradePayModel model = new AlipayTradePayModel();
|
||||
model.setSubject(payOrder.getTitle());
|
||||
|
@@ -10,7 +10,7 @@ import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
|
||||
import cn.bootx.platform.daxpay.result.pay.SyncResult;
|
||||
import cn.bootx.platform.daxpay.service.code.WeChatPayCode;
|
||||
import cn.bootx.platform.daxpay.service.code.WeChatPayWay;
|
||||
import cn.bootx.platform.daxpay.service.common.context.AsyncPayLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.context.PayLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayConfig;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
|
||||
@@ -79,7 +79,7 @@ public class WeChatPayService {
|
||||
|
||||
Integer amount = payChannelParam.getAmount();
|
||||
String totalFee = String.valueOf(amount);
|
||||
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();;
|
||||
PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo();;
|
||||
String payBody = null;
|
||||
PayWayEnum payWayEnum = PayWayEnum.findByCode(payChannelParam.getWay());
|
||||
|
||||
@@ -173,7 +173,7 @@ public class WeChatPayService {
|
||||
* 付款码支付
|
||||
*/
|
||||
private void barCode(String amount, PayOrder payment, String authCode, WeChatPayConfig weChatPayConfig) {
|
||||
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();
|
||||
PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo();
|
||||
|
||||
Map<String, String> params = MicroPayModel.builder()
|
||||
.appid(weChatPayConfig.getWxAppId())
|
||||
|
@@ -5,7 +5,7 @@ import cn.bootx.platform.daxpay.code.PayStatusEnum;
|
||||
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
|
||||
import cn.bootx.platform.daxpay.param.pay.PayParam;
|
||||
import cn.bootx.platform.daxpay.result.pay.PayResult;
|
||||
import cn.bootx.platform.daxpay.service.common.context.AsyncPayLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.context.PayLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.context.NoticeLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.context.PlatformLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
@@ -37,7 +37,7 @@ public class PayBuilder {
|
||||
public PayOrder buildPayOrder(PayParam payParam) {
|
||||
// 订单超时时间
|
||||
LocalDateTime expiredTime = PaymentContextLocal.get()
|
||||
.getAsyncPayInfo()
|
||||
.getPayInfo()
|
||||
.getExpiredTime();
|
||||
// 计算总价
|
||||
int sumAmount = payParam.getPayChannels().stream()
|
||||
@@ -118,7 +118,7 @@ public class PayBuilder {
|
||||
paymentResult.setStatus(payOrder.getStatus());
|
||||
|
||||
// 设置异步支付参数
|
||||
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();;
|
||||
PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo();;
|
||||
if (StrUtil.isNotBlank(asyncPayInfo.getPayBody())) {
|
||||
paymentResult.setPayBody(asyncPayInfo.getPayBody());
|
||||
}
|
||||
|
@@ -5,7 +5,7 @@ import cn.bootx.platform.common.core.util.ResultConvertUtil;
|
||||
import cn.bootx.platform.daxpay.code.RefundStatusEnum;
|
||||
import cn.bootx.platform.daxpay.code.PayStatusEnum;
|
||||
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
|
||||
import cn.bootx.platform.daxpay.service.common.context.AsyncPayLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.context.PayLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayChannelOrderManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder;
|
||||
@@ -54,7 +54,7 @@ public class PayChannelOrderService {
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void switchAsyncPayChannel(PayOrder payOrder, PayChannelParam payChannelParam){
|
||||
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();
|
||||
PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo();
|
||||
// 是否支付完成
|
||||
PayStatusEnum payStatus = asyncPayInfo.isPayComplete() ? PayStatusEnum.SUCCESS : PayStatusEnum.PROGRESS;
|
||||
// 判断新发起的
|
||||
|
@@ -1,18 +0,0 @@
|
||||
package cn.bootx.platform.daxpay.service.core.payment.notice.dao;
|
||||
|
||||
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.notice.entity.ClientNoticeTask;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2024/2/20
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ClientNoticeTaskManager extends BaseManager<ClientNoticeTaskMapper, ClientNoticeTask> {
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
package cn.bootx.platform.daxpay.service.core.payment.notice.entity;
|
||||
|
||||
import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 消息通知任务记录表
|
||||
* @author xxm
|
||||
* @since 2024/2/20
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ClientNoticeRecord extends MpCreateEntity {
|
||||
}
|
@@ -3,8 +3,10 @@ package cn.bootx.platform.daxpay.service.core.payment.notice.service;
|
||||
import cn.bootx.platform.common.core.exception.RepetitiveOperationException;
|
||||
import cn.bootx.platform.common.core.util.CollUtil;
|
||||
import cn.bootx.platform.common.core.util.LocalDateTimeUtil;
|
||||
import cn.bootx.platform.common.jackson.util.JacksonUtil;
|
||||
import cn.bootx.platform.common.redis.RedisClient;
|
||||
import cn.bootx.platform.daxpay.code.PaySignTypeEnum;
|
||||
import cn.bootx.platform.daxpay.service.code.ClientNoticeSendTypeEnum;
|
||||
import cn.bootx.platform.daxpay.service.code.ClientNoticeTypeEnum;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayChannelOrderManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayOrderExtraManager;
|
||||
@@ -12,24 +14,23 @@ import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderExtra;
|
||||
import cn.bootx.platform.daxpay.service.core.order.refund.dao.RefundChannelOrderManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.refund.dao.RefundOrderExtraManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundChannelOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.refund.entity.RefundOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.notice.dao.ClientNoticeTaskManager;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.notice.entity.ClientNoticeTask;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.notice.result.PayChannelResult;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.notice.result.PayNoticeResult;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.notice.result.RefundChannelResult;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.notice.result.RefundNoticeResult;
|
||||
import cn.bootx.platform.daxpay.service.core.system.config.entity.PlatformConfig;
|
||||
import cn.bootx.platform.daxpay.service.core.system.config.service.PlatformConfigService;
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.dao.ClientNoticeTaskManager;
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.entity.ClientNoticeRecord;
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.entity.ClientNoticeTask;
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.service.ClientNoticeRecordService;
|
||||
import cn.bootx.platform.daxpay.util.PaySignUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.ContentType;
|
||||
import cn.hutool.http.HttpException;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.baomidou.lock.LockInfo;
|
||||
import com.baomidou.lock.LockTemplate;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -43,7 +44,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 消息通知任务服务
|
||||
* 总共会发起15次通知,通知频率为15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h
|
||||
* 如果失败总共会重新发起15次通知,通知频率为15s/15s/30s/3m/10m/20m/30m/30m/30m/60m/3h/3h/3h/6h/6h
|
||||
* @author xxm
|
||||
* @since 2024/2/20
|
||||
*/
|
||||
@@ -56,14 +57,14 @@ public class ClientNoticeService {
|
||||
|
||||
private final PayChannelOrderManager payChannelOrderManager;
|
||||
|
||||
private final RefundOrderExtraManager refundOrderExtraManager;
|
||||
|
||||
private final RefundChannelOrderManager refundChannelOrderManager;
|
||||
|
||||
private final PlatformConfigService configService;
|
||||
|
||||
private final ClientNoticeTaskManager taskManager;
|
||||
|
||||
private final ClientNoticeRecordService recordService;
|
||||
|
||||
private final RedisClient redisClient;
|
||||
|
||||
private final LockTemplate lockTemplate;
|
||||
@@ -129,12 +130,8 @@ public class ClientNoticeService {
|
||||
log.error("注册支付消息通知任务失败,数据错误,订单ID:{}",order.getId());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
try {
|
||||
// 同时触发一次通知, 如果成功发送, 任务结束
|
||||
this.sendData(task, LocalDateTime.now());
|
||||
} catch (HttpException e) {
|
||||
this.failHandler(task, LocalDateTime.now());
|
||||
}
|
||||
// 同时触发一次通知, 如果成功发送, 任务结束
|
||||
this.sendData(task, LocalDateTime.now());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,7 +167,8 @@ public class ClientNoticeService {
|
||||
}
|
||||
return new ClientNoticeTask()
|
||||
.setUrl(orderExtra.getNotifyUrl())
|
||||
.setContent(JSONUtil.toJsonStr(payNoticeResult))
|
||||
// 时间序列化进行了重写
|
||||
.setContent(JacksonUtil.toJson(payNoticeResult))
|
||||
.setType(ClientNoticeTypeEnum.PAY.getType())
|
||||
.setSendCount(0)
|
||||
.setOrderId(order.getId());
|
||||
@@ -209,14 +207,11 @@ public class ClientNoticeService {
|
||||
taskManager.save(task);
|
||||
} catch (Exception e) {
|
||||
log.error("注册退款消息通知任务失败,数据错误,订单ID:{}",order.getId());
|
||||
log.error("错误内容",e);
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
try {
|
||||
// 同时触发一次通知, 如果成功发送, 任务结束
|
||||
this.sendData(task, LocalDateTime.now());
|
||||
} catch (HttpException e) {
|
||||
this.failHandler(task, LocalDateTime.now());
|
||||
}
|
||||
// 同时触发一次通知, 如果成功发送, 任务结束
|
||||
this.sendData(task, LocalDateTime.now());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -252,7 +247,8 @@ public class ClientNoticeService {
|
||||
}
|
||||
return new ClientNoticeTask()
|
||||
.setUrl(orderExtra.getNotifyUrl())
|
||||
.setContent(JSONUtil.toJsonStr(payNoticeResult))
|
||||
// 时间序列化进行了重写
|
||||
.setContent(JacksonUtil.toJson(payNoticeResult))
|
||||
.setType(ClientNoticeTypeEnum.PAY.getType())
|
||||
.setSendCount(0)
|
||||
.setOrderId(order.getId());
|
||||
@@ -269,9 +265,9 @@ public class ClientNoticeService {
|
||||
// 发起一个异步任务,
|
||||
for (String taskId : taskIds) {
|
||||
this.run(Long.valueOf(taskId));
|
||||
// 删除Redis中任务
|
||||
redisClient.zremByMembers(KEY,taskId);
|
||||
}
|
||||
// 删除Redis中任务
|
||||
redisClient.zremRangeByScore(KEY, start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -285,16 +281,19 @@ public class ClientNoticeService {
|
||||
throw new RepetitiveOperationException("支付同步处理中,请勿重复操作");
|
||||
}
|
||||
// 查询任务, 进行发送
|
||||
ClientNoticeTask task = taskManager.findById(taskId).orElse(null);
|
||||
ClientNoticeTask task = null;
|
||||
try {
|
||||
task = taskManager.findById(taskId).orElse(null);
|
||||
// 不存在任务直接跳过
|
||||
if (Objects.isNull(task)) {
|
||||
return;
|
||||
}
|
||||
// 已经发送成功则不进行发送
|
||||
if (task.isSuccess()){
|
||||
return;
|
||||
}
|
||||
// 执行发送逻辑
|
||||
this.sendData(task, now);
|
||||
} catch (HttpException e) {
|
||||
//noinspection DataFlowIssue
|
||||
this.failHandler(task, now);
|
||||
} finally {
|
||||
lockTemplate.releaseLock(lock);
|
||||
}
|
||||
@@ -304,17 +303,37 @@ public class ClientNoticeService {
|
||||
* 发送通知数据, 如果失败, 注册下次重发的任务
|
||||
*/
|
||||
private void sendData(ClientNoticeTask task, LocalDateTime now){
|
||||
HttpResponse execute = HttpUtil.createPost(task.getUrl())
|
||||
.body(task.getContent(), ContentType.JSON.getValue())
|
||||
.timeout(5000)
|
||||
.execute();
|
||||
String body = execute.body();
|
||||
// 创建记录
|
||||
ClientNoticeRecord record = new ClientNoticeRecord()
|
||||
.setTaskId(task.getId())
|
||||
.setType(ClientNoticeSendTypeEnum.AUTO.getType())
|
||||
.setReqCount(task.getSendCount()+1);
|
||||
String body = null;
|
||||
try {
|
||||
HttpResponse execute = HttpUtil.createPost(task.getUrl())
|
||||
.body(task.getContent(), ContentType.JSON.getValue())
|
||||
.timeout(5000)
|
||||
.execute();
|
||||
body = execute.body();
|
||||
} catch (Exception e) {
|
||||
log.error("发送通知失败,数据错误,任务ID:{}",task.getOrderId());
|
||||
log.error("错误内容",e);
|
||||
record.setErrorMsg(e.getMessage());
|
||||
}
|
||||
// 如果响应值等于SUCCESS, 说明发送成功, 进行成功处理
|
||||
if (Objects.equals(body, "SUCCESS")){
|
||||
this.successHandler(task);
|
||||
record.setSuccess(true);
|
||||
} else {
|
||||
this.failHandler(task,now);
|
||||
// 如果响应地址不为空, 将错误响应写到记录中
|
||||
if (Objects.nonNull(body)){
|
||||
// 预防返回值过长, 只保留100位
|
||||
record.setErrorMsg(StrUtil.sub(body,0,100));
|
||||
}
|
||||
}
|
||||
// 保存请求记录
|
||||
recordService.save(record);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -331,8 +350,13 @@ public class ClientNoticeService {
|
||||
* 失败处理, 首先发送次数+1, 然后注册后推指定时间的重试任务
|
||||
*/
|
||||
private void failHandler(ClientNoticeTask task, LocalDateTime now){
|
||||
// 为空不进行处理
|
||||
if (Objects.isNull(task)){
|
||||
return;
|
||||
}
|
||||
|
||||
// 次数+1
|
||||
task.setSendCount(task.getSendCount() + 1);
|
||||
task.setSendCount(task.getSendCount() + 1).setLatestTime(now);
|
||||
// 判断发送次数是否未超过15次, 注册任务到redis中
|
||||
if (task.getSendCount() < 16){
|
||||
// 根据当前次数和时间计算出毫秒值, 然后写入到Redis中
|
||||
|
@@ -17,6 +17,7 @@ import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderExtra;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderQueryService;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderService;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.sync.service.PaySyncService;
|
||||
import cn.bootx.platform.daxpay.service.func.AbsPayStrategy;
|
||||
import cn.bootx.platform.daxpay.util.PayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -27,6 +28,7 @@ import java.time.LocalDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.bootx.platform.daxpay.code.PayStatusEnum.*;
|
||||
|
||||
@@ -71,7 +73,7 @@ public class PayAssistService {
|
||||
if (PayUtil.isNotSync(payParam.getPayChannels())){
|
||||
return;
|
||||
}
|
||||
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();
|
||||
PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo();
|
||||
PlatformLocal platform = PaymentContextLocal.get().getPlatformInfo();
|
||||
// 支付订单是非为空
|
||||
if (Objects.nonNull(order)){
|
||||
@@ -100,18 +102,18 @@ public class PayAssistService {
|
||||
// 首先读取请求参数
|
||||
noticeInfo.setNotifyUrl(payParam.getNotifyUrl());
|
||||
// 读取接口配置
|
||||
if (StrUtil.isNotBlank(noticeInfo.getNotifyUrl())){
|
||||
if (StrUtil.isBlank(noticeInfo.getNotifyUrl())){
|
||||
noticeInfo.setNotifyUrl(apiInfo.getNoticeUrl());
|
||||
}
|
||||
// 读取平台配置
|
||||
if (StrUtil.isNotBlank(noticeInfo.getNotifyUrl())){
|
||||
if (StrUtil.isBlank(noticeInfo.getNotifyUrl())){
|
||||
noticeInfo.setNotifyUrl(platform.getNotifyUrl());
|
||||
}
|
||||
}
|
||||
// 同步回调
|
||||
noticeInfo.setNotifyUrl(payParam.getReturnUrl());
|
||||
if (StrUtil.isNotBlank(noticeInfo.getNotifyUrl())){
|
||||
noticeInfo.setNotifyUrl(platform.getNotifyUrl());
|
||||
noticeInfo.setReturnUrl(payParam.getReturnUrl());
|
||||
if (StrUtil.isBlank(noticeInfo.getReturnUrl())){
|
||||
noticeInfo.setReturnUrl(platform.getNotifyUrl());
|
||||
}
|
||||
// 退出回调地址
|
||||
noticeInfo.setQuitUrl(payParam.getQuitUrl());
|
||||
@@ -141,16 +143,31 @@ public class PayAssistService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建支付订单/附加表/支付通道表并保存,返回支付订单
|
||||
* 创建支付订单并保存, 返回支付订单
|
||||
*/
|
||||
public PayOrder createPayOrder(PayParam payParam) {
|
||||
PayLocal payInfo = PaymentContextLocal.get().getPayInfo();
|
||||
// 构建支付订单并保存
|
||||
PayOrder payOrder = PayBuilder.buildPayOrder(payParam);
|
||||
payOrderService.save(payOrder);
|
||||
PayOrder order = PayBuilder.buildPayOrder(payParam);
|
||||
payOrderService.save(order);
|
||||
// 构建支付订单扩展表并保存
|
||||
PayOrderExtra payOrderExtra = PayBuilder.buildPayOrderExtra(payParam, payOrder.getId());
|
||||
PayOrderExtra payOrderExtra = PayBuilder.buildPayOrderExtra(payParam, order.getId());
|
||||
payOrderExtraManager.save(payOrderExtra);
|
||||
return payOrder;
|
||||
payInfo.setPayOrder(order).setPayOrderExtra(payOrderExtra);
|
||||
return order;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建并保存通道支付订单
|
||||
*/
|
||||
public void createPayChannelOrder(List<AbsPayStrategy> payStrategies) {
|
||||
PayLocal payInfo = PaymentContextLocal.get().getPayInfo();
|
||||
List<PayChannelOrder> channelOrders = payStrategies.stream()
|
||||
.map(AbsPayStrategy::getChannelOrder)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
payChannelOrderManager.saveAll(channelOrders);
|
||||
payInfo.setPayChannelOrders(channelOrders);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,8 +182,7 @@ public class PayAssistService {
|
||||
PayOrderExtra payOrderExtra = payOrderExtraManager.findById(paymentId)
|
||||
.orElseThrow(() -> new DataNotExistException("支付订单不存在"));
|
||||
|
||||
NoticeLocal noticeInfo = PaymentContextLocal.get()
|
||||
.getNoticeInfo();
|
||||
NoticeLocal noticeInfo = PaymentContextLocal.get().getNoticeInfo();
|
||||
String notifyUrl = noticeInfo.getNotifyUrl();
|
||||
String returnUrl = noticeInfo.getReturnUrl();
|
||||
|
||||
|
@@ -6,11 +6,10 @@ import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
|
||||
import cn.bootx.platform.daxpay.param.pay.PayParam;
|
||||
import cn.bootx.platform.daxpay.param.pay.SimplePayParam;
|
||||
import cn.bootx.platform.daxpay.result.pay.PayResult;
|
||||
import cn.bootx.platform.daxpay.service.common.context.AsyncPayLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.context.PayLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.builder.PayBuilder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.dao.PayChannelOrderManager;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayChannelOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrder;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.entity.PayOrderExtra;
|
||||
import cn.bootx.platform.daxpay.service.core.order.pay.service.PayOrderService;
|
||||
@@ -33,7 +32,6 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.bootx.platform.daxpay.code.PayStatusEnum.*;
|
||||
|
||||
@@ -144,31 +142,27 @@ public class PayService {
|
||||
private void firstPayHandler(PayParam payParam, PayOrder payOrder) {
|
||||
|
||||
// 1.获取支付方式,通过工厂生成对应的策略组
|
||||
List<AbsPayStrategy> payStrategyList = PayStrategyFactory.createAsyncLast(payParam.getPayChannels());
|
||||
if (CollectionUtil.isEmpty(payStrategyList)) {
|
||||
List<AbsPayStrategy> strategies = PayStrategyFactory.createAsyncLast(payParam.getPayChannels());
|
||||
if (CollectionUtil.isEmpty(strategies)) {
|
||||
throw new PayUnsupportedMethodException();
|
||||
}
|
||||
|
||||
// 2.初始化支付的参数
|
||||
for (AbsPayStrategy paymentStrategy : payStrategyList) {
|
||||
paymentStrategy.initPayParam(payOrder, payParam);
|
||||
for (AbsPayStrategy strategy : strategies) {
|
||||
strategy.initPayParam(payOrder, payParam);
|
||||
}
|
||||
|
||||
// 3.1 执行支付前处理动作
|
||||
payStrategyList.forEach(AbsPayStrategy::doBeforePayHandler);
|
||||
strategies.forEach(AbsPayStrategy::doBeforePayHandler);
|
||||
// 3.2 执行通道支付单的生成动作
|
||||
payStrategyList.forEach(AbsPayStrategy::generateChannelOrder);
|
||||
strategies.forEach(AbsPayStrategy::generateChannelOrder);
|
||||
|
||||
// 4.1 支付操作
|
||||
payStrategyList.forEach(AbsPayStrategy::doPayHandler);
|
||||
strategies.forEach(AbsPayStrategy::doPayHandler);
|
||||
// 4.2 支付调用成功操作, 进行扣款、创建记录类类似的操作
|
||||
payStrategyList.forEach(AbsPayStrategy::doSuccessHandler);
|
||||
// 4.3 获取通道支付订单进行保存, 异步支付通道的订单单独处理
|
||||
List<PayChannelOrder> channelOrders = payStrategyList.stream()
|
||||
.map(AbsPayStrategy::getChannelOrder)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
payChannelOrderManager.saveAll(channelOrders);
|
||||
strategies.forEach(AbsPayStrategy::doSuccessHandler);
|
||||
// 4.3 保存通道支付订单
|
||||
payAssistService.createPayChannelOrder(strategies);
|
||||
|
||||
// 5.1 如果没有异步支付, 直接进行订单完成处理
|
||||
if (PayUtil.isNotSync(payParam.getPayChannels())) {
|
||||
@@ -178,7 +172,7 @@ public class PayService {
|
||||
payOrderService.updateById(payOrder);
|
||||
}
|
||||
// 5.2 如果异步支付完成, 进行订单完成处理, 同时发送回调消息
|
||||
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();
|
||||
PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo();
|
||||
if (asyncPayInfo.isPayComplete()) {
|
||||
payOrder.setGatewayOrderNo(asyncPayInfo.getGatewayOrderNo())
|
||||
.setStatus(SUCCESS.getCode())
|
||||
@@ -188,9 +182,9 @@ public class PayService {
|
||||
|
||||
// 如果支付完成 发送通知
|
||||
if (Objects.equals(payOrder.getStatus(), SUCCESS.getCode())){
|
||||
clientNoticeService.registerPayNotice(payOrder, null, channelOrders);
|
||||
PayLocal payInfo = PaymentContextLocal.get().getPayInfo();
|
||||
clientNoticeService.registerPayNotice(payOrder, payInfo.getPayOrderExtra(), payInfo.getPayChannelOrders());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -222,7 +216,7 @@ public class PayService {
|
||||
payStrategyList.forEach(AbsPayStrategy::doSuccessHandler);
|
||||
|
||||
// 6.1 如果异步支付完成, 进行订单完成处理
|
||||
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();
|
||||
PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo();
|
||||
if (asyncPayInfo.isPayComplete()) {
|
||||
payOrder.setGatewayOrderNo(asyncPayInfo.getGatewayOrderNo())
|
||||
.setStatus(SUCCESS.getCode())
|
||||
|
@@ -5,7 +5,7 @@ import cn.bootx.platform.daxpay.exception.pay.PayAmountAbnormalException;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayFailureException;
|
||||
import cn.bootx.platform.daxpay.param.channel.AliPayParam;
|
||||
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
|
||||
import cn.bootx.platform.daxpay.service.common.context.AsyncPayLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.context.PayLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliPayConfig;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.alipay.service.AliPayConfigService;
|
||||
@@ -93,7 +93,7 @@ public class AliPayStrategy extends AbsPayStrategy {
|
||||
*/
|
||||
@Override
|
||||
public void doSuccessHandler() {
|
||||
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();
|
||||
PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo();
|
||||
channelOrderService.switchAsyncPayChannel(this.getOrder(), this.getPayChannelParam());
|
||||
// 支付完成, 保存记录
|
||||
if (asyncPayInfo.isPayComplete()) {
|
||||
|
@@ -3,7 +3,7 @@ package cn.bootx.platform.daxpay.service.core.payment.pay.strategy;
|
||||
import cn.bootx.platform.daxpay.code.PayChannelEnum;
|
||||
import cn.bootx.platform.daxpay.exception.pay.PayAmountAbnormalException;
|
||||
import cn.bootx.platform.daxpay.param.pay.PayChannelParam;
|
||||
import cn.bootx.platform.daxpay.service.common.context.AsyncPayLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.context.PayLocal;
|
||||
import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayConfig;
|
||||
import cn.bootx.platform.daxpay.service.core.channel.wechat.service.WeChatPayConfigService;
|
||||
@@ -92,7 +92,7 @@ public class WeChatPayStrategy extends AbsPayStrategy {
|
||||
public void doSuccessHandler() {
|
||||
channelOrderService.switchAsyncPayChannel(this.getOrder(), this.getPayChannelParam());
|
||||
this.getOrder().setAsyncChannel(this.getChannel().getCode());
|
||||
AsyncPayLocal asyncPayInfo = PaymentContextLocal.get().getAsyncPayInfo();
|
||||
PayLocal asyncPayInfo = PaymentContextLocal.get().getPayInfo();
|
||||
// 是否支付完成, 保存流水记录
|
||||
if (asyncPayInfo.isPayComplete()){
|
||||
weChatPayRecordService.pay(this.getOrder(), this.getChannelOrder());
|
||||
|
@@ -0,0 +1,23 @@
|
||||
package cn.bootx.platform.daxpay.service.core.task.notice.convert;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.entity.ClientNoticeRecord;
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.entity.ClientNoticeTask;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.notice.ClientNoticeRecordDto;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.notice.ClientNoticeTaskDto;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2024/2/23
|
||||
*/
|
||||
@Mapper
|
||||
public interface ClientNoticeConvert {
|
||||
ClientNoticeConvert CONVERT = Mappers.getMapper(ClientNoticeConvert.class);
|
||||
|
||||
ClientNoticeRecordDto convert(ClientNoticeRecord in);
|
||||
|
||||
ClientNoticeTaskDto convert(ClientNoticeTask in);
|
||||
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
package cn.bootx.platform.daxpay.service.core.task.notice.dao;
|
||||
|
||||
import cn.bootx.platform.common.core.rest.param.PageParam;
|
||||
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
|
||||
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
|
||||
import cn.bootx.platform.common.query.generator.QueryGenerator;
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.entity.ClientNoticeRecord;
|
||||
import cn.bootx.platform.daxpay.service.param.record.ClientNoticeRecordQuery;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2024/2/23
|
||||
*/
|
||||
@Slf4j
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class ClientNoticeRecordManager extends BaseManager<ClientNoticeRecordMapper, ClientNoticeRecord> {
|
||||
|
||||
/**
|
||||
* 分页
|
||||
*/
|
||||
public Page<ClientNoticeRecord> page(PageParam pageParam, ClientNoticeRecordQuery query){
|
||||
QueryWrapper<ClientNoticeRecord> generator = QueryGenerator.generator(query);
|
||||
Page<ClientNoticeRecord> mpPage = MpUtil.getMpPage(pageParam, ClientNoticeRecord.class);
|
||||
|
||||
return this.page(mpPage, generator);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,14 @@
|
||||
package cn.bootx.platform.daxpay.service.core.task.notice.dao;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.entity.ClientNoticeRecord;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2024/2/23
|
||||
*/
|
||||
@Mapper
|
||||
public interface ClientNoticeRecordMapper extends BaseMapper<ClientNoticeRecord> {
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
package cn.bootx.platform.daxpay.service.core.task.notice.dao;
|
||||
|
||||
import cn.bootx.platform.common.core.rest.param.PageParam;
|
||||
import cn.bootx.platform.common.mybatisplus.impl.BaseManager;
|
||||
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
|
||||
import cn.bootx.platform.common.query.generator.QueryGenerator;
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.entity.ClientNoticeTask;
|
||||
import cn.bootx.platform.daxpay.service.param.record.ClientNoticeTaskQuery;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author xxm
|
||||
* @since 2024/2/20
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ClientNoticeTaskManager extends BaseManager<ClientNoticeTaskMapper, ClientNoticeTask> {
|
||||
|
||||
|
||||
/**
|
||||
* 分页
|
||||
*/
|
||||
public Page<ClientNoticeTask> page(PageParam pageParam, ClientNoticeTaskQuery query){
|
||||
QueryWrapper<ClientNoticeTask> generator = QueryGenerator.generator(query);
|
||||
Page<ClientNoticeTask> mpPage = MpUtil.getMpPage(pageParam, ClientNoticeTask.class);
|
||||
|
||||
return this.page(mpPage, generator);
|
||||
}
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
package cn.bootx.platform.daxpay.service.core.payment.notice.dao;
|
||||
package cn.bootx.platform.daxpay.service.core.task.notice.dao;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.payment.notice.entity.ClientNoticeTask;
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.entity.ClientNoticeTask;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
@@ -0,0 +1,57 @@
|
||||
package cn.bootx.platform.daxpay.service.core.task.notice.entity;
|
||||
|
||||
import cn.bootx.platform.common.core.function.EntityBaseFunction;
|
||||
import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity;
|
||||
import cn.bootx.platform.daxpay.service.code.ClientNoticeSendTypeEnum;
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.convert.ClientNoticeConvert;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.notice.ClientNoticeRecordDto;
|
||||
import cn.bootx.table.modify.annotation.DbColumn;
|
||||
import cn.bootx.table.modify.annotation.DbTable;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 消息通知任务记录表
|
||||
* @author xxm
|
||||
* @since 2024/2/20
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@DbTable(comment = "消息通知任务记录")
|
||||
@TableName("pay_client_notice_record")
|
||||
public class ClientNoticeRecord extends MpCreateEntity implements EntityBaseFunction<ClientNoticeRecordDto> {
|
||||
|
||||
/** 任务ID */
|
||||
@DbColumn(comment = "任务ID")
|
||||
private Long taskId;
|
||||
|
||||
/** 请求次数 */
|
||||
@DbColumn(comment = "请求次数")
|
||||
private Integer reqCount;
|
||||
|
||||
/** 发送是否成功 */
|
||||
@DbColumn(comment = "发送是否成功")
|
||||
private boolean success;
|
||||
|
||||
/**
|
||||
* 发送类型, 自动发送, 手动发送
|
||||
* @see ClientNoticeSendTypeEnum
|
||||
*/
|
||||
@DbColumn(comment = "发送类型")
|
||||
private String type;
|
||||
|
||||
/** 错误信息 */
|
||||
@DbColumn(comment = "错误信息")
|
||||
private String errorMsg;
|
||||
|
||||
/**
|
||||
* 转换
|
||||
*/
|
||||
@Override
|
||||
public ClientNoticeRecordDto toDto() {
|
||||
return ClientNoticeConvert.CONVERT.convert(this);
|
||||
}
|
||||
}
|
@@ -1,7 +1,10 @@
|
||||
package cn.bootx.platform.daxpay.service.core.payment.notice.entity;
|
||||
package cn.bootx.platform.daxpay.service.core.task.notice.entity;
|
||||
|
||||
import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity;
|
||||
import cn.bootx.platform.common.core.function.EntityBaseFunction;
|
||||
import cn.bootx.platform.common.mybatisplus.base.MpBaseEntity;
|
||||
import cn.bootx.platform.daxpay.service.code.ClientNoticeTypeEnum;
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.convert.ClientNoticeConvert;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.notice.ClientNoticeTaskDto;
|
||||
import cn.bootx.table.modify.annotation.DbColumn;
|
||||
import cn.bootx.table.modify.annotation.DbTable;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
@@ -9,6 +12,8 @@ import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 消息通知任务
|
||||
* @author xxm
|
||||
@@ -18,18 +23,18 @@ import lombok.experimental.Accessors;
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@DbTable(comment = "消息通知任务")
|
||||
@TableName("tb_client_notice_task")
|
||||
public class ClientNoticeTask extends MpCreateEntity {
|
||||
@TableName("pay_client_notice_task")
|
||||
public class ClientNoticeTask extends MpBaseEntity implements EntityBaseFunction<ClientNoticeTaskDto> {
|
||||
|
||||
/** 本地订单ID */
|
||||
@DbColumn(comment = "本地订单ID")
|
||||
private Long orderId;
|
||||
|
||||
/**
|
||||
* 回调类型
|
||||
* 消息类型
|
||||
* @see ClientNoticeTypeEnum
|
||||
*/
|
||||
@DbColumn(comment = "回调类型")
|
||||
@DbColumn(comment = "消息类型")
|
||||
private String type;
|
||||
|
||||
/** 消息内容 */
|
||||
@@ -47,4 +52,16 @@ public class ClientNoticeTask extends MpCreateEntity {
|
||||
/** 发送地址 */
|
||||
@DbColumn(comment = "发送地址")
|
||||
private String url;
|
||||
|
||||
/** 最后发送时间 */
|
||||
@DbColumn(comment = "最后发送时间")
|
||||
private LocalDateTime latestTime;
|
||||
|
||||
/**
|
||||
* 转换
|
||||
*/
|
||||
@Override
|
||||
public ClientNoticeTaskDto toDto() {
|
||||
return ClientNoticeConvert.CONVERT.convert(this);
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
package cn.bootx.platform.daxpay.service.core.task.notice.service;
|
||||
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.dao.ClientNoticeRecordManager;
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.entity.ClientNoticeRecord;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* 消息通知发送记录
|
||||
* @author xxm
|
||||
* @since 2024/2/23
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ClientNoticeRecordService {
|
||||
private final ClientNoticeRecordManager recordManager;
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRES_NEW)
|
||||
public void save(ClientNoticeRecord record){
|
||||
recordManager.save(record);
|
||||
}
|
||||
}
|
@@ -0,0 +1,70 @@
|
||||
package cn.bootx.platform.daxpay.service.core.task.notice.service;
|
||||
|
||||
import cn.bootx.platform.common.core.exception.DataNotExistException;
|
||||
import cn.bootx.platform.common.core.rest.PageResult;
|
||||
import cn.bootx.platform.common.core.rest.param.PageParam;
|
||||
import cn.bootx.platform.common.mybatisplus.util.MpUtil;
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.entity.ClientNoticeRecord;
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.entity.ClientNoticeTask;
|
||||
import cn.bootx.platform.daxpay.service.core.payment.notice.service.ClientNoticeService;
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.dao.ClientNoticeRecordManager;
|
||||
import cn.bootx.platform.daxpay.service.core.task.notice.dao.ClientNoticeTaskManager;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.notice.ClientNoticeRecordDto;
|
||||
import cn.bootx.platform.daxpay.service.dto.record.notice.ClientNoticeTaskDto;
|
||||
import cn.bootx.platform.daxpay.service.param.record.ClientNoticeRecordQuery;
|
||||
import cn.bootx.platform.daxpay.service.param.record.ClientNoticeTaskQuery;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 通知任务查询类
|
||||
* @author xxm
|
||||
* @since 2024/2/23
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ClientNoticeTaskService {
|
||||
|
||||
private final ClientNoticeService clientNoticeService;
|
||||
|
||||
private final ClientNoticeTaskManager taskManager;
|
||||
|
||||
private final ClientNoticeRecordManager recordManager;
|
||||
|
||||
|
||||
/**
|
||||
* 手动触发消息发送
|
||||
*/
|
||||
public void sendData(Long taskId){
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务分页查询
|
||||
*/
|
||||
public PageResult<ClientNoticeTaskDto> taskPage(PageParam pageParam, ClientNoticeTaskQuery query){
|
||||
return MpUtil.convert2DtoPageResult(taskManager.page(pageParam, query));
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务详情
|
||||
*/
|
||||
public ClientNoticeTaskDto findTaskById(Long id){
|
||||
return taskManager.findById(id).map(ClientNoticeTask::toDto).orElseThrow(DataNotExistException::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录分页
|
||||
*/
|
||||
public PageResult<ClientNoticeRecordDto> recordPage(PageParam pageParam, ClientNoticeRecordQuery query){
|
||||
return MpUtil.convert2DtoPageResult(recordManager.page(pageParam, query));
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录详情
|
||||
*/
|
||||
public ClientNoticeRecordDto findRecordById(Long id){
|
||||
return recordManager.findById(id).map(ClientNoticeRecord::toDto).orElseThrow(DataNotExistException::new);
|
||||
}
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
package cn.bootx.platform.daxpay.service.dto.record.notice;
|
||||
|
||||
import cn.bootx.platform.common.core.rest.dto.BaseDto;
|
||||
import cn.bootx.platform.daxpay.service.code.ClientNoticeSendTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 消息通知记录
|
||||
* @author xxm
|
||||
* @since 2024/2/23
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "消息通知记录")
|
||||
public class ClientNoticeRecordDto extends BaseDto {
|
||||
|
||||
/** 任务ID */
|
||||
@Schema(description = "任务ID")
|
||||
private Long taskId;
|
||||
|
||||
/**
|
||||
* 发送类型, 自动发送, 手动发送
|
||||
* @see ClientNoticeSendTypeEnum
|
||||
*/
|
||||
@Schema(description = "发送类型")
|
||||
private String type;
|
||||
|
||||
/** 请求次数 */
|
||||
@Schema(description = "请求次数")
|
||||
private Integer reqCount;
|
||||
|
||||
/** 发送是否成功 */
|
||||
@Schema(description = "发送是否成功")
|
||||
private boolean success;
|
||||
|
||||
/** 错误信息 */
|
||||
@Schema(description = "错误信息")
|
||||
private String errorMsg;
|
||||
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
package cn.bootx.platform.daxpay.service.dto.record.notice;
|
||||
|
||||
import cn.bootx.platform.common.core.rest.dto.BaseDto;
|
||||
import cn.bootx.platform.daxpay.service.code.ClientNoticeTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 消息通知任务
|
||||
* @author xxm
|
||||
* @since 2024/2/23
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "消息通知任务")
|
||||
public class ClientNoticeTaskDto extends BaseDto {
|
||||
|
||||
/** 本地订单ID */
|
||||
@Schema(description = "本地订单ID")
|
||||
private Long orderId;
|
||||
|
||||
/**
|
||||
* 回调类型
|
||||
* @see ClientNoticeTypeEnum
|
||||
*/
|
||||
@Schema(description = "回调类型")
|
||||
private String type;
|
||||
|
||||
/** 消息内容 */
|
||||
@Schema(description = "消息内容")
|
||||
private String content;
|
||||
|
||||
/** 是否发送成功 */
|
||||
@Schema(description = "是否发送成功")
|
||||
private boolean success;
|
||||
|
||||
/** 发送次数 */
|
||||
@Schema(description = "发送次数")
|
||||
private Integer sendCount;
|
||||
|
||||
/** 发送地址 */
|
||||
@Schema(description = "发送地址")
|
||||
private String url;
|
||||
|
||||
/** 最后发送时间 */
|
||||
@Schema(description = "最后发送时间")
|
||||
private LocalDateTime latestTime;
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
package cn.bootx.platform.daxpay.service.param.record;
|
||||
|
||||
import cn.bootx.platform.common.core.annotation.QueryParam;
|
||||
import cn.bootx.platform.common.core.rest.param.QueryOrder;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 客户通知记录查询
|
||||
* @author xxm
|
||||
* @since 2024/2/24
|
||||
*/
|
||||
@QueryParam
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "客户通知记录查询")
|
||||
public class ClientNoticeRecordQuery extends QueryOrder {
|
||||
|
||||
/** 任务ID */
|
||||
@Schema(description ="任务ID")
|
||||
private Long taskId;
|
||||
|
||||
/** 请求次数 */
|
||||
@Schema(description ="请求次数")
|
||||
private Integer reqCount;
|
||||
|
||||
/** 发送是否成功 */
|
||||
@Schema(description ="发送是否成功")
|
||||
private Boolean success;
|
||||
|
||||
/** 错误信息 */
|
||||
@Schema(description ="错误信息")
|
||||
private String errorMsg;
|
||||
}
|
@@ -0,0 +1,49 @@
|
||||
package cn.bootx.platform.daxpay.service.param.record;
|
||||
|
||||
import cn.bootx.platform.common.core.annotation.QueryParam;
|
||||
import cn.bootx.platform.common.core.rest.param.QueryOrder;
|
||||
import cn.bootx.platform.daxpay.service.code.ClientNoticeTypeEnum;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 发送通知任务查询
|
||||
* @author xxm
|
||||
* @since 2024/2/24
|
||||
*/
|
||||
@QueryParam
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Schema(title = "发送通知任务查询")
|
||||
public class ClientNoticeTaskQuery extends QueryOrder {
|
||||
|
||||
/** 本地订单ID */
|
||||
@Schema(description ="本地订单ID")
|
||||
private Long orderId;
|
||||
|
||||
/**
|
||||
* 通知类型
|
||||
* @see ClientNoticeTypeEnum
|
||||
*/
|
||||
@Schema(description ="通知类型")
|
||||
private String type;
|
||||
|
||||
/** 消息内容 */
|
||||
@Schema(description ="消息内容")
|
||||
private String content;
|
||||
|
||||
/** 是否发送成功 */
|
||||
@Schema(description ="是否发送成功")
|
||||
private Boolean success;
|
||||
|
||||
/** 发送次数 */
|
||||
@Schema(description ="发送次数")
|
||||
private Integer sendCount;
|
||||
|
||||
/** 发送地址 */
|
||||
@Schema(description ="发送地址")
|
||||
private String url;
|
||||
}
|
@@ -10,7 +10,7 @@ import org.springframework.stereotype.Component;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 消息通知任务
|
||||
* 发送消息通知任务
|
||||
* @author xxm
|
||||
* @since 2024/2/22
|
||||
*/
|
||||
@@ -19,7 +19,7 @@ import java.time.LocalDateTime;
|
||||
@DisallowConcurrentExecution
|
||||
@PersistJobDataAfterExecution
|
||||
@RequiredArgsConstructor
|
||||
public class ClientNoticeTask implements Job {
|
||||
public class ClientNoticeSendTask implements Job {
|
||||
|
||||
private final ClientNoticeService clientNoticeService;
|
||||
|
@@ -33,7 +33,7 @@ public class PayReconcileTaskService {
|
||||
reconcileService.downAndSave(reconcileOrder);
|
||||
|
||||
// 3. 执行账单比对, 生成差异单
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user