From 22a81487f6a096e72860d07b29d832fe1c1b37b1 Mon Sep 17 00:00:00 2001 From: bootx Date: Mon, 22 Jan 2024 09:19:02 +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=E8=AE=A2=E5=8D=95=E5=88=9B=E5=BB=BA=E5=92=8C=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E8=BD=AC=E6=8D=A2=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _doc/Task.md | 12 ++-- .../platform/daxpay/code/PayStatusEnum.java | 4 +- .../gateway/controller/TestController.java | 13 ---- .../common/context/PaymentContext.java | 3 + .../common/context/ReconcileLocal.java | 22 ++++++ .../common/local/PaymentContextLocal.java | 12 ++++ .../dao/AliReconcileBillDetailManager.java | 18 +++++ .../dao/AliReconcileBillDetailMapper.java | 14 ++++ .../dao/AliReconcileBillTotalManager.java | 18 +++++ .../dao/AliReconcileBillTotalMapper.java | 14 ++++ .../alipay/entity/AliReconcileBillDetail.java | 37 +++++++++- .../alipay/entity/AliReconcileBillTotal.java | 16 +++++ .../service/AliPayReconcileService.java | 70 +++++++++++++++++-- .../dao/WxReconcileFundFlowDetailManager.java | 18 +++++ .../dao/WxReconcileFundFlowDetailMapper.java | 14 ++++ .../dao/WxReconcileFundFlowTotalManager.java | 18 +++++ .../dao/WxReconcileFundFlowTotalMapper.java | 14 ++++ .../wechat/entity/WxReconcileBillDetail.java | 32 +++++++++ .../wechat/entity/WxReconcileBillTotal.java | 11 +++ .../entity/WxReconcileFundFlowDetail.java | 17 ++++- .../entity/WxReconcileFundFlowTotal.java | 8 +++ .../service/WechatPayReconcileService.java | 56 ++++++++++++--- .../reconcile/entity/PayReconcileDetail.java | 30 +++++--- .../reconcile/entity/PayReconcileOrder.java | 15 ++-- .../PayReconcileOrderQueryService.java | 51 ++++++++++++++ .../service/PayReconcileOrderService.java | 1 - .../service/PayReconcileService.java | 15 ++++ .../strategy/AlipayReconcileStrategy.java | 6 +- .../strategy/WechatPayReconcileStrategy.java | 2 +- 29 files changed, 501 insertions(+), 60 deletions(-) create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/context/ReconcileLocal.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/dao/AliReconcileBillDetailManager.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/dao/AliReconcileBillDetailMapper.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/dao/AliReconcileBillTotalManager.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/dao/AliReconcileBillTotalMapper.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/dao/WxReconcileFundFlowDetailManager.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/dao/WxReconcileFundFlowDetailMapper.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/dao/WxReconcileFundFlowTotalManager.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/dao/WxReconcileFundFlowTotalMapper.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/service/PayReconcileOrderQueryService.java diff --git a/_doc/Task.md b/_doc/Task.md index 5b3a9b305..e32f6c4d7 100644 --- a/_doc/Task.md +++ b/_doc/Task.md @@ -63,13 +63,15 @@ - 2024-01-16: - [x] 支付单涉及退款状态同步逻辑 - 2024-01-17: - - [x] 支付宝和微信支付对账下载接口 -- 2024-01-18: +- 2024-01-21: - [x] (对账) 微信对账文件解析 - - [ ] (对账) 支付宝对账文件解析 - - [ ] (对账) 对账策略类和定时任务 - - [ ] (对账) 对账记录和明细保存 + - [x] (对账) 支付宝对账文件解析 + - [x] (对账) 对账策略类和定时任务 + - [x] (对账) 对账记录和明细保存 +- 2024-01-22: + - [ ] (对账) 通用结构对账结构转换 + - [ ] (对账) 对账列表页、操作按钮(手动创建、执行、重试) - **任务池** - [ ] 微信退款状态不一致补偿 - [ ] 接入支付网关的演示项目 diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayStatusEnum.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayStatusEnum.java index 3b59f11b0..05ac863bb 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayStatusEnum.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/PayStatusEnum.java @@ -18,9 +18,9 @@ public enum PayStatusEnum { PROGRESS("progress","支付中"), SUCCESS("success","成功"), CLOSE("close","支付关闭"), - FAIL("fail","失败"), PARTIAL_REFUND("partial_refund","部分退款"), - REFUNDED("refunded","全部退款"); + REFUNDED("refunded","全部退款"), + FAIL("fail","失败"); /** 编码 */ private final String code; diff --git a/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/TestController.java b/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/TestController.java index ab2709c8c..45587b359 100644 --- a/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/TestController.java +++ b/daxpay-single/daxpay-single-gateway/src/main/java/cn/bootx/platform/daxpay/gateway/controller/TestController.java @@ -70,17 +70,4 @@ public class TestController { return Res.ok(name); } - @Operation(summary = "下载支付宝对账单") - @GetMapping("/aliDownReconcile") - public ResResult aliDownReconcile(String date){ - alipayReconcileService.downAndSave(date); - return Res.ok(); - } - @Operation(summary = "下载微信对账单") - @GetMapping("/wxDownReconcile") - public ResResult wxDownReconcile(String date){ - wechatPayReconcileService.downAndSave(date,null); - return Res.ok(); - } - } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/context/PaymentContext.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/context/PaymentContext.java index cbd898c27..29a99111e 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/context/PaymentContext.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/context/PaymentContext.java @@ -36,4 +36,7 @@ public class PaymentContext { /** 支付请求相关信息 */ private final RequestLocal request = new RequestLocal(); + /** 支付对账相关信息 */ + private final ReconcileLocal reconcile = new ReconcileLocal(); + } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/context/ReconcileLocal.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/context/ReconcileLocal.java new file mode 100644 index 000000000..3432004bc --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/context/ReconcileLocal.java @@ -0,0 +1,22 @@ +package cn.bootx.platform.daxpay.service.common.context; + +import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.PayReconcileDetail; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +/** + * 支付对账上下文信息 + * @author xxm + * @since 2024/1/21 + */ +@Data +@Accessors(chain = true) +public class ReconcileLocal { + + /** */ + private List reconcileDetails; + + +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/local/PaymentContextLocal.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/local/PaymentContextLocal.java index 764434308..837b48ebb 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/local/PaymentContextLocal.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/common/local/PaymentContextLocal.java @@ -23,6 +23,18 @@ public final class PaymentContextLocal { THREAD_LOCAL.set(paymentContext); } + /** + * 不存在则进行赋值 + */ + public static boolean setIfAbsent(PaymentContext paymentContext){ + if (THREAD_LOCAL.get() == null){ + set(paymentContext); + return true; + } + return false; + } + + /** * 获取 */ diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/dao/AliReconcileBillDetailManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/dao/AliReconcileBillDetailManager.java new file mode 100644 index 000000000..f7a587508 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/dao/AliReconcileBillDetailManager.java @@ -0,0 +1,18 @@ +package cn.bootx.platform.daxpay.service.core.channel.alipay.dao; + +import cn.bootx.platform.common.mybatisplus.impl.BaseManager; +import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliReconcileBillDetail; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Repository; + +/** + * + * @author xxm + * @since 2024/1/21 + */ +@Slf4j +@Repository +@RequiredArgsConstructor +public class AliReconcileBillDetailManager extends BaseManager { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/dao/AliReconcileBillDetailMapper.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/dao/AliReconcileBillDetailMapper.java new file mode 100644 index 000000000..919efbb68 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/dao/AliReconcileBillDetailMapper.java @@ -0,0 +1,14 @@ +package cn.bootx.platform.daxpay.service.core.channel.alipay.dao; + +import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliReconcileBillDetail; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * + * @author xxm + * @since 2024/1/21 + */ +@Mapper +public interface AliReconcileBillDetailMapper extends BaseMapper { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/dao/AliReconcileBillTotalManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/dao/AliReconcileBillTotalManager.java new file mode 100644 index 000000000..e2d19f2e5 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/dao/AliReconcileBillTotalManager.java @@ -0,0 +1,18 @@ +package cn.bootx.platform.daxpay.service.core.channel.alipay.dao; + +import cn.bootx.platform.common.mybatisplus.impl.BaseManager; +import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliReconcileBillTotal; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Repository; + +/** + * + * @author xxm + * @since 2024/1/21 + */ +@Slf4j +@Repository +@RequiredArgsConstructor +public class AliReconcileBillTotalManager extends BaseManager { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/dao/AliReconcileBillTotalMapper.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/dao/AliReconcileBillTotalMapper.java new file mode 100644 index 000000000..ef7cb4354 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/dao/AliReconcileBillTotalMapper.java @@ -0,0 +1,14 @@ +package cn.bootx.platform.daxpay.service.core.channel.alipay.dao; + +import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliReconcileBillTotal; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * + * @author xxm + * @since 2024/1/21 + */ +@Mapper +public interface AliReconcileBillTotalMapper extends BaseMapper { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/entity/AliReconcileBillDetail.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/entity/AliReconcileBillDetail.java index f05f75d1d..d3fdce8a2 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/entity/AliReconcileBillDetail.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/entity/AliReconcileBillDetail.java @@ -1,61 +1,96 @@ package cn.bootx.platform.daxpay.service.core.channel.alipay.entity; +import cn.bootx.platform.common.mybatisplus.base.MpIdEntity; +import cn.bootx.table.modify.annotation.DbColumn; +import cn.bootx.table.modify.annotation.DbTable; import cn.hutool.core.annotation.Alias; +import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; +import lombok.EqualsAndHashCode; /** * 支付宝业务明细对账单 * @author xxm * @since 2024/1/18 */ +@EqualsAndHashCode(callSuper = true) @Data -public class AliReconcileBillDetail { +@DbTable(comment = "支付宝业务明细对账单") +@TableName("pay_ali_reconcile_bill_detail") +public class AliReconcileBillDetail extends MpIdEntity { + /** 关联对账订单ID */ + @DbColumn(comment = "关联对账订单ID") + private Long recordOrderId; @Alias("支付宝交易号") + @DbColumn(comment = "支付宝交易号") private String tradeNo; @Alias("商户订单号") + @DbColumn(comment = "商户订单号") private String outTradeNo; @Alias("业务类型") + @DbColumn(comment = "业务类型") private String tradeType; @Alias("商品名称") + @DbColumn(comment = "商品名称") private String subject; @Alias("完成时间") + @DbColumn(comment = "完成时间") private String endTime; @Alias("门店编号") + @DbColumn(comment = "门店编号") private String storeId; @Alias("门店名称") + @DbColumn(comment = "门店名称") private String storeName; @Alias("操作员") + @DbColumn(comment = "操作员") private String operator; @Alias("终端号") + @DbColumn(comment = "终端号") private String terminalId; @Alias("对方账户") + @DbColumn(comment = "对方账户") private String otherAccount; @Alias("订单金额(元)") + @DbColumn(comment = "订单金额(元)") private String orderAmount; @Alias("商家实收(元)") + @DbColumn(comment = "商家实收(元)") private String realAmount; @Alias("支付宝红包(元)") + @DbColumn(comment = "支付宝红包(元)") private String alipayAmount; @Alias("集分宝(元)") + @DbColumn(comment = "集分宝(元)") private String jfbAmount; @Alias("支付宝优惠(元)") + @DbColumn(comment = "支付宝优惠(元)") private String alipayDiscountAmount; @Alias("商家优惠(元)") + @DbColumn(comment = "商家优惠(元)") private String discountAmount; @Alias("券核销金额(元)") + @DbColumn(comment = "券核销金额(元)") private String couponDiscountAmount; @Alias("券名称") + @DbColumn(comment = "券名称") private String couponName; @Alias("商家红包消费金额(元)") + @DbColumn(comment = "商家红包消费金额(元)") private String couponAmount; @Alias("卡消费金额(元)") + @DbColumn(comment = "卡消费金额(元)") private String cardAmount; @Alias("退款批次号/请求号") + @DbColumn(comment = "退款批次号/请求号") private String batchNo; @Alias("服务费(元)") + @DbColumn(comment = "服务费(元)") private String serviceAmount; @Alias("分润(元)") + @DbColumn(comment = "分润(元)") private String splitAmount; @Alias("备注") + @DbColumn(comment = "备注") private String remark; } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/entity/AliReconcileBillTotal.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/entity/AliReconcileBillTotal.java index bcbf76efa..71e4f1c6b 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/entity/AliReconcileBillTotal.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/entity/AliReconcileBillTotal.java @@ -1,5 +1,6 @@ package cn.bootx.platform.daxpay.service.core.channel.alipay.entity; +import cn.bootx.table.modify.annotation.DbColumn; import cn.hutool.core.annotation.Alias; import lombok.Data; @@ -10,29 +11,44 @@ import lombok.Data; */ @Data public class AliReconcileBillTotal { + /** 关联对账订单ID */ + @DbColumn(comment = "关联对账订单ID") + private Long recordOrderId; @Alias("门店编号") + @DbColumn(comment = "门店编号") private String storeId; @Alias("门店名称") + @DbColumn(comment = "门店名称") private String storeName; @Alias("交易订单总笔数") + @DbColumn(comment = "交易订单总笔数") private String totalNum; @Alias("退款订单总笔数") + @DbColumn(comment = "退款订单总笔数") private String totalRefundNum; @Alias("订单金额(元)") + @DbColumn(comment = "订单金额(元)") private String totalOrderAmount; @Alias("商家实收(元)") + @DbColumn(comment = "商家实收(元)") private String totalAmount; @Alias("支付宝优惠(元)") + @DbColumn(comment = "支付宝优惠(元)") private String totalDiscountAmount; @Alias("商家优惠(元)") + @DbColumn(comment = "商家优惠(元)") private String totalCouponAmount; // 卡消费金额(元) 服务费(元) 分润(元) 实收净额(元) @Alias("卡消费金额(元)") + @DbColumn(comment = "卡消费金额(元)") private String totalConsumeAmount; @Alias("服务费(元)") + @DbColumn(comment = "服务费(元)") private String totalServiceAmount; @Alias("分润(元)") + @DbColumn(comment = "分润(元)") private String totalShareAmount; @Alias("实收净额(元)") + @DbColumn(comment = "实收净额(元)") private String totalNetAmount; } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayReconcileService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayReconcileService.java index b7d447809..7e6e4baa6 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayReconcileService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/alipay/service/AliPayReconcileService.java @@ -2,9 +2,13 @@ package cn.bootx.platform.daxpay.service.core.channel.alipay.service; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; import cn.bootx.platform.daxpay.service.code.AliPayCode; +import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; +import cn.bootx.platform.daxpay.service.core.channel.alipay.dao.AliReconcileBillDetailManager; +import cn.bootx.platform.daxpay.service.core.channel.alipay.dao.AliReconcileBillTotalManager; +import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliPayConfig; import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliReconcileBillDetail; import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliReconcileBillTotal; -import cn.bootx.platform.daxpay.service.core.channel.alipay.entity.AliPayConfig; +import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.PayReconcileDetail; import cn.hutool.core.io.IoUtil; import cn.hutool.core.text.csv.CsvReader; import cn.hutool.core.text.csv.CsvUtil; @@ -20,6 +24,7 @@ import lombok.val; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.io.BufferedReader; import java.io.ByteArrayInputStream; @@ -40,12 +45,19 @@ import java.util.stream.Collectors; public class AliPayReconcileService { private final AliPayConfigService configService; + private final AliReconcileBillDetailManager reconcileBillDetailManager; + + private final AliReconcileBillTotalManager reconcileBillTotalManager; + /** * 下载对账单, 并进行解析进行保存 + * * @param date 对账日期 yyyy-MM-dd 格式 + * @param recordOrderId 对账订单ID */ @SneakyThrows - public void downAndSave(String date){ + @Transactional(rollbackFor = Exception.class) + public void downAndSave(String date, Long recordOrderId){ AliPayConfig config = configService.getConfig(); configService.initConfig(config); @@ -63,29 +75,73 @@ public class AliPayReconcileService { // 获取对账单下载地址并下载 String url = response.getBillDownloadUrl(); byte[] bytes = HttpUtil.downloadBytes(url); - // 使用 Apache commons-compress 包装流, + // 使用 Apache commons-compress 包装流, 读取返回的对账CSV文件 ZipArchiveInputStream zipArchiveInputStream = new ZipArchiveInputStream(new ByteArrayInputStream(bytes),"GBK"); ZipArchiveEntry entry; - List billDetails; - List billTotals; + List billDetails = new ArrayList<>(); + List billTotals = new ArrayList<>(); while ((entry= zipArchiveInputStream.getNextZipEntry()) != null){ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(zipArchiveInputStream,"GBK")); List strings = IoUtil.readLines(bufferedReader, new ArrayList<>()); String name = entry.getName(); if (StrUtil.endWith(name,"_业务明细(汇总).csv")){ + // 汇总 billTotals = this.parseTotal(strings); } else { + // 明细 billDetails = this.parseDetail(strings); } } - // 保存 - System.out.println(); + // 保存原始对账记录 + this.save(billDetails, billTotals, recordOrderId); + + // 将原始交易明细对账记录转换通用结构并保存到上下文中 + this.convertAndSave(billDetails); + } catch (AlipayApiException e) { log.error("下载对账单失败",e); throw new RuntimeException(e); } } + /** + * 保存原始对账记录 + */ + private void save(List billDetails, List billTotals, Long recordOrderId){ + billDetails.forEach(o->o.setRecordOrderId(recordOrderId)); + reconcileBillDetailManager.saveAll(billDetails); + billTotals.forEach(o->o.setRecordOrderId(recordOrderId)); + reconcileBillTotalManager.saveAll(billTotals); + } + + /** + * 转换为通用对账记录对象 + */ + private void convertAndSave(List billDetails){ + List collect = billDetails.stream() + .map(this::convert) + .collect(Collectors.toList()); + // 写入到上下文中 + PaymentContextLocal.get().getReconcile().setReconcileDetails(collect); + } + + /** + * 转换为通用对账记录对象 + */ + private PayReconcileDetail convert(AliReconcileBillDetail billDetail){ + // 默认为支付 + PayReconcileDetail payReconcileDetail = new PayReconcileDetail() + .setRecordOrderId(billDetail.getRecordOrderId()) + .setOrderId(billDetail.getOutTradeNo()) + .setTitle(billDetail.getSubject()) + .setGatewayOrderNo(billDetail.getTradeNo()); + // 如果是退款 + if (Objects.equals(billDetail.getTradeType(), "refund")){ + } + return payReconcileDetail; + } + + /** * 解析明细 */ diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/dao/WxReconcileFundFlowDetailManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/dao/WxReconcileFundFlowDetailManager.java new file mode 100644 index 000000000..02ab628c9 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/dao/WxReconcileFundFlowDetailManager.java @@ -0,0 +1,18 @@ +package cn.bootx.platform.daxpay.service.core.channel.wechat.dao; + +import cn.bootx.platform.common.mybatisplus.impl.BaseManager; +import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WxReconcileFundFlowDetail; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Repository; + +/** + * + * @author xxm + * @since 2024/1/21 + */ +@Slf4j +@Repository +@RequiredArgsConstructor +public class WxReconcileFundFlowDetailManager extends BaseManager { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/dao/WxReconcileFundFlowDetailMapper.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/dao/WxReconcileFundFlowDetailMapper.java new file mode 100644 index 000000000..0192d39ef --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/dao/WxReconcileFundFlowDetailMapper.java @@ -0,0 +1,14 @@ +package cn.bootx.platform.daxpay.service.core.channel.wechat.dao; + +import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WxReconcileFundFlowDetail; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * + * @author xxm + * @since 2024/1/21 + */ +@Mapper +public interface WxReconcileFundFlowDetailMapper extends BaseMapper { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/dao/WxReconcileFundFlowTotalManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/dao/WxReconcileFundFlowTotalManager.java new file mode 100644 index 000000000..217096262 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/dao/WxReconcileFundFlowTotalManager.java @@ -0,0 +1,18 @@ +package cn.bootx.platform.daxpay.service.core.channel.wechat.dao; + +import cn.bootx.platform.common.mybatisplus.impl.BaseManager; +import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WxReconcileFundFlowTotal; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Repository; + +/** + * + * @author xxm + * @since 2024/1/21 + */ +@Slf4j +@Repository +@RequiredArgsConstructor +public class WxReconcileFundFlowTotalManager extends BaseManager { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/dao/WxReconcileFundFlowTotalMapper.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/dao/WxReconcileFundFlowTotalMapper.java new file mode 100644 index 000000000..e97363b0c --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/dao/WxReconcileFundFlowTotalMapper.java @@ -0,0 +1,14 @@ +package cn.bootx.platform.daxpay.service.core.channel.wechat.dao; + +import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WxReconcileFundFlowTotal; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +/** + * + * @author xxm + * @since 2024/1/21 + */ +@Mapper +public interface WxReconcileFundFlowTotalMapper extends BaseMapper { +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WxReconcileBillDetail.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WxReconcileBillDetail.java index a54c761f2..01fbebc3d 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WxReconcileBillDetail.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WxReconcileBillDetail.java @@ -1,6 +1,7 @@ package cn.bootx.platform.daxpay.service.core.channel.wechat.entity; import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity; +import cn.bootx.table.modify.annotation.DbColumn; import cn.hutool.core.annotation.Alias; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @@ -15,86 +16,117 @@ import lombok.EqualsAndHashCode; @Data @TableName("pay_wechat_reconcile_bill_detail") public class WxReconcileBillDetail extends MpCreateEntity { + + @DbColumn(comment = "关联对账订单ID") + private Long recordOrderId; + @Alias("交易时间") + @DbColumn(comment = "交易时间") private String transactionTime; @Alias("公众账号ID") + @DbColumn(comment = "公众账号ID") private String appId; @Alias("商户号") + @DbColumn(comment = "商户号") private String merchantId; @Alias("特约商户号") + @DbColumn(comment = "特约商户号") private String subMerchantId; @Alias("微信订单号") + @DbColumn(comment = "微信订单号") private String weiXinOrderNo; @Alias("商户订单号") + @DbColumn(comment = "商户订单号") private String mchOrderNo; @Alias("用户标识") + @DbColumn(comment = "用户标识") private String userId; @Alias("设备号") + @DbColumn(comment = "设备号") private String deviceInfo; @Alias("交易类型") + @DbColumn(comment = "交易类型") private String type; @Alias("交易状态") + @DbColumn(comment = "交易状态") private String status; @Alias("付款银行") + @DbColumn(comment = "付款银行") private String bank; @Alias("货币种类") + @DbColumn(comment = "货币种类") private String currency; @Alias("应结订单金额") + @DbColumn(comment = "应结订单金额") private String amount; @Alias("代金券金额") + @DbColumn(comment = "代金券金额") private String envelopeAmount; @Alias("微信退款单号") + @DbColumn(comment = "微信退款单号") private String name; @Alias("商户退款单号") + @DbColumn(comment = "商户退款单号") private String packet; @Alias("退款金额") + @DbColumn(comment = "退款金额") private String poundage; @Alias("充值券退款金额") + @DbColumn(comment = "充值券退款金额") private String amount2; @Alias("退款类型") + @DbColumn(comment = "退款类型") private String rate; @Alias("退款状态") + @DbColumn(comment = "退款状态") private String orderAmount; @Alias("商品名称") + @DbColumn(comment = "商品名称") private String packet2; @Alias("商户数据包") + @DbColumn(comment = "商户数据包") private String packet3; @Alias("手续费") + @DbColumn(comment = "手续费") private String packet4; @Alias("费率") + @DbColumn(comment = "费率") private String packet5; @Alias("订单金额") + @DbColumn(comment = "订单金额") private String packet6; @Alias("申请退款金额") + @DbColumn(comment = "申请退款金额") private String packet7; @Alias("费率备注") + @DbColumn(comment = "费率备注") private String packet8; } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WxReconcileBillTotal.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WxReconcileBillTotal.java index 805cb5d09..e6c37a88e 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WxReconcileBillTotal.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WxReconcileBillTotal.java @@ -1,6 +1,7 @@ package cn.bootx.platform.daxpay.service.core.channel.wechat.entity; import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity; +import cn.bootx.table.modify.annotation.DbColumn; import cn.hutool.core.annotation.Alias; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @@ -16,25 +17,35 @@ import lombok.EqualsAndHashCode; @TableName("pay_wechat_reconcile_bill_total") public class WxReconcileBillTotal extends MpCreateEntity { + @DbColumn(comment = "关联对账订单ID") + private Long recordOrderId; + @Alias("总交易单数") + @DbColumn(comment = "总交易单数") private String totalNum; @Alias("应结订单总金额") + @DbColumn(comment = "应结订单总金额") private String totalAmount; @Alias("退款总金额") + @DbColumn(comment = "退款总金额") private String totalRefundAmount; @Alias("充值券退款总金额") + @DbColumn(comment = "充值券退款总金额") private String totalRefundCouponAmount; @Alias("手续费总金额") + @DbColumn(comment = "手续费总金额") private String totalFee; @Alias("订单总金额") + @DbColumn(comment = "订单总金额") private String totalOrderAmount; @Alias("申请退款总金额") + @DbColumn(comment = "申请退款总金额") private String applyTotalRefundAmount; } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WxReconcileFundFlowDetail.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WxReconcileFundFlowDetail.java index 837b4f9d5..ee70be531 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WxReconcileFundFlowDetail.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WxReconcileFundFlowDetail.java @@ -1,6 +1,7 @@ package cn.bootx.platform.daxpay.service.core.channel.wechat.entity; import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity; +import cn.bootx.table.modify.annotation.DbColumn; import cn.hutool.core.annotation.Alias; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @@ -15,26 +16,40 @@ import lombok.EqualsAndHashCode; @Data @TableName("pay_wechat_reconcile_fund_flow_detail") public class WxReconcileFundFlowDetail extends MpCreateEntity { + + @DbColumn(comment = "关联对账订单ID") + private Long recordOrderId; @Alias("记账时间") + @DbColumn(comment = "记账时间") private String time; @Alias("微信支付业务单号") + @DbColumn(comment = "微信支付业务单号") private String outTradeNo; @Alias("资金流水单号") - private String id; + @DbColumn(comment = "资金流水单号") + private String flowId; @Alias("业务名称") + @DbColumn(comment = "业务名称") private String packet1; @Alias("业务类型") + @DbColumn(comment = "业务类型") private String packet2; @Alias("收支类型") + @DbColumn(comment = "收支类型") private String packet3; @Alias("收支金额(元)") + @DbColumn(comment = "收支金额(元)") private String amount; @Alias("账户结余(元)") + @DbColumn(comment = "账户结余(元)") private String balance; @Alias("资金变更提交申请人") + @DbColumn(comment = "资金变更提交申请人") private String packet4; @Alias("备注") + @DbColumn(comment = "备注") private String packet5; @Alias("业务凭证号") + @DbColumn(comment = "业务凭证号") private String packet6; } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WxReconcileFundFlowTotal.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WxReconcileFundFlowTotal.java index 90941d5f8..8eea0ca0a 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WxReconcileFundFlowTotal.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/entity/WxReconcileFundFlowTotal.java @@ -1,6 +1,7 @@ package cn.bootx.platform.daxpay.service.core.channel.wechat.entity; import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity; +import cn.bootx.table.modify.annotation.DbColumn; import cn.hutool.core.annotation.Alias; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @@ -16,14 +17,21 @@ import lombok.EqualsAndHashCode; @TableName("pay_wechat_reconcile_fund_flow_total") public class WxReconcileFundFlowTotal extends MpCreateEntity { + @DbColumn(comment = "关联对账订单ID") + private Long recordOrderId; @Alias("资金流水总笔数") + @DbColumn(comment = "资金流水总笔数") private String totalNum; @Alias("收入笔数") + @DbColumn(comment = "收入笔数") private String incomeNum; @Alias("收入金额") + @DbColumn(comment = "收入金额") private String incomeAmount; @Alias("支出笔数") + @DbColumn(comment = "支出笔数") private String expenditureNum; @Alias("支出金额") + @DbColumn(comment = "支出金额") private String expenditureAmount; } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WechatPayReconcileService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WechatPayReconcileService.java index ace236288..300d01cf0 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WechatPayReconcileService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/wechat/service/WechatPayReconcileService.java @@ -2,12 +2,14 @@ package cn.bootx.platform.daxpay.service.core.channel.wechat.service; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; import cn.bootx.platform.daxpay.service.code.WeChatPayCode; +import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; import cn.bootx.platform.daxpay.service.core.channel.wechat.dao.WxReconcileBillDetailManager; import cn.bootx.platform.daxpay.service.core.channel.wechat.dao.WxReconcileBillTotalManger; import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WeChatPayConfig; import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WxReconcileBillDetail; import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WxReconcileBillTotal; import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WxReconcileFundFlowDetail; +import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.PayReconcileDetail; import cn.hutool.core.codec.Base64; import cn.hutool.core.text.csv.CsvReader; import cn.hutool.core.text.csv.CsvUtil; @@ -20,11 +22,13 @@ import com.ijpay.wxpay.model.DownloadFundFlowModel; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.io.ByteArrayInputStream; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; import static cn.bootx.platform.daxpay.service.code.WeChatPayCode.ACCOUNT_TYPE_BASIC; @@ -37,7 +41,6 @@ import static cn.bootx.platform.daxpay.service.code.WeChatPayCode.ACCOUNT_TYPE_B @Service @RequiredArgsConstructor public class WechatPayReconcileService{ - private final WeChatPayConfigService weChatPayConfigService; private final WxReconcileBillTotalManger reconcileBillTotalManger; private final WxReconcileBillDetailManager reconcileBillDetailManager; @@ -45,17 +48,20 @@ public class WechatPayReconcileService{ * 下载对账单并保存 * @param date 对账日期 yyyyMMdd 格式 */ - public void downAndSave(String date, WeChatPayConfig config) { - config = weChatPayConfigService.getConfig(); - this.downBill(date, config); - this.downFundFlow(date, config); + @Transactional(rollbackFor = Exception.class) + public void downAndSave(String date, Long recordOrderId, WeChatPayConfig config) { + this.downBill(date, recordOrderId, config); + // 资金对账单先不启用 +// this.downFundFlow(date, recordOrderId, config); } /** * 下载交易账单 - * @param date 对账日期 yyyyMMdd 格式 + * + * @param date 对账日期 yyyyMMdd 格式 + * @param recordOrderId 对账订单ID */ - public void downBill(String date, WeChatPayConfig config){ + public void downBill(String date, Long recordOrderId, WeChatPayConfig config){ // 下载交易账单 Map params = DownloadBillModel.builder() .mch_id(config.getWxMchId()) @@ -74,14 +80,41 @@ public class WechatPayReconcileService{ result = result.replaceAll("`", "").replaceAll("\uFEFF", ""); CsvReader reader = CsvUtil.getReader(); - // 获取交易记录 + // 获取交易记录并保存 String billDetail = StrUtil.subBefore(result, "总交易单数", false); List billDetails = reader.read(billDetail, WxReconcileBillDetail.class); + billDetails.forEach(o->o.setRecordOrderId(recordOrderId)); + reconcileBillDetailManager.saveAll(billDetails); - // 获取汇总数据 + // 获取汇总数据并保存 String billTotal = result.substring(result.indexOf("总交易单数")); List billTotals = reader.read(billTotal, WxReconcileBillTotal.class); + billTotals.forEach(o->o.setRecordOrderId(recordOrderId)); + reconcileBillTotalManger.saveAll(billTotals); + // 将原始交易明细对账记录转换通用结构并保存到上下文中 + this.convertAndSave(billDetails); + + } + + /** + * 转换为通用对账记录对象 + */ + public void convertAndSave(List billDetails){ + List collect = billDetails.stream() + .map(this::convert) + .collect(Collectors.toList()); + // 写入到上下文中 + PaymentContextLocal.get().getReconcile().setReconcileDetails(collect); + } + + /** + * 转换为通用对账记录对象 + */ + public PayReconcileDetail convert(WxReconcileBillDetail billDetail){ + PayReconcileDetail payReconcileDetail = new PayReconcileDetail() + .setRecordOrderId(billDetail.getRecordOrderId()); + return payReconcileDetail; } @@ -90,9 +123,10 @@ public class WechatPayReconcileService{ * 如果出现 No appropriate protocol (protocol is disabled or cipher suites are inappropriate) * 更换一下最新的JDK即可, 例如 corretto Jdk * - * @param date 对账日期 yyyyMMdd 格式 + * @param date 对账日期 yyyyMMdd 格式 + * @param recordOrderId 对账订单ID */ - public void downFundFlow(String date, WeChatPayConfig config){ + public void downFundFlow(String date, Long recordOrderId, WeChatPayConfig config){ if (StrUtil.isBlank(config.getP12())){ return; } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/entity/PayReconcileDetail.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/entity/PayReconcileDetail.java index 882fbbe97..960b5f4b6 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/entity/PayReconcileDetail.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/entity/PayReconcileDetail.java @@ -1,44 +1,52 @@ package cn.bootx.platform.daxpay.service.core.order.reconcile.entity; import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity; +import cn.bootx.table.modify.annotation.DbColumn; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; /** - * 支付对账记录详情 + * 通用支付对账记录 * @author xxm * @since 2024/1/18 */ @EqualsAndHashCode(callSuper = true) @Data @Accessors(chain = true) -@TableName("pay_reconcile_detail_record") +@TableName("pay_reconcile_detail") public class PayReconcileDetail extends MpCreateEntity { - /** 交易状态 */ + /** 关联对账订单ID */ + @DbColumn(comment = "关联对账订单ID") + private Long recordOrderId; + + /** + * 交易状态 + * @see cn.bootx.platform.daxpay.code.PayStatusEnum + */ + @DbColumn(comment = "交易状态") private String status; /** 交易类型 支付/退款 */ + @DbColumn(comment = "交易类型") private String type; - /** 订单号 - 支付ID/退款ID */ - private String paymentId; + /** 订单id - 支付ID/退款ID等 */ + @DbColumn(comment = "订单id") + private String orderId; /** 网关订单号 - 支付宝/微信的订单号 */ + @DbColumn(comment = "网关订单号") private String gatewayOrderNo; /** 交易金额 */ + @DbColumn(comment = "交易金额") private Integer amount; - /** 手续费 */ - private Integer poundage; - - /** 费率 */ - private Integer rate; - /** 商品名称 */ + @DbColumn(comment = "商品名称") private String title; } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/entity/PayReconcileOrder.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/entity/PayReconcileOrder.java index d9cbc02dd..a4b76b2be 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/entity/PayReconcileOrder.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/entity/PayReconcileOrder.java @@ -1,6 +1,7 @@ package cn.bootx.platform.daxpay.service.core.order.reconcile.entity; import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity; +import cn.bootx.table.modify.annotation.DbColumn; import cn.bootx.table.modify.annotation.DbTable; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @@ -10,15 +11,15 @@ import lombok.experimental.Accessors; import java.time.LocalDate; /** - * 支付对账单记录 + * 支付对账单订单 * @author xxm * @since 2024/1/18 */ @EqualsAndHashCode(callSuper = true) @Data @Accessors(chain = true) -@DbTable(comment = "支付对账单记录") -@TableName("pay_reconcile_record") +@DbTable(comment = "支付对账单订单") +@TableName("pay_reconcile_order") public class PayReconcileOrder extends MpCreateEntity { /** @@ -26,21 +27,27 @@ public class PayReconcileOrder extends MpCreateEntity { * 规则:通道简称 + yyyyMMdd + 两位流水号 * 例子:wx2024012001、ali2024012002 */ + @DbColumn(comment = "批次号") private String batchNo; /** 日期 */ + @DbColumn(comment = "日期") private LocalDate date; /** 通道 */ + @DbColumn(comment = "通道") private String channel; - /** 对账单是否下载成功 */ + /** 是否下载成功 */ + @DbColumn(comment = "是否下载成功") private boolean down; /** 是否比对完成 */ + @DbColumn(comment = "是否比对完成") private boolean compare; /** 错误信息 */ + @DbColumn(comment = "错误信息") private String errorMsg; } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/service/PayReconcileOrderQueryService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/service/PayReconcileOrderQueryService.java new file mode 100644 index 000000000..bbaf5efc1 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/service/PayReconcileOrderQueryService.java @@ -0,0 +1,51 @@ +package cn.bootx.platform.daxpay.service.core.order.reconcile.service; + +import cn.bootx.platform.common.core.rest.PageResult; +import cn.bootx.platform.common.core.rest.param.PageParam; +import cn.bootx.platform.daxpay.service.core.order.reconcile.dao.PayReconcileDetailManager; +import cn.bootx.platform.daxpay.service.core.order.reconcile.dao.PayReconcileOrderManager; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** + * 支付对账订单查询服务类 + * @author xxm + * @since 2024/1/21 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class PayReconcileOrderQueryService { + private final PayReconcileOrderManager orderManager; + private final PayReconcileDetailManager detailManager; + + /** + * 分页 + */ + public PageResult page(PageParam pageParam){ + return null; + } + + /** + * 对账订单详情 + */ + public void findById(Long id){ + + } + + /** + * 明细分页 + */ + public PageResult pageDetail(PageParam pageParam, Long orderId){ + return null; + } + + /** + * 明细详情 + */ + public void findDetailById(Long id){ + + } + +} 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 index 0bcd69857..08950d550 100644 --- 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 @@ -28,7 +28,6 @@ public class PayReconcileOrderService { private final PayReconcileOrderManager reconcileOrderManager; private final Sequence sequence; - /** * 更新, 开启一个新事务进行更新 */ 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 c64633d0e..7dcb93487 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,6 +1,10 @@ package cn.bootx.platform.daxpay.service.core.payment.reconcile.service; import cn.bootx.platform.common.core.exception.DataNotExistException; +import cn.bootx.platform.daxpay.service.common.context.PaymentContext; +import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; +import cn.bootx.platform.daxpay.service.core.order.reconcile.dao.PayReconcileDetailManager; +import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.PayReconcileDetail; 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; @@ -9,6 +13,8 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import java.util.List; + /** * 支付对账单下载服务 * @author xxm @@ -19,6 +25,7 @@ import org.springframework.stereotype.Service; @RequiredArgsConstructor public class PayReconcileService { private final PayReconcileOrderService reconcileOrderService; + private final PayReconcileDetailManager reconcileDetailManager; /** * 下载对账单并进行保存 @@ -33,6 +40,9 @@ public class PayReconcileService { * 下载对账单并进行保存 */ public void downAndSave(PayReconcileOrder recordOrder) { + // 初始化上下文 + PaymentContextLocal.setIfAbsent(new PaymentContext()); + // 构建对账策略 AbsReconcileStrategy absReconcileStrategy = PayReconcileStrategyFactory.create(recordOrder.getChannel()); absReconcileStrategy.initParam(recordOrder); absReconcileStrategy.doBeforeHandler(); @@ -46,6 +56,11 @@ public class PayReconcileService { reconcileOrderService.update(recordOrder); throw new RuntimeException(e); } + // 保存转换后的通用结构对账单 + List reconcileDetails = PaymentContextLocal.get() + .getReconcile() + .getReconcileDetails(); + reconcileDetailManager.saveAll(reconcileDetails); } } 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 e7a90269a..3bde33e30 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 @@ -52,11 +52,11 @@ public class AlipayReconcileStrategy extends AbsReconcileStrategy { } /** - * 下载对账单 + * 下载和保存对账单 */ @Override public void downAndSave() { - String format = LocalDateTimeUtil.format(this.getRecordOrder().getDate(), DatePattern.NORM_DATE_PATTERN); - reconcileService.downAndSave(format); + String date = LocalDateTimeUtil.format(this.getRecordOrder().getDate(), DatePattern.NORM_DATE_PATTERN); + reconcileService.downAndSave(date,this.getRecordOrder().getId()); } } 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 3d9be1b06..d591f3898 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 @@ -55,6 +55,6 @@ public class WechatPayReconcileStrategy extends AbsReconcileStrategy { @Override public void downAndSave() { String format = LocalDateTimeUtil.format(this.getRecordOrder().getDate(), DatePattern.PURE_DATE_PATTERN); - reconcileService.downAndSave(format,this.config); + reconcileService.downAndSave(format,this.getRecordOrder().getId(), this.config); } }