diff --git a/_doc/Task.md b/_doc/Task.md index 241045f8a..3979f89ea 100644 --- a/_doc/Task.md +++ b/_doc/Task.md @@ -27,9 +27,9 @@ - [x] 微信 - [x] 支付宝 - [x] 云闪付 - - [ ] 解析原有文件, 可以转换为指定格式进行下载 - - [ ] 增加下载系统对账单功能 - - [x] 增加对单差异数据查看功能 + - [x] 解析原有文件, 可以转换为指定格式进行下载 + - [x] 增加下载系统对账单功能 + - [x] 增加对单差异数据查看功能和查看功能 - [ ] 自动分账改造 - [ ] SDK新增对账接收放添加接口 - [ ] 创建定时任务, 自动对待分账订单进行分账 diff --git a/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/order/ReconcileOrderController.java b/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/order/ReconcileOrderController.java index 471a1195e..d038739f2 100644 --- a/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/order/ReconcileOrderController.java +++ b/daxpay-single/daxpay-single-admin/src/main/java/cn/bootx/platform/daxpay/admin/controller/order/ReconcileOrderController.java @@ -75,6 +75,18 @@ public class ReconcileOrderController { return reconcileService.downOriginal2Csv(id); } + @Operation(summary = "下载系统对账单(CSV格式)") + @GetMapping("/downLocalCsv") + public ResponseEntity downLocalCsv(Long id){ + return reconcileService.downLocalCsv(id); + } + + @Operation(summary = "下载对账差异单(CSV格式)") + @GetMapping("/downDiffCsv") + public ResponseEntity downDiffCsv(Long id){ + return reconcileService.downDiffCsv(id); + } + @Operation(summary = "对账单分页") @GetMapping("/page") public ResResult> page(PageParam pageParam, ReconcileOrderQuery query){ diff --git a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/ReconcileTradeEnum.java b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/ReconcileTradeEnum.java index 033e7351d..10b9c4302 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/ReconcileTradeEnum.java +++ b/daxpay-single/daxpay-single-core/src/main/java/cn/bootx/platform/daxpay/code/ReconcileTradeEnum.java @@ -1,8 +1,12 @@ package cn.bootx.platform.daxpay.code; +import cn.bootx.platform.common.core.exception.DataNotExistException; import lombok.AllArgsConstructor; import lombok.Getter; +import java.util.Arrays; +import java.util.Objects; + /** * 对账交易类型 * @author xxm @@ -18,4 +22,11 @@ public enum ReconcileTradeEnum { private final String code; private final String name; + + public static ReconcileTradeEnum findByCode(String code) { + return Arrays.stream(values()) + .filter(value -> Objects.equals(value.getCode(), code)) + .findFirst() + .orElseThrow(() -> new DataNotExistException("未找到对应的交易类型")); + } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/PaymentTypeEnum.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/PaymentTypeEnum.java index 5a2659597..9c6234217 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/PaymentTypeEnum.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/PaymentTypeEnum.java @@ -1,8 +1,12 @@ package cn.bootx.platform.daxpay.service.code; +import cn.bootx.platform.common.core.exception.DataNotExistException; import lombok.AllArgsConstructor; import lombok.Getter; +import java.util.Arrays; +import java.util.Objects; + /** * 支付系统中常见的操作类型, 如支付/退款/转账等 * @author xxm @@ -18,4 +22,12 @@ public enum PaymentTypeEnum { private final String code; private final String name; + + public static PaymentTypeEnum findByCode(String code){ + return Arrays.stream(values()) + .filter(value -> Objects.equals(value.getCode(), code)) + .findFirst() + .orElseThrow(() -> new DataNotExistException("未找到对应的支付类型")); + + } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/ReconcileDiffTypeEnum.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/ReconcileDiffTypeEnum.java index b9af5a4a3..999c23f50 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/ReconcileDiffTypeEnum.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/code/ReconcileDiffTypeEnum.java @@ -1,8 +1,12 @@ package cn.bootx.platform.daxpay.service.code; +import cn.bootx.platform.common.core.exception.DataNotExistException; import lombok.AllArgsConstructor; import lombok.Getter; +import java.util.Arrays; +import java.util.Objects; + /** * 对账差异类型 * @author xxm @@ -21,4 +25,13 @@ public enum ReconcileDiffTypeEnum { final String code; final String name; + + + public static ReconcileDiffTypeEnum findByCode(String code){ + return Arrays.stream(values()) + .filter(value -> Objects.equals(value.getCode(), code)) + .findFirst() + .orElseThrow(() -> new DataNotExistException("未找到对应的支付类型")); + + } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayReconcileService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayReconcileService.java index 59c56cbae..cdaec5f59 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayReconcileService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/channel/union/service/UnionPayReconcileService.java @@ -174,7 +174,6 @@ public class UnionPayReconcileService { // 默认为支付对账记录 ReconcileTradeDetail reconcileTradeDetail = new ReconcileTradeDetail() - .setTitle("未知") .setReconcileId(billDetail.getReconcileId()) .setTradeNo(billDetail.getOrderId()) .setType(ReconcileTradeEnum.PAY.getCode()) diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/ReconcileDiffManager.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/ReconcileDiffManager.java index 694b39f81..cd320482d 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/ReconcileDiffManager.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/order/reconcile/dao/ReconcileDiffManager.java @@ -12,6 +12,8 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Repository; +import java.util.List; + /** * * @author xxm @@ -30,4 +32,11 @@ public class ReconcileDiffManager extends BaseManager generator = QueryGenerator.generator(query); return this.page(mpPage,generator); } + + /** + * 查询对账单对应的差异明细 + */ + public List findAllByReconcileId(Long reconcileId) { + return this.findAllByField(ReconcileDiff::getReconcileId,reconcileId); + } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/domain/GeneralTradeInfo.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/domain/GeneralTradeInfo.java index 13dd3aec2..8a2f5e9ab 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/domain/GeneralTradeInfo.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/domain/GeneralTradeInfo.java @@ -1,6 +1,9 @@ package cn.bootx.platform.daxpay.service.core.payment.reconcile.domain; import cn.bootx.platform.daxpay.service.code.PaymentTypeEnum; +import cn.bootx.platform.daxpay.service.handler.excel.AmountConverter; +import cn.bootx.platform.daxpay.service.handler.excel.PaymentTypeConvert; +import com.alibaba.excel.annotation.ExcelProperty; import lombok.Data; import lombok.experimental.Accessors; @@ -15,23 +18,29 @@ import java.time.LocalDateTime; @Accessors(chain = true) public class GeneralTradeInfo { /** 标题 */ + @ExcelProperty("标题") private String title; /** 金额 */ + @ExcelProperty(value = "金额(元)", converter = AmountConverter.class) private Integer amount; /** * 业务类型 * @see PaymentTypeEnum */ + @ExcelProperty(value = "业务类型", converter = PaymentTypeConvert.class) private String type; /** 本地交易号 */ + @ExcelProperty("本地交易号") private String tradeNo; - /** 网关交易号 */ + /** 外部交易号 */ + @ExcelProperty("外部交易号") private String outTradeNo; /** 网关完成时间 */ + @ExcelProperty("网关完成时间") private LocalDateTime finishTime; } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/service/ReconcileService.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/service/ReconcileService.java index 94434292f..4cde26223 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/service/ReconcileService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/service/ReconcileService.java @@ -2,10 +2,13 @@ package cn.bootx.platform.daxpay.service.core.payment.reconcile.service; import cn.bootx.platform.common.core.exception.DataNotExistException; import cn.bootx.platform.common.core.util.CollUtil; +import cn.bootx.platform.common.core.util.LocalDateTimeUtil; +import cn.bootx.platform.daxpay.code.PayChannelEnum; import cn.bootx.platform.daxpay.exception.pay.PayFailureException; import cn.bootx.platform.daxpay.service.code.ReconcileFileTypeEnum; import cn.bootx.platform.daxpay.service.code.ReconcileResultEnum; import cn.bootx.platform.daxpay.service.common.local.PaymentContextLocal; +import cn.bootx.platform.daxpay.service.core.order.reconcile.dao.ReconcileDiffManager; import cn.bootx.platform.daxpay.service.core.order.reconcile.dao.ReconcileFileManager; import cn.bootx.platform.daxpay.service.core.order.reconcile.dao.ReconcileOrderManager; import cn.bootx.platform.daxpay.service.core.order.reconcile.dao.ReconcileTradeDetailManager; @@ -13,14 +16,20 @@ import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.ReconcileDif import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.ReconcileFile; import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.ReconcileOrder; import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.ReconcileTradeDetail; -import cn.bootx.platform.daxpay.service.core.order.reconcile.service.ReconcileDiffService; import cn.bootx.platform.daxpay.service.core.order.reconcile.service.ReconcileOrderService; import cn.bootx.platform.daxpay.service.core.payment.reconcile.domain.GeneralTradeInfo; import cn.bootx.platform.daxpay.service.core.payment.reconcile.factory.ReconcileStrategyFactory; +import cn.bootx.platform.daxpay.service.dto.order.reconcile.ReconcileDiffExcel; +import cn.bootx.platform.daxpay.service.dto.order.reconcile.ReconcileTradeDetailExcel; import cn.bootx.platform.daxpay.service.func.AbsReconcileStrategy; import cn.bootx.platform.daxpay.service.param.reconcile.ReconcileUploadParam; import cn.bootx.platform.daxpay.util.OrderNoGenerateUtil; +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.DatePattern; import cn.hutool.core.util.CharsetUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.support.ExcelTypeEnum; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -35,9 +44,11 @@ import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; +import java.io.ByteArrayOutputStream; import java.net.URLEncoder; import java.time.LocalDate; import java.util.List; +import java.util.stream.Collectors; /** * 对账服务, @@ -50,7 +61,7 @@ import java.util.List; public class ReconcileService { private final ReconcileOrderService reconcileOrderService; - private final ReconcileDiffService reconcileDiffService; + private final ReconcileDiffManager reconcileDiffManager; private final ReconcileOrderManager reconcileOrderManager; @@ -188,7 +199,7 @@ public class ReconcileService { } reconcileOrder.setCompare(true); reconcileOrderService.update(reconcileOrder); - reconcileDiffService.saveAll(diffRecords); + reconcileDiffManager.saveAll(diffRecords); } catch (Exception e) { log.error("比对对账单异常", e); throw e; @@ -228,19 +239,90 @@ public class ReconcileService { ReconcileOrder reconcileOrder = reconcileOrderService.findById(id) .orElseThrow(() -> new DataNotExistException("未找到对账订单")); // 查询对账-第三方交易明细 - List reconcileTradeDetails = reconcileTradeDetailManager.findAllByReconcileId(reconcileOrder.getId()); + List reconcileTradeDetails = reconcileTradeDetailManager.findAllByReconcileId(reconcileOrder.getId()) + .stream() + .map(o->{ + ReconcileTradeDetailExcel excel = new ReconcileTradeDetailExcel(); + BeanUtil.copyProperties(o,excel); + return excel; + }).collect(Collectors.toList()); // 转换为csv文件 + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + EasyExcel.write(byteArrayOutputStream, ReconcileTradeDetailExcel.class) + .excelType(ExcelTypeEnum.CSV) + .sheet("对账单明细") + .doWrite(() -> reconcileTradeDetails); + byte[] bytes = byteArrayOutputStream.toByteArray(); + // 设置header信息 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); - return null; + PayChannelEnum channelEnum = PayChannelEnum.findByCode(reconcileOrder.getChannel()); + String date = LocalDateTimeUtil.format(reconcileOrder.getDate(), DatePattern.PURE_DATE_PATTERN); + // 将原始文件进行保存 通道-日期 + String fileName = StrUtil.format("外部对账单-{}-{}.csv", channelEnum.getName(),date); + headers.setContentDispositionFormData("attachment", URLEncoder.encode(fileName, CharsetUtil.UTF_8)); + return new ResponseEntity<>(bytes,headers, HttpStatus.OK); } /** * 下载对账单(本系统中的订单) */ @SneakyThrows - public ResponseEntity downLocal(Long id){ - return null; + public ResponseEntity downLocalCsv(Long id){ + ReconcileOrder reconcileOrder = reconcileOrderService.findById(id) + .orElseThrow(() -> new DataNotExistException("未找到对账订单")); + List generalTradeInfoList = reconcileAssistService.getGeneralTradeInfoList(reconcileOrder); + + // 转换为csv文件 + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + EasyExcel.write(byteArrayOutputStream, GeneralTradeInfo.class) + .excelType(ExcelTypeEnum.CSV) + .sheet("对账单明细") + .doWrite(() -> generalTradeInfoList); + byte[] bytes = byteArrayOutputStream.toByteArray();// 设置header信息 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + + PayChannelEnum channelEnum = PayChannelEnum.findByCode(reconcileOrder.getChannel()); + String date = LocalDateTimeUtil.format(reconcileOrder.getDate(), DatePattern.PURE_DATE_PATTERN); + // 将原始文件进行保存 通道-日期 + String fileName = StrUtil.format("系统对账单-{}-{}.csv", channelEnum.getName(),date); + headers.setContentDispositionFormData("attachment", URLEncoder.encode(fileName, CharsetUtil.UTF_8)); + return new ResponseEntity<>(bytes,headers, HttpStatus.OK); + } + + /** + * 下载对账差异单 + */ + @SneakyThrows + public ResponseEntity downDiffCsv(Long id){ + ReconcileOrder reconcileOrder = reconcileOrderService.findById(id) + .orElseThrow(() -> new DataNotExistException("未找到对账订单")); + List reconcileDiffs = reconcileDiffManager.findAllByReconcileId(reconcileOrder.getId()).stream() + .map(o->{ + ReconcileDiffExcel excel = new ReconcileDiffExcel(); + BeanUtil.copyProperties(o,excel); + return excel; + }).collect(Collectors.toList()); + + // 转换为csv文件 + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + EasyExcel.write(byteArrayOutputStream, ReconcileDiffExcel.class) + .excelType(ExcelTypeEnum.CSV) + .sheet("对账单明细") + .doWrite(() -> reconcileDiffs); + byte[] bytes = byteArrayOutputStream.toByteArray();// 设置header信息 + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + + PayChannelEnum channelEnum = PayChannelEnum.findByCode(reconcileOrder.getChannel()); + String date = LocalDateTimeUtil.format(reconcileOrder.getDate(), DatePattern.PURE_DATE_PATTERN); + // 将原始文件进行保存 通道-日期 + String fileName = StrUtil.format("对账差异单-{}-{}.csv", channelEnum.getName(),date); + headers.setContentDispositionFormData("attachment", URLEncoder.encode(fileName, CharsetUtil.UTF_8)); + return new ResponseEntity<>(bytes,headers, HttpStatus.OK); } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/ReconcileDiffDto.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/ReconcileDiffDto.java index 5612af7cb..543441f63 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/ReconcileDiffDto.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/ReconcileDiffDto.java @@ -6,6 +6,7 @@ import cn.bootx.platform.daxpay.code.ReconcileTradeEnum; import cn.bootx.platform.daxpay.service.code.ReconcileDiffTypeEnum; import cn.bootx.platform.daxpay.service.core.payment.reconcile.domain.ReconcileDiffDetail; import cn.bootx.table.modify.annotation.DbColumn; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -24,14 +25,15 @@ import java.util.List; @Data @Accessors(chain = true) @Schema(title = "对账差异单") +@ExcelIgnoreUnannotated public class ReconcileDiffDto extends BaseDto { /** 对账单ID */ @Schema(description = "对账单ID") private Long reconcileId; - /** 对账号 */ - @Schema(description = "对账号") + /** 对账单号 */ + @Schema(description = "对账单号") private String reconcileNo; /** 对账单明细ID */ diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/ReconcileDiffExcel.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/ReconcileDiffExcel.java new file mode 100644 index 000000000..08206761d --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/ReconcileDiffExcel.java @@ -0,0 +1,111 @@ +package cn.bootx.platform.daxpay.service.dto.order.reconcile; + +import cn.bootx.platform.daxpay.code.PayChannelEnum; +import cn.bootx.platform.daxpay.code.ReconcileTradeEnum; +import cn.bootx.platform.daxpay.service.code.ReconcileDiffTypeEnum; +import cn.bootx.platform.daxpay.service.core.payment.reconcile.domain.ReconcileDiffDetail; +import cn.bootx.platform.daxpay.service.handler.excel.*; +import cn.bootx.table.modify.annotation.DbColumn; +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.List; + +/** + * 对账差异单导出对象 + * @author xxm + * @since 2024/3/3 + */ +@Data +@Schema(title = "对账差异单") +@ExcelIgnoreUnannotated +public class ReconcileDiffExcel { + + /** 对账单ID */ + @Schema(description = "对账单ID") + @ExcelIgnore + private Long reconcileId; + + /** 对账单号 */ + @Schema(description = "对账单号") + @ExcelProperty("对账单号") + private String reconcileNo; + + /** 对账单明细ID */ + @Schema(description = "对账单明细ID") + @ExcelIgnore + private Long detailId; + + /** 对账日期 */ + @Schema(description = "对账日期") + @ExcelProperty("对账日期") + private LocalDate reconcileDate; + + /** 本地交易号 */ + @Schema(description = "本地交易号") + @ExcelProperty("本地交易号") + private String tradeNo; + + /** 外部交易号 */ + @Schema(description = "外部交易号") + @ExcelProperty("外部交易号") + private String outTradeNo; + + /** 交易时间 */ + @Schema(description = "交易时间") + @ExcelProperty("网关完成时间") + private LocalDateTime tradeTime; + + /** 订单标题 */ + @Schema(description = "订单标题") + @ExcelProperty("商品名称") + private String title; + + /** + * 通道 + * @see PayChannelEnum + */ + @Schema(description = "通道") + @ExcelProperty(value = "通道", converter = PayChannelConvert.class) + private String channel; + + /** 交易金额 */ + @Schema(description = "交易金额") + @ExcelProperty(value = "交易金额(元)", converter = AmountConverter.class) + private Integer amount; + + /** 外部交易金额 */ + @DbColumn(comment = "外部交易金额") + @ExcelProperty(value = "外部交易金额(元)", converter = AmountConverter.class) + private Integer outAmount; + + /** + * 交易类型 + * @see ReconcileTradeEnum + */ + @Schema(description = "交易类型") + @ExcelProperty(value = "交易类型", converter = ReconcileTradeConvert.class) + private String tradeType; + + /** + * 差异类型 + * @see ReconcileDiffTypeEnum + */ + @Schema(description = "差异类型") + @ExcelProperty(value = "差异类型", converter = ReconcileDiffTypeConvert.class) + private String diffType; + + /** + * 差异内容, 存储json字符串, 格式为 + * {属性: '标题', 本地字段值:'标题1', 网关字段值: '标题2'} + * @see ReconcileDiffDetail + */ + @Schema(description = "差异内容") + @ExcelProperty(value = "差异内容", converter = ReconcileDiffDetailConvert.class) + private List diffs; +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/ReconcileTradeDetailDto.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/ReconcileTradeDetailDto.java index b16e6ea18..95a71fae9 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/ReconcileTradeDetailDto.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/ReconcileTradeDetailDto.java @@ -2,6 +2,11 @@ package cn.bootx.platform.daxpay.service.dto.order.reconcile; import cn.bootx.platform.common.core.rest.dto.BaseDto; import cn.bootx.platform.daxpay.service.code.PaymentTypeEnum; +import cn.bootx.platform.daxpay.service.handler.excel.AmountConverter; +import cn.bootx.platform.daxpay.service.handler.excel.PaymentTypeConvert; +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; @@ -18,18 +23,22 @@ import java.time.LocalDateTime; @Data @Accessors(chain = true) @Schema(title = "对账订单详情") +@ExcelIgnoreUnannotated public class ReconcileTradeDetailDto extends BaseDto { /** 关联对账订单ID */ @Schema(description = "关联对账订单ID") + @ExcelIgnore private Long reconcileId; /** 商品名称 */ @Schema(description = "商品名称") + @ExcelProperty("商品名称") private String title; /** 交易金额 */ @Schema(description = "交易金额") + @ExcelProperty(value = "交易金额(元)", converter = AmountConverter.class) private Integer amount; /** @@ -37,17 +46,22 @@ public class ReconcileTradeDetailDto extends BaseDto { * @see PaymentTypeEnum */ @Schema(description = "交易类型") + @ExcelProperty(value = "交易类型",converter = PaymentTypeConvert.class) private String type; /** 本地交易号 */ @Schema(description = "本地交易号") + @ExcelProperty("本地交易号") private String tradeNo; /** 外部交易号 - 支付宝/微信的订单号 */ @Schema(description = "外部交易号") + @ExcelProperty("外部交易号") private String outTradeNo; /** 交易时间 */ @Schema(description = "交易时间") + @ExcelProperty("交易时间") private LocalDateTime tradeTime; + } diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/ReconcileTradeDetailExcel.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/ReconcileTradeDetailExcel.java new file mode 100644 index 000000000..61a273347 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/dto/order/reconcile/ReconcileTradeDetailExcel.java @@ -0,0 +1,56 @@ +package cn.bootx.platform.daxpay.service.dto.order.reconcile; + +import cn.bootx.platform.daxpay.service.code.PaymentTypeEnum; +import cn.bootx.platform.daxpay.service.handler.excel.AmountConverter; +import cn.bootx.platform.daxpay.service.handler.excel.PaymentTypeConvert; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * 对账订单详情 + * @author xxm + * @since 2024/1/22 + */ +@Data +@Schema(title = "对账订单详情") +@ExcelIgnoreUnannotated +public class ReconcileTradeDetailExcel { + + /** 商品名称 */ + @Schema(description = "商品名称") + @ExcelProperty("商品名称") + private String title; + + /** 交易金额 */ + @Schema(description = "交易金额") + @ExcelProperty(value = "交易金额(元)", converter = AmountConverter.class) + private Integer amount; + + /** + * 交易类型 + * @see PaymentTypeEnum + */ + @Schema(description = "交易类型") + @ExcelProperty(value = "交易类型",converter = PaymentTypeConvert.class) + private String type; + + /** 本地交易号 */ + @Schema(description = "本地交易号") + @ExcelProperty("本地交易号") + private String tradeNo; + + /** 外部交易号 - 支付宝/微信的订单号 */ + @Schema(description = "外部交易号") + @ExcelProperty("外部交易号") + private String outTradeNo; + + /** 交易时间 */ + @Schema(description = "交易时间") + @ExcelProperty("交易时间") + private LocalDateTime tradeTime; + +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/AmountConverter.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/AmountConverter.java new file mode 100644 index 000000000..43f9f85ca --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/AmountConverter.java @@ -0,0 +1,30 @@ +package cn.bootx.platform.daxpay.service.handler.excel; + +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * 金额分转元 + * @author xxm + * @since 2024/5/6 + */ +public class AmountConverter implements Converter { + + /** + * 将分转为元 + */ + @Override + public WriteCellData convertToExcelData(Integer value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { + if (value == null){ + return new WriteCellData<>(""); + } + BigDecimal divide = BigDecimal.valueOf(value) + .divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP); + return new WriteCellData<>(divide); + } +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/PayChannelConvert.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/PayChannelConvert.java new file mode 100644 index 000000000..ff8e1e71c --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/PayChannelConvert.java @@ -0,0 +1,22 @@ +package cn.bootx.platform.daxpay.service.handler.excel; + +import cn.bootx.platform.daxpay.code.PayChannelEnum; +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; + +/** + * 支付通道转换 + * @author xxm + * @since 2024/5/6 + */ +public class PayChannelConvert implements Converter { + public WriteCellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception{ + if (value == null){ + return new WriteCellData<>(""); + } + PayChannelEnum typeEnum = PayChannelEnum.findByCode(value); + return new WriteCellData<>(typeEnum.getName()); + } +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/PaymentTypeConvert.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/PaymentTypeConvert.java new file mode 100644 index 000000000..7a32a6b1c --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/PaymentTypeConvert.java @@ -0,0 +1,23 @@ +package cn.bootx.platform.daxpay.service.handler.excel; + +import cn.bootx.platform.daxpay.service.code.PaymentTypeEnum; +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; + +/** + * 支付类型转换 + * @author xxm + * @since 2024/5/6 + */ +public class PaymentTypeConvert implements Converter { + @Override + public WriteCellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { + if (value == null){ + return new WriteCellData<>(""); + } + PaymentTypeEnum typeEnum = PaymentTypeEnum.findByCode(value); + return new WriteCellData<>(typeEnum.getName()); + } +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/ReconcileDiffDetailConvert.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/ReconcileDiffDetailConvert.java new file mode 100644 index 000000000..5e01e95b5 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/ReconcileDiffDetailConvert.java @@ -0,0 +1,30 @@ +package cn.bootx.platform.daxpay.service.handler.excel; + +import cn.bootx.platform.daxpay.service.core.payment.reconcile.domain.ReconcileDiffDetail; +import cn.hutool.core.collection.CollUtil; +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; + +import java.util.List; +import java.util.stream.Collectors; + +/** + * 对账差异单转换 + * @author xxm + * @since 2024/5/6 + */ +public class ReconcileDiffDetailConvert implements Converter> { + + public WriteCellData convertToExcelData(List value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { + if (CollUtil.isEmpty(value)){ + return new WriteCellData<>(""); + } + // 转换为 + String collect = value.stream() + .map(item -> item.getFieldName() + ":" + item.getLocalValue() + "<->" + item.getOutValue()) + .collect(Collectors.joining("|")); + return new WriteCellData<>(collect); + } +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/ReconcileDiffTypeConvert.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/ReconcileDiffTypeConvert.java new file mode 100644 index 000000000..d9585f4ed --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/ReconcileDiffTypeConvert.java @@ -0,0 +1,21 @@ +package cn.bootx.platform.daxpay.service.handler.excel; + +import cn.bootx.platform.daxpay.service.code.ReconcileDiffTypeEnum; +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; + +/** + * 对账差异转换 + * @author xxm + * @since 2024/5/6 + */ +public class ReconcileDiffTypeConvert implements Converter { + public WriteCellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { + if (value == null){ + return new WriteCellData<>(""); + } + return new WriteCellData<>(ReconcileDiffTypeEnum.findByCode(value).getName()); + } +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/ReconcileTradeConvert.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/ReconcileTradeConvert.java new file mode 100644 index 000000000..f654af47b --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/handler/excel/ReconcileTradeConvert.java @@ -0,0 +1,23 @@ +package cn.bootx.platform.daxpay.service.handler.excel; + +import cn.bootx.platform.daxpay.code.ReconcileTradeEnum; +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; + +/** + * 对账交易订单转换 + * @author xxm + * @since 2024/5/6 + */ +public class ReconcileTradeConvert implements Converter { + + public WriteCellData convertToExcelData(String value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { + if (value == null){ + return new WriteCellData<>(""); + } + ReconcileTradeEnum tradeEnum = ReconcileTradeEnum.findByCode(value); + return new WriteCellData<>(tradeEnum.getName()); + } +}