From 97ed6b7e256b15cd53c5ba6d776dc458604e07e9 Mon Sep 17 00:00:00 2001 From: bootx Date: Sun, 21 Jan 2024 01:04:24 +0800 Subject: [PATCH] =?UTF-8?q?feat=20=E6=94=AF=E4=BB=98=E5=AF=B9=E8=B4=A6?= =?UTF-8?q?=E5=8D=95=E5=88=9B=E5=BB=BA=E5=92=8C=E4=B8=8B=E8=BD=BD,=20?= =?UTF-8?q?=E4=BB=A5=E5=8F=8A=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../record/PayReconcileOrderController.java | 41 ++++++++++ .../record/PayReconcileRecordController.java | 20 ----- .../platform/daxpay/code/PayChannelEnum.java | 15 ++-- daxpay-single/daxpay-single-service/pom.xml | 12 ++- .../dao/PayReconcileDetailManager.java | 18 +++++ .../dao/PayReconcileDetailMapper.java | 14 ++++ .../dao/PayReconcileOrderManager.java} | 6 +- .../dao/PayReconcileOrderMapper.java | 14 ++++ .../reconcile/entity/PayReconcileDetail.java} | 4 +- .../reconcile/entity/PayReconcileOrder.java} | 16 +++- .../service/PayReconcileOrderService.java | 81 +++++++++++++++++++ .../service/PayReconcileService.java | 51 ++++++------ .../strategy/AlipayReconcileStrategy.java | 6 +- .../strategy/WechatPayReconcileStrategy.java | 6 +- .../dao/PayReconcileRecordMapper.java | 14 ---- .../service/func/AbsReconcileStrategy.java | 21 +++-- .../reconcile/CreateReconcileOrderParam.java | 28 +++++++ .../daxpay/service/task/PayReconcileTask.java | 52 ++++++++++++ .../task/service/PayReconcileTaskService.java | 39 +++++++++ 19 files changed, 368 insertions(+), 90 deletions(-) create mode 100644 daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/record/PayReconcileOrderController.java delete mode 100644 daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/record/PayReconcileRecordController.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileDetailManager.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileDetailMapper.java rename daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/{record/reconcile/dao/PayReconcileRecordManager.java => order/reconcile/dao/PayReconcileOrderManager.java} (51%) create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileOrderMapper.java rename daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/{record/reconcile/entity/PayReconcileDetailRecord.java => order/reconcile/entity/PayReconcileDetail.java} (86%) rename daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/{record/reconcile/entity/PayReconcileRecord.java => order/reconcile/entity/PayReconcileOrder.java} (64%) create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/service/PayReconcileOrderService.java delete mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/reconcile/dao/PayReconcileRecordMapper.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/reconcile/CreateReconcileOrderParam.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/task/PayReconcileTask.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/task/service/PayReconcileTaskService.java diff --git a/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/record/PayReconcileOrderController.java b/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/record/PayReconcileOrderController.java new file mode 100644 index 000000000..5730d4557 --- /dev/null +++ b/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/record/PayReconcileOrderController.java @@ -0,0 +1,41 @@ +package cn.bootx.platform.daxpay.admin.controller.record; + +import cn.bootx.platform.common.core.rest.Res; +import cn.bootx.platform.common.core.rest.ResResult; +import cn.bootx.platform.common.core.util.ValidationUtil; +import cn.bootx.platform.daxpay.service.core.order.reconcile.service.PayReconcileOrderService; +import cn.bootx.platform.daxpay.service.core.payment.reconcile.service.PayReconcileService; +import cn.bootx.platform.daxpay.service.param.reconcile.CreateReconcileOrderParam; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +/** + * 支付对账 + * @author xxm + * @since 2024/1/18 + */ +@Tag(name = "支付对账控制器") +@RestController +@RequestMapping("/record/reconcile") +@RequiredArgsConstructor +public class PayReconcileOrderController { + private final PayReconcileService reconcileService; + private final PayReconcileOrderService reconcileOrderService; + + @Operation(summary = "手动创建支付对账订单") + @PostMapping("/createOrder") + public ResResult createOrder(@RequestBody CreateReconcileOrderParam param){ + ValidationUtil.validateParam(param); + reconcileOrderService.create(param.getDate(), param.getChannel()); + return Res.ok(); + } + + @Operation(summary = "手动触发对账文件下载") + @PostMapping("/downById") + public ResResult downByChannel(Long id){ + reconcileService.downAndSave(id); + return Res.ok(); + } +} diff --git a/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/record/PayReconcileRecordController.java b/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/record/PayReconcileRecordController.java deleted file mode 100644 index 11f82c683..000000000 --- a/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/record/PayReconcileRecordController.java +++ /dev/null @@ -1,20 +0,0 @@ -package cn.bootx.platform.daxpay.admin.controller.record; - -import cn.bootx.platform.daxpay.service.core.payment.reconcile.service.PayReconcileService; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -/** - * 支付对账 - * @author xxm - * @since 2024/1/18 - */ -@Tag(name = "支付对账控制器") -@RestController -@RequestMapping("/record/reconcile") -@RequiredArgsConstructor -public class PayReconcileRecordController { - private final PayReconcileService reconcileService; -} diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayChannelEnum.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayChannelEnum.java index 9dece64b8..131247596 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayChannelEnum.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayChannelEnum.java @@ -19,12 +19,12 @@ import java.util.Objects; @RequiredArgsConstructor public enum PayChannelEnum { - ALI("ali_pay", "支付宝"), - WECHAT("wechat_pay", "微信支付"), - UNION_PAY("union_pay", "云闪付"), - CASH("cash_pay", "现金支付"), - WALLET("wallet_pay", "钱包支付"), - VOUCHER("voucher_pay", "储值卡支付"); + ALI("ali_pay", "支付宝", "ali"), + WECHAT("wechat_pay", "微信支付", "wx"), + UNION_PAY("union_pay", "云闪付", "uni"), + CASH("cash_pay", "现金支付",null), + WALLET("wallet_pay", "钱包支付",null), + VOUCHER("voucher_pay", "储值卡支付",null); /** 支付通道编码 */ private final String code; @@ -32,6 +32,9 @@ public enum PayChannelEnum { /** 支付通道名称 */ private final String name; + /** 对账前缀 */ + private final String reconcilePrefix; + /** * 根据字符编码获取 */ diff --git a/daxpay-single/daxpay-single-service/pom.xml b/daxpay-single/daxpay-single-service/pom.xml index 291008862..4cf0b71f6 100644 --- a/daxpay-single/daxpay-single-service/pom.xml +++ b/daxpay-single/daxpay-single-service/pom.xml @@ -49,12 +49,22 @@ cn.bootx.platform common-spring - cn.bootx.platform common-super-query + + + cn.bootx.platform + common-starter-quartz + + + + cn.bootx.platform + common-sequence + ${bootx-platform.version} + diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileDetailManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileDetailManager.java new file mode 100644 index 000000000..82af70a19 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileDetailManager.java @@ -0,0 +1,18 @@ +package cn.bootx.platform.daxpay.service.core.order.reconcile.dao; + +import cn.bootx.platform.common.mybatisplus.impl.BaseManager; +import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.PayReconcileDetail; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Repository; + +/** + * + * @author xxm + * @since 2024/1/20 + */ +@Slf4j +@Repository +@RequiredArgsConstructor +public class PayReconcileDetailManager extends BaseManager { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileDetailMapper.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileDetailMapper.java new file mode 100644 index 000000000..fa86df1d8 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileDetailMapper.java @@ -0,0 +1,14 @@ +package cn.bootx.platform.daxpay.service.core.order.reconcile.dao; + +import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.PayReconcileDetail; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * + * @author xxm + * @since 2024/1/20 + */ +@Mapper +public interface PayReconcileDetailMapper extends BaseMapper { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/reconcile/dao/PayReconcileRecordManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileOrderManager.java similarity index 51% rename from daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/reconcile/dao/PayReconcileRecordManager.java rename to daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileOrderManager.java index 50c362d37..5657a2e55 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/reconcile/dao/PayReconcileRecordManager.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileOrderManager.java @@ -1,7 +1,7 @@ -package cn.bootx.platform.daxpay.service.core.record.reconcile.dao; +package cn.bootx.platform.daxpay.service.core.order.reconcile.dao; import cn.bootx.platform.common.mybatisplus.impl.BaseManager; -import cn.bootx.platform.daxpay.service.core.record.reconcile.entity.PayReconcileRecord; +import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.PayReconcileOrder; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Repository; @@ -14,5 +14,5 @@ import org.springframework.stereotype.Repository; @Slf4j @Repository @RequiredArgsConstructor -public class PayReconcileRecordManager extends BaseManager { +public class PayReconcileOrderManager extends BaseManager { } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileOrderMapper.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileOrderMapper.java new file mode 100644 index 000000000..041e45066 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileOrderMapper.java @@ -0,0 +1,14 @@ +package cn.bootx.platform.daxpay.service.core.order.reconcile.dao; + +import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.PayReconcileOrder; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * + * @author xxm + * @since 2024/1/18 + */ +@Mapper +public interface PayReconcileOrderMapper extends BaseMapper { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/reconcile/entity/PayReconcileDetailRecord.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/entity/PayReconcileDetail.java similarity index 86% rename from daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/reconcile/entity/PayReconcileDetailRecord.java rename to daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/entity/PayReconcileDetail.java index 467fc1626..882fbbe97 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/reconcile/entity/PayReconcileDetailRecord.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/entity/PayReconcileDetail.java @@ -1,4 +1,4 @@ -package cn.bootx.platform.daxpay.service.core.record.reconcile.entity; +package cn.bootx.platform.daxpay.service.core.order.reconcile.entity; import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity; import com.baomidou.mybatisplus.annotation.TableName; @@ -15,7 +15,7 @@ import lombok.experimental.Accessors; @Data @Accessors(chain = true) @TableName("pay_reconcile_detail_record") -public class PayReconcileDetailRecord extends MpCreateEntity { +public class PayReconcileDetail extends MpCreateEntity { /** 交易状态 */ private String status; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/reconcile/entity/PayReconcileRecord.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/entity/PayReconcileOrder.java similarity index 64% rename from daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/reconcile/entity/PayReconcileRecord.java rename to daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/entity/PayReconcileOrder.java index 47d2b3f14..d9cbc02dd 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/reconcile/entity/PayReconcileRecord.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/entity/PayReconcileOrder.java @@ -1,4 +1,4 @@ -package cn.bootx.platform.daxpay.service.core.record.reconcile.entity; +package cn.bootx.platform.daxpay.service.core.order.reconcile.entity; import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity; import cn.bootx.table.modify.annotation.DbTable; @@ -19,7 +19,14 @@ import java.time.LocalDate; @Accessors(chain = true) @DbTable(comment = "支付对账单记录") @TableName("pay_reconcile_record") -public class PayReconcileRecord extends MpCreateEntity { +public class PayReconcileOrder extends MpCreateEntity { + + /** + * 批次号 + * 规则:通道简称 + yyyyMMdd + 两位流水号 + * 例子:wx2024012001、ali2024012002 + */ + private String batchNo; /** 日期 */ private LocalDate date; @@ -28,7 +35,10 @@ public class PayReconcileRecord extends MpCreateEntity { private String channel; /** 对账单是否下载成功 */ - private boolean success; + private boolean down; + + /** 是否比对完成 */ + private boolean compare; /** 错误信息 */ private String errorMsg; diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/service/PayReconcileOrderService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/service/PayReconcileOrderService.java new file mode 100644 index 000000000..0bcd69857 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/service/PayReconcileOrderService.java @@ -0,0 +1,81 @@ +package cn.bootx.platform.daxpay.service.core.order.reconcile.service; + +import cn.bootx.platform.common.core.util.LocalDateTimeUtil; +import cn.bootx.platform.common.sequence.func.Sequence; +import cn.bootx.platform.daxpay.code.PayChannelEnum; +import cn.bootx.platform.daxpay.exception.pay.PayFailureException; +import cn.bootx.platform.daxpay.service.core.order.reconcile.dao.PayReconcileOrderManager; +import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.PayReconcileOrder; +import cn.hutool.core.date.DatePattern; +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; + +import java.time.LocalDate; +import java.util.Optional; + +/** + * 支付对账订单服务 + * @author xxm + * @since 2024/1/20 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class PayReconcileOrderService { + private final PayReconcileOrderManager reconcileOrderManager; + private final Sequence sequence; + + + /** + * 更新, 开启一个新事务进行更新 + */ + @Transactional(propagation = Propagation.REQUIRES_NEW) + public void update(PayReconcileOrder order){ + reconcileOrderManager.updateById(order); + } + + /** + * 根据Id查询 + */ + public Optional findById(Long id){ + return reconcileOrderManager.findById(id); + } + + /** + * 创建对账订单 + */ + public PayReconcileOrder create(LocalDate date,String channel) { + // 获取通道枚举 + PayChannelEnum channelEnum = PayChannelEnum.findByCode(channel); + // 判断是否为为异步通道 + if (!PayChannelEnum.ASYNC_TYPE.contains(channelEnum)){ + throw new PayFailureException("不支持对账的通道, 请检查"); + } + // 生成批次号 + String format = LocalDateTimeUtil.format(date, DatePattern.PURE_DATE_PATTERN); + String key = channelEnum.getReconcilePrefix()+format; + String seqNo = this.genSeqNo(key); + + PayReconcileOrder order = new PayReconcileOrder() + .setBatchNo(seqNo) + .setChannel(channel) + .setDate(date); + reconcileOrderManager.save(order); + return order; + } + + + /** + * 生成批次号 + * 规则:通道简称 + yyyyMMdd + 两位流水号 + * 例子:wx2024012001、ali2024012002 + */ + private String genSeqNo(String key){ + long next = sequence.next(key); + return String.format("%2d",next); + + } +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/service/PayReconcileService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/service/PayReconcileService.java index 4623a921c..c64633d0e 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/service/PayReconcileService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/service/PayReconcileService.java @@ -1,14 +1,14 @@ package cn.bootx.platform.daxpay.service.core.payment.reconcile.service; +import cn.bootx.platform.common.core.exception.DataNotExistException; +import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.PayReconcileOrder; +import cn.bootx.platform.daxpay.service.core.order.reconcile.service.PayReconcileOrderService; import cn.bootx.platform.daxpay.service.core.payment.reconcile.factory.PayReconcileStrategyFactory; import cn.bootx.platform.daxpay.service.func.AbsReconcileStrategy; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; -import java.time.LocalDate; -import java.util.List; - /** * 支付对账单下载服务 * @author xxm @@ -18,37 +18,34 @@ import java.util.List; @Service @RequiredArgsConstructor public class PayReconcileService { + private final PayReconcileOrderService reconcileOrderService; + /** - * 下载对账单 + * 下载对账单并进行保存 */ - public void downAll(LocalDate date){ - List strategies = PayReconcileStrategyFactory.create(); - strategies.forEach(AbsReconcileStrategy::doBeforeHandler); + public void downAndSave(Long reconcileOrderId) { + PayReconcileOrder payReconcileOrder = reconcileOrderService.findById(reconcileOrderId) + .orElseThrow(() -> new DataNotExistException("未找到对账订单")); + this.downAndSave(payReconcileOrder); } /** - * 手动发起对账下载 + * 下载对账单并进行保存 */ - public void downByChannel(LocalDate date, String channel){ - AbsReconcileStrategy absReconcileStrategy = PayReconcileStrategyFactory.create(channel); + public void downAndSave(PayReconcileOrder recordOrder) { + AbsReconcileStrategy absReconcileStrategy = PayReconcileStrategyFactory.create(recordOrder.getChannel()); + absReconcileStrategy.initParam(recordOrder); absReconcileStrategy.doBeforeHandler(); - absReconcileStrategy.downAndSave(date); + try { + absReconcileStrategy.downAndSave(); + recordOrder.setDown(true); + reconcileOrderService.update(recordOrder); + } catch (Exception e) { + log.error("下载对账单异常", e); + recordOrder.setErrorMsg(e.getMessage()); + reconcileOrderService.update(recordOrder); + throw new RuntimeException(e); + } } - /** - * 全部对账 - */ - public void offsetting(LocalDate date){ - List strategies = PayReconcileStrategyFactory.create(); - strategies.forEach(AbsReconcileStrategy::doBeforeHandler); - } - - /** - * 全部对账 - */ - public void offsettingByChannel(LocalDate date, String channel){ - AbsReconcileStrategy absReconcileStrategy = PayReconcileStrategyFactory.create(channel); - absReconcileStrategy.doBeforeHandler(); - absReconcileStrategy.offsetting(date); - } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/AlipayReconcileStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/AlipayReconcileStrategy.java index 6c126aabe..e7a90269a 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/AlipayReconcileStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/AlipayReconcileStrategy.java @@ -12,8 +12,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; -import java.time.LocalDate; - import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE; /** @@ -57,8 +55,8 @@ public class AlipayReconcileStrategy extends AbsReconcileStrategy { * 下载对账单 */ @Override - public void downAndSave(LocalDate date) { - String format = LocalDateTimeUtil.format(date, DatePattern.NORM_DATE_PATTERN); + public void downAndSave() { + String format = LocalDateTimeUtil.format(this.getRecordOrder().getDate(), DatePattern.NORM_DATE_PATTERN); reconcileService.downAndSave(format); } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/WechatPayReconcileStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/WechatPayReconcileStrategy.java index 1ea9bf60d..3d9be1b06 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/WechatPayReconcileStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/WechatPayReconcileStrategy.java @@ -12,8 +12,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; -import java.time.LocalDate; - import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE; /** @@ -55,8 +53,8 @@ public class WechatPayReconcileStrategy extends AbsReconcileStrategy { * 下载对账单 */ @Override - public void downAndSave(LocalDate date) { - String format = LocalDateTimeUtil.format(date, DatePattern.PURE_DATE_PATTERN); + public void downAndSave() { + String format = LocalDateTimeUtil.format(this.getRecordOrder().getDate(), DatePattern.PURE_DATE_PATTERN); reconcileService.downAndSave(format,this.config); } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/reconcile/dao/PayReconcileRecordMapper.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/reconcile/dao/PayReconcileRecordMapper.java deleted file mode 100644 index d92513c0e..000000000 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/record/reconcile/dao/PayReconcileRecordMapper.java +++ /dev/null @@ -1,14 +0,0 @@ -package cn.bootx.platform.daxpay.service.core.record.reconcile.dao; - -import cn.bootx.platform.daxpay.service.core.record.reconcile.entity.PayReconcileRecord; -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import org.apache.ibatis.annotations.Mapper; - -/** - * - * @author xxm - * @since 2024/1/18 - */ -@Mapper -public interface PayReconcileRecordMapper extends BaseMapper { -} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsReconcileStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsReconcileStrategy.java index 92b4ab360..e91d75fb4 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsReconcileStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsReconcileStrategy.java @@ -1,17 +1,19 @@ package cn.bootx.platform.daxpay.service.func; import cn.bootx.platform.daxpay.code.PayChannelEnum; - -import java.time.LocalDate; +import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.PayReconcileOrder; +import lombok.Getter; /** * 支付对账策略 * @author xxm * @since 2024/1/18 */ +@Getter public abstract class AbsReconcileStrategy { - + /** 对账订单 */ + private PayReconcileOrder recordOrder; /** * 策略标识 @@ -25,19 +27,26 @@ public abstract class AbsReconcileStrategy { public void doBeforeHandler() { } + /** + * 初始化参数 + */ + public void initParam(PayReconcileOrder recordOrder){ + this.recordOrder = recordOrder; + } /** * 下载对账单到本地进行保存 */ - public abstract void downAndSave(LocalDate date); + public abstract void downAndSave(); /** - * 轧差 + * 比对生成对账差异单 * 1. 远程有, 本地无 补单(追加回订单/记录差异表) * 2. 远程无, 本地有 记录差错表 * 3. 远程有, 本地有, 但状态不一致 */ - public void offsetting(LocalDate date){ + public void offsetting(){ + } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/reconcile/CreateReconcileOrderParam.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/reconcile/CreateReconcileOrderParam.java new file mode 100644 index 000000000..615235240 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/reconcile/CreateReconcileOrderParam.java @@ -0,0 +1,28 @@ +package cn.bootx.platform.daxpay.service.param.reconcile; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.time.LocalDate; + +/** + * 创建对账订单参数 + * @author xxm + * @since 2024/1/20 + */ +@Data +@Accessors(chain = true) +@Schema(title = "创建对账订单参数") +public class CreateReconcileOrderParam { + + @NotNull(message = "日期不能为空") + @Schema(description = "日期") + private LocalDate date; + + @NotBlank(message = "同步的支付通道不能为空") + @Schema(description = "支付通道") + private String channel; +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/task/PayReconcileTask.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/task/PayReconcileTask.java new file mode 100644 index 000000000..9740205aa --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/task/PayReconcileTask.java @@ -0,0 +1,52 @@ +package cn.bootx.platform.daxpay.service.task; + +import cn.bootx.platform.daxpay.service.task.service.PayReconcileTaskService; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.quartz.*; +import org.springframework.stereotype.Component; + +import java.time.LocalDate; +import java.util.Objects; + +/** + * 对账任务下载和保存定时任务 + * @author xxm + * @since 2024/1/20 + */ +@Slf4j +@Component +@DisallowConcurrentExecution +@PersistJobDataAfterExecution +@RequiredArgsConstructor +public class PayReconcileTask implements Job { + private final PayReconcileTaskService reconcileTaskService; + + /** + * 若参数变量名修改 QuartzJobScheduler 中也需对应修改 需要给一个set方法, 让系统设置值 + */ + @Setter + private String channel; + + /** + * 同步账单规则是 T+N 天, 例如T+1就是同步昨天的账单, T+2就是同步前天的账单 + */ + @Setter + private Integer n; + + /** + * 任务实现 + */ + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + // 日期, 如果未配置T+N规则, 默认为T+1 + LocalDate date = LocalDate.now(); + if (Objects.nonNull(n)){ + date = date.minusDays(n); + } else { + date = date.minusDays(1); + } + reconcileTaskService.x1(date,channel); + } +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/task/service/PayReconcileTaskService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/task/service/PayReconcileTaskService.java new file mode 100644 index 000000000..88b4aab61 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/task/service/PayReconcileTaskService.java @@ -0,0 +1,39 @@ +package cn.bootx.platform.daxpay.service.task.service; + +import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.PayReconcileOrder; +import cn.bootx.platform.daxpay.service.core.order.reconcile.service.PayReconcileOrderService; +import cn.bootx.platform.daxpay.service.core.payment.reconcile.service.PayReconcileService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; + +/** + * 支付对账定时任务服务类 + * @author xxm + * @since 2024/1/20 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class PayReconcileTaskService { + private final PayReconcileService reconcileService; + private final PayReconcileOrderService reconcileOrderService; + + /** + * 执行任务 + */ + public void x1(LocalDate date, String channel){ + + // 1. 查询需要定时对账的通道, 创建出来对账订单 + PayReconcileOrder reconcileOrder = reconcileOrderService.create(date, channel); + + // 2. 执行对账任务, 下载对账单并解析, 分别存储为原始数据和通用对账数据 + reconcileService.downAndSave(reconcileOrder); + + // 3. 执行账单比对, 生成差异单 + + } + +}