diff --git a/_doc/Task.md b/_doc/Task.md index e32f6c4d..cd64a7e5 100644 --- a/_doc/Task.md +++ b/_doc/Task.md @@ -61,9 +61,9 @@ - [x] 优化支付相关订单和记录的查询条件 - [x] 开放接口新增查询类接口 - 2024-01-16: - - [x] 支付单涉及退款状态同步逻辑 + - [x] 支付单涉及退款状态同步逻辑 - 2024-01-17: - - [x] 支付宝和微信支付对账下载接口 + - [x] 支付宝和微信支付对账下载接口 - 2024-01-21: - [x] (对账) 微信对账文件解析 - [x] (对账) 支付宝对账文件解析 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 index 5730d455..2021ff80 100644 --- 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 @@ -1,11 +1,18 @@ package cn.bootx.platform.daxpay.admin.controller.record; +import cn.bootx.platform.common.core.rest.PageResult; import cn.bootx.platform.common.core.rest.Res; import cn.bootx.platform.common.core.rest.ResResult; +import cn.bootx.platform.common.core.rest.param.PageParam; 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.order.reconcile.service.PayReconcileQueryService; import cn.bootx.platform.daxpay.service.core.payment.reconcile.service.PayReconcileService; -import cn.bootx.platform.daxpay.service.param.reconcile.CreateReconcileOrderParam; +import cn.bootx.platform.daxpay.service.dto.order.reconcile.PayReconcileDetailDto; +import cn.bootx.platform.daxpay.service.dto.order.reconcile.PayReconcileOrderDto; +import cn.bootx.platform.daxpay.service.param.reconcile.ReconcileDetailQuery; +import cn.bootx.platform.daxpay.service.param.reconcile.ReconcileOrderCreate; +import cn.bootx.platform.daxpay.service.param.reconcile.ReconcileOrderQuery; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; @@ -18,24 +25,49 @@ import org.springframework.web.bind.annotation.*; */ @Tag(name = "支付对账控制器") @RestController -@RequestMapping("/record/reconcile") +@RequestMapping("/order/reconcile") @RequiredArgsConstructor public class PayReconcileOrderController { private final PayReconcileService reconcileService; private final PayReconcileOrderService reconcileOrderService; + private final PayReconcileQueryService reconcileQueryService; @Operation(summary = "手动创建支付对账订单") - @PostMapping("/createOrder") - public ResResult createOrder(@RequestBody CreateReconcileOrderParam param){ + @PostMapping("/create") + public ResResult create(@RequestBody ReconcileOrderCreate param){ ValidationUtil.validateParam(param); reconcileOrderService.create(param.getDate(), param.getChannel()); return Res.ok(); } @Operation(summary = "手动触发对账文件下载") - @PostMapping("/downById") - public ResResult downByChannel(Long id){ + @PostMapping("/downAndSave") + public ResResult downAndSave(Long id){ reconcileService.downAndSave(id); return Res.ok(); } + + @Operation(summary = "订单分页") + @GetMapping("/page") + public ResResult> page(PageParam pageParam, ReconcileOrderQuery query){ + return Res.ok(reconcileQueryService.page(pageParam, query)); + } + + @Operation(summary = "订单详情") + @GetMapping("/findById") + public ResResult findById(Long id){ + return Res.ok(reconcileQueryService.findById(id)); + } + + @Operation(summary = "对账明细分页") + @GetMapping("/pageDetail") + public ResResult> pageDetail(PageParam pageParam, ReconcileDetailQuery query){ + return Res.ok(reconcileQueryService.pageDetail(pageParam, query)); + } + + @Operation(summary = "对账明细详情") + @GetMapping("/findDetailById") + public ResResult findDetailById(Long id){ + return Res.ok(reconcileQueryService.findDetailById(id)); + } } 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 index 3432004b..56f0bc5c 100644 --- 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 @@ -15,7 +15,7 @@ import java.util.List; @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/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 d3fdce8a..dfc224a7 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 @@ -16,7 +16,7 @@ import lombok.EqualsAndHashCode; @EqualsAndHashCode(callSuper = true) @Data @DbTable(comment = "支付宝业务明细对账单") -@TableName("pay_ali_reconcile_bill_detail") +@TableName("pay_alipay_reconcile_bill_detail") public class AliReconcileBillDetail extends MpIdEntity { /** 关联对账订单ID */ @DbColumn(comment = "关联对账订单ID") @@ -33,6 +33,9 @@ public class AliReconcileBillDetail extends MpIdEntity { @Alias("商品名称") @DbColumn(comment = "商品名称") private String subject; + @Alias("创建时间") + @DbColumn(comment = "完成时间") + private String createTime; @Alias("完成时间") @DbColumn(comment = "完成时间") private String endTime; 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 71e4f1c6..e4f86116 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,16 +1,23 @@ 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/17 */ +@EqualsAndHashCode(callSuper = true) @Data -public class AliReconcileBillTotal { +@DbTable(comment = "支付宝业务汇总对账单") +@TableName("pay_alipay_reconcile_bill_total") +public class AliReconcileBillTotal extends MpIdEntity { /** 关联对账订单ID */ @DbColumn(comment = "关联对账订单ID") private Long recordOrderId; 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 7e6e4baa..90e2010a 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 @@ -129,15 +129,25 @@ public class AliPayReconcileService { * 转换为通用对账记录对象 */ private PayReconcileDetail convert(AliReconcileBillDetail billDetail){ - // 默认为支付 + // 金额 + String orderAmount = billDetail.getOrderAmount(); + double v = Double.parseDouble(orderAmount) * 100; + int amount = Math.abs(((int) v)); + + // 默认为支付对账记录 PayReconcileDetail payReconcileDetail = new PayReconcileDetail() .setRecordOrderId(billDetail.getRecordOrderId()) .setOrderId(billDetail.getOutTradeNo()) + .setType("pay") + .setAmount(amount) .setTitle(billDetail.getSubject()) .setGatewayOrderNo(billDetail.getTradeNo()); - // 如果是退款 - if (Objects.equals(billDetail.getTradeType(), "refund")){ + // 退款覆盖更新对应的字段 + if (Objects.equals(billDetail.getTradeType(), "退款")){ + payReconcileDetail.setOrderId(billDetail.getBatchNo()) + .setType("refund"); } + return payReconcileDetail; } @@ -146,14 +156,15 @@ public class AliPayReconcileService { * 解析明细 */ public List parseDetail(List list){ - // 去除前 4 行和后 2 行 然后合并是个一个字符串 - String billDetail = list.subList(4, list.size() - 2) - .stream() + // 截取需要进行解析的文本内容 + String billDetail = list.stream() .collect(Collectors.joining(System.lineSeparator())); + billDetail = StrUtil.subBetween(billDetail, + "#-----------------------------------------业务明细列表----------------------------------------"+System.lineSeparator(), + "#-----------------------------------------业务明细列表结束------------------------------------"); billDetail = billDetail.replaceAll("\t", ""); CsvReader reader = CsvUtil.getReader(); - List billDetails = reader.read(billDetail, AliReconcileBillDetail.class); - return billDetails; + return reader.read(billDetail, AliReconcileBillDetail.class); } /** @@ -161,13 +172,14 @@ public class AliPayReconcileService { */ public List parseTotal(List list){ // 去除前 4 行和后 2 行 然后合并是个一个字符串 - String billTotal = list.subList(4, list.size() - 2) - .stream() + String billTotal = list.stream() .collect(Collectors.joining(System.lineSeparator())); + billTotal = StrUtil.subBetween(billTotal, + "#-----------------------------------------业务汇总列表----------------------------------------"+System.lineSeparator(), + "#----------------------------------------业务汇总列表结束-------------------------------------"); + billTotal = billTotal.replaceAll("\t", ""); CsvReader reader = CsvUtil.getReader(); - List billTotals = reader.read(billTotal, AliReconcileBillTotal.class); - return billTotals; + return reader.read(billTotal, AliReconcileBillTotal.class); } - } 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 01fbebc3..21104dbd 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,7 +1,8 @@ package cn.bootx.platform.daxpay.service.core.channel.wechat.entity; -import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity; +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; @@ -14,8 +15,9 @@ import lombok.EqualsAndHashCode; */ @EqualsAndHashCode(callSuper = true) @Data +@DbTable(comment = "微信对账单明细") @TableName("pay_wechat_reconcile_bill_detail") -public class WxReconcileBillDetail extends MpCreateEntity { +public class WxReconcileBillDetail extends MpIdEntity { @DbColumn(comment = "关联对账订单ID") private Long recordOrderId; @@ -82,51 +84,51 @@ public class WxReconcileBillDetail extends MpCreateEntity { @Alias("商户退款单号") @DbColumn(comment = "商户退款单号") - private String packet; + private String mchRefundNo; @Alias("退款金额") @DbColumn(comment = "退款金额") - private String poundage; + private String refundAmount; @Alias("充值券退款金额") @DbColumn(comment = "充值券退款金额") - private String amount2; + private String couponRefundAmount; @Alias("退款类型") @DbColumn(comment = "退款类型") - private String rate; + private String refundType; @Alias("退款状态") @DbColumn(comment = "退款状态") - private String orderAmount; + private String refundStatus; @Alias("商品名称") @DbColumn(comment = "商品名称") - private String packet2; + private String subject; @Alias("商户数据包") @DbColumn(comment = "商户数据包") - private String packet3; + private String mchDataPacket; @Alias("手续费") @DbColumn(comment = "手续费") - private String packet4; + private String premium; @Alias("费率") @DbColumn(comment = "费率") - private String packet5; + private String rates; @Alias("订单金额") @DbColumn(comment = "订单金额") - private String packet6; + private String orderAmount; @Alias("申请退款金额") @DbColumn(comment = "申请退款金额") - private String packet7; + private String applyRefundAmount; @Alias("费率备注") @DbColumn(comment = "费率备注") - private String packet8; + private String ratesRemark; } 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 e6c37a88..5d33546c 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,7 +1,8 @@ package cn.bootx.platform.daxpay.service.core.channel.wechat.entity; -import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity; +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; @@ -14,8 +15,9 @@ import lombok.EqualsAndHashCode; */ @EqualsAndHashCode(callSuper = true) @Data +@DbTable(comment = "微信对账单汇总") @TableName("pay_wechat_reconcile_bill_total") -public class WxReconcileBillTotal extends MpCreateEntity { +public class WxReconcileBillTotal extends MpIdEntity { @DbColumn(comment = "关联对账订单ID") private Long recordOrderId; 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 300d01cf..2a8cb605 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 @@ -80,9 +80,11 @@ 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); + List billDetails = reader.read(billDetail, WxReconcileBillDetail.class).stream() + .filter(o->Objects.equals(o.getAppId(), config.getWxAppId())) + .collect(Collectors.toList()); billDetails.forEach(o->o.setRecordOrderId(recordOrderId)); reconcileBillDetailManager.saveAll(billDetails); @@ -112,8 +114,34 @@ public class WechatPayReconcileService{ * 转换为通用对账记录对象 */ public PayReconcileDetail convert(WxReconcileBillDetail billDetail){ + // 默认为支付对账记录 PayReconcileDetail payReconcileDetail = new PayReconcileDetail() - .setRecordOrderId(billDetail.getRecordOrderId()); + .setRecordOrderId(billDetail.getRecordOrderId()) + .setOrderId(billDetail.getMchOrderNo()) + .setTitle(billDetail.getSubject()) + .setGatewayOrderNo(billDetail.getWeiXinOrderNo()); + // 支付 + if (Objects.equals(billDetail.getStatus(), "SUCCESS")){ + // 金额 + String orderAmount = billDetail.getOrderAmount(); + double v = Double.parseDouble(orderAmount) * 100; + int amount = Math.abs(((int) v)); + payReconcileDetail.setType("pay") + .setAmount(amount); + } + // 退款 + if (Objects.equals(billDetail.getStatus(), "REFUND")){ + // 金额 + String refundAmount = billDetail.getApplyRefundAmount(); + double v = Double.parseDouble(refundAmount) * 100; + int amount = Math.abs(((int) v)); + payReconcileDetail.setType("refund") + .setAmount(amount); + } + // TODO 已撤销, 暂时未处理 + if (Objects.equals(billDetail.getStatus(), "REVOKED")){ + + } return payReconcileDetail; } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/conver/PayReconcileConvert.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/conver/PayReconcileConvert.java new file mode 100644 index 00000000..2eee966e --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/conver/PayReconcileConvert.java @@ -0,0 +1,22 @@ +package cn.bootx.platform.daxpay.service.core.order.reconcile.conver; + +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.dto.order.reconcile.PayReconcileDetailDto; +import cn.bootx.platform.daxpay.service.dto.order.reconcile.PayReconcileOrderDto; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * + * @author xxm + * @since 2024/1/22 + */ +@Mapper +public interface PayReconcileConvert { + PayReconcileConvert CONVERT = Mappers.getMapper(PayReconcileConvert.class); + + PayReconcileDetailDto convert(PayReconcileDetail in); + + PayReconcileOrderDto convert(PayReconcileOrder in); +} 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 index 82af70a1..5b748009 100644 --- 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 @@ -1,7 +1,13 @@ package cn.bootx.platform.daxpay.service.core.order.reconcile.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.order.reconcile.entity.PayReconcileDetail; +import cn.bootx.platform.daxpay.service.param.reconcile.ReconcileDetailQuery; +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; @@ -15,4 +21,13 @@ import org.springframework.stereotype.Repository; @Repository @RequiredArgsConstructor public class PayReconcileDetailManager extends BaseManager { + + /** + * 分页 + */ + public Page page(PageParam pageParam, ReconcileDetailQuery query){ + Page mpPage = MpUtil.getMpPage(pageParam, PayReconcileDetail.class); + QueryWrapper generator = QueryGenerator.generator(query); + return this.page(mpPage,generator); + } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileOrderManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileOrderManager.java index 5657a2e5..958a74b8 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileOrderManager.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/PayReconcileOrderManager.java @@ -1,7 +1,13 @@ package cn.bootx.platform.daxpay.service.core.order.reconcile.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.order.reconcile.entity.PayReconcileOrder; +import cn.bootx.platform.daxpay.service.param.reconcile.ReconcileOrderQuery; +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; @@ -15,4 +21,13 @@ import org.springframework.stereotype.Repository; @Repository @RequiredArgsConstructor public class PayReconcileOrderManager extends BaseManager { + + /** + * 分页 + */ + public Page page(PageParam pageParam, ReconcileOrderQuery query){ + Page mpPage = MpUtil.getMpPage(pageParam, PayReconcileOrder.class); + QueryWrapper generator = QueryGenerator.generator(query); + return this.page(mpPage,generator); + } } 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 960b5f4b..61043a26 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,7 +1,11 @@ package cn.bootx.platform.daxpay.service.core.order.reconcile.entity; +import cn.bootx.platform.common.core.function.EntityBaseFunction; import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity; +import cn.bootx.platform.daxpay.service.core.order.reconcile.conver.PayReconcileConvert; +import cn.bootx.platform.daxpay.service.dto.order.reconcile.PayReconcileDetailDto; 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; @@ -15,20 +19,14 @@ import lombok.experimental.Accessors; @EqualsAndHashCode(callSuper = true) @Data @Accessors(chain = true) +@DbTable(comment = "支付对账记录") @TableName("pay_reconcile_detail") -public class PayReconcileDetail extends MpCreateEntity { +public class PayReconcileDetail extends MpCreateEntity implements EntityBaseFunction { /** 关联对账订单ID */ @DbColumn(comment = "关联对账订单ID") private Long recordOrderId; - /** - * 交易状态 - * @see cn.bootx.platform.daxpay.code.PayStatusEnum - */ - @DbColumn(comment = "交易状态") - private String status; - /** 交易类型 支付/退款 */ @DbColumn(comment = "交易类型") private String type; @@ -49,4 +47,8 @@ public class PayReconcileDetail extends MpCreateEntity { @DbColumn(comment = "商品名称") private String title; + @Override + public PayReconcileDetailDto toDto() { + return PayReconcileConvert.CONVERT.convert(this); + } } 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 a4b76b2b..2f20326e 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,8 +1,12 @@ package cn.bootx.platform.daxpay.service.core.order.reconcile.entity; +import cn.bootx.platform.common.core.function.EntityBaseFunction; import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity; +import cn.bootx.platform.daxpay.service.core.order.reconcile.conver.PayReconcileConvert; +import cn.bootx.platform.daxpay.service.dto.order.reconcile.PayReconcileOrderDto; import cn.bootx.table.modify.annotation.DbColumn; import cn.bootx.table.modify.annotation.DbTable; +import cn.bootx.table.modify.mysql.annotation.DbMySqlIndex; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; import lombok.EqualsAndHashCode; @@ -20,13 +24,14 @@ import java.time.LocalDate; @Accessors(chain = true) @DbTable(comment = "支付对账单订单") @TableName("pay_reconcile_order") -public class PayReconcileOrder extends MpCreateEntity { +public class PayReconcileOrder extends MpCreateEntity implements EntityBaseFunction { /** * 批次号 * 规则:通道简称 + yyyyMMdd + 两位流水号 * 例子:wx2024012001、ali2024012002 */ + @DbMySqlIndex(name="批次号索引") @DbColumn(comment = "批次号") private String batchNo; @@ -50,4 +55,11 @@ public class PayReconcileOrder extends MpCreateEntity { @DbColumn(comment = "错误信息") private String errorMsg; + /** + * @return + */ + @Override + public PayReconcileOrderDto toDto() { + return PayReconcileConvert.CONVERT.convert(this); + } } 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 deleted file mode 100644 index bbaf5efc..00000000 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/service/PayReconcileOrderQueryService.java +++ /dev/null @@ -1,51 +0,0 @@ -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 08950d55..715560cd 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 @@ -56,7 +56,7 @@ public class PayReconcileOrderService { // 生成批次号 String format = LocalDateTimeUtil.format(date, DatePattern.PURE_DATE_PATTERN); String key = channelEnum.getReconcilePrefix()+format; - String seqNo = this.genSeqNo(key); + String seqNo = key + this.genSeqNo(key); PayReconcileOrder order = new PayReconcileOrder() .setBatchNo(seqNo) @@ -74,7 +74,6 @@ public class PayReconcileOrderService { */ private String genSeqNo(String key){ long next = sequence.next(key); - return String.format("%2d",next); - + return String.format("%02d",next); } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/service/PayReconcileQueryService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/service/PayReconcileQueryService.java new file mode 100644 index 00000000..e74f51f3 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/service/PayReconcileQueryService.java @@ -0,0 +1,61 @@ +package cn.bootx.platform.daxpay.service.core.order.reconcile.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.order.reconcile.dao.PayReconcileDetailManager; +import cn.bootx.platform.daxpay.service.core.order.reconcile.dao.PayReconcileOrderManager; +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.dto.order.reconcile.PayReconcileDetailDto; +import cn.bootx.platform.daxpay.service.dto.order.reconcile.PayReconcileOrderDto; +import cn.bootx.platform.daxpay.service.param.reconcile.ReconcileDetailQuery; +import cn.bootx.platform.daxpay.service.param.reconcile.ReconcileOrderQuery; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** + * 支付对账订单查询服务类 + * @author xxm + * @since 2024/1/21 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class PayReconcileQueryService { + private final PayReconcileOrderManager orderManager; + private final PayReconcileDetailManager detailManager; + + /** + * 分页 + */ + public PageResult page(PageParam pageParam, ReconcileOrderQuery query){ + return MpUtil.convert2DtoPageResult(orderManager.page(pageParam, query)); + } + + /** + * 对账订单 + */ + public PayReconcileOrderDto findById(Long id){ + return orderManager.findById(id).map(PayReconcileOrder::toDto) + .orElseThrow(()->new DataNotExistException("对账订单不存在")); + } + + /** + * 明细分页 + */ + public PageResult pageDetail(PageParam pageParam, ReconcileDetailQuery query){ + return MpUtil.convert2DtoPageResult(detailManager.page(pageParam, query)); + } + + /** + * 明细详情 + */ + public PayReconcileDetailDto findDetailById(Long id){ + return detailManager.findById(id).map(PayReconcileDetail::toDto) + .orElseThrow(()->new DataNotExistException("对账详情不存在")); + } + +} 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 7dcb9348..df19ed16 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 @@ -52,7 +52,7 @@ public class PayReconcileService { reconcileOrderService.update(recordOrder); } catch (Exception e) { log.error("下载对账单异常", e); - recordOrder.setErrorMsg(e.getMessage()); + recordOrder.setErrorMsg("错误原因: " + e.getMessage()); reconcileOrderService.update(recordOrder); throw new RuntimeException(e); } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/PayReconcileDetailDto.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/PayReconcileDetailDto.java new file mode 100644 index 00000000..89169392 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/PayReconcileDetailDto.java @@ -0,0 +1,48 @@ +package cn.bootx.platform.daxpay.service.dto.order.reconcile; + +import cn.bootx.platform.common.core.rest.dto.BaseDto; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 对账订单详情 + * @author xxm + * @since 2024/1/22 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@Schema(title = "对账订单详情") +public class PayReconcileDetailDto extends BaseDto { + + @Schema(description = "关联对账订单ID") + private Long recordOrderId; + + /** + * @see cn.bootx.platform.daxpay.code.PayStatusEnum + */ + @Schema(description = "交易状态") + private String status; + + /** 交易类型 支付/退款 */ + @Schema(description = "交易类型") + private String type; + + /** 订单id - 支付ID/退款ID等 */ + @Schema(description = "订单id") + private String orderId; + + /** 网关订单号 - 支付宝/微信的订单号 */ + @Schema(description = "网关订单号") + private String gatewayOrderNo; + + /** 交易金额 */ + @Schema(description = "交易金额") + private Integer amount; + + /** 商品名称 */ + @Schema(description = "商品名称") + private String title; +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/PayReconcileOrderDto.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/PayReconcileOrderDto.java new file mode 100644 index 00000000..d4b298f5 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/PayReconcileOrderDto.java @@ -0,0 +1,39 @@ +package cn.bootx.platform.daxpay.service.dto.order.reconcile; + +import cn.bootx.platform.common.core.rest.dto.BaseDto; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.time.LocalDate; + +/** + * 对账订单 + * @author xxm + * @since 2024/1/22 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Accessors(chain = true) +@Schema(title = "对账订单") +public class PayReconcileOrderDto extends BaseDto { + + @Schema(description = "日期") + private LocalDate date; + + @Schema(description = "批次号") + private String batchNo; + + @Schema(description = "通道") + private String channel; + + @Schema(description = "是否下载成功") + private boolean down; + + @Schema(description = "是否比对完成") + private boolean compare; + + @Schema(description = "错误信息") + private String errorMsg; +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/reconcile/ReconcileDetailQuery.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/reconcile/ReconcileDetailQuery.java new file mode 100644 index 00000000..2bec1a5b --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/reconcile/ReconcileDetailQuery.java @@ -0,0 +1,48 @@ +package cn.bootx.platform.daxpay.service.param.reconcile; + +import cn.bootx.platform.common.core.annotation.QueryParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 对账详情查询 + * @author xxm + * @since 2024/1/22 + */ +@QueryParam(type = QueryParam.CompareTypeEnum.EQ) +@Data +@Accessors(chain = true) +@Schema(title = "对账详情查询") +public class ReconcileDetailQuery { + + @Schema(description = "关联对账订单ID") + private Long recordOrderId; + + /** + * @see cn.bootx.platform.daxpay.code.PayStatusEnum + */ + @Schema(description = "交易状态") + private String status; + + /** 交易类型 支付/退款 */ + @Schema(description = "交易类型") + private String type; + + /** 订单id - 支付ID/退款ID等 */ + @Schema(description = "订单id") + private String orderId; + + /** 网关订单号 - 支付宝/微信的订单号 */ + @Schema(description = "网关订单号") + private String gatewayOrderNo; + + /** 交易金额 */ + @Schema(description = "交易金额") + private Integer amount; + + /** 商品名称 */ + @QueryParam(type = QueryParam.CompareTypeEnum.LIKE) + @Schema(description = "商品名称") + private String title; +} 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/ReconcileOrderCreate.java similarity index 94% rename from daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/reconcile/CreateReconcileOrderParam.java rename to daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/reconcile/ReconcileOrderCreate.java index 61523524..18e0de6e 100644 --- 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/ReconcileOrderCreate.java @@ -16,7 +16,7 @@ import java.time.LocalDate; @Data @Accessors(chain = true) @Schema(title = "创建对账订单参数") -public class CreateReconcileOrderParam { +public class ReconcileOrderCreate { @NotNull(message = "日期不能为空") @Schema(description = "日期") diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/reconcile/ReconcileOrderQuery.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/reconcile/ReconcileOrderQuery.java new file mode 100644 index 00000000..5b64fa8b --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/param/reconcile/ReconcileOrderQuery.java @@ -0,0 +1,39 @@ +package cn.bootx.platform.daxpay.service.param.reconcile; + +import cn.bootx.platform.common.core.annotation.QueryParam; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.time.LocalDate; + +/** + * 对账订单查询参数 + * @author xxm + * @since 2024/1/22 + */ +@QueryParam(type = QueryParam.CompareTypeEnum.EQ) +@Data +@Accessors(chain = true) +@Schema(title = "对账订单查询参数") +public class ReconcileOrderQuery { + + @Schema(description = "批次号") + private String batchNo; + + @Schema(description = "日期") + private LocalDate date; + + @Schema(description = "通道") + private String channel; + + @Schema(description = "是否下载成功") + private Boolean down; + + @Schema(description = "是否比对完成") + private Boolean compare; + + @Schema(description = "错误信息") + @QueryParam(type = QueryParam.CompareTypeEnum.LIKE) + private String errorMsg; +} diff --git a/daxpay-single/daxpay-single-start/src/main/resources/application-dev.yml b/daxpay-single/daxpay-single-start/src/main/resources/application-dev.yml index 132281a7..45003539 100644 --- a/daxpay-single/daxpay-single-start/src/main/resources/application-dev.yml +++ b/daxpay-single/daxpay-single-start/src/main/resources/application-dev.yml @@ -96,14 +96,16 @@ bootx: cache: # 默认超时时间 30分钟 default-ttl: 1800 - # 对Key设置超时间 (秒) - keys-ttl: - "[iam:user:path]" : 5200 - "[iam:ignore:path]" : 28800 - "[base:china:region]" : 28800 # 序列生成器 sequence: + # 生成方式 type: jdbc + # 序列生成器起始值 + range-start: 1 + # 序列生成器区间, 设置1每次都会操作数据库 + range-step: 1 + # 步长 + step: 1 # 异常 exception: # 显示详细异常