From 4b9df729f5c3884caa59f324d992d7e5cd093bb7 Mon Sep 17 00:00:00 2001 From: xxm1995 Date: Mon, 25 Mar 2024 22:48:52 +0800 Subject: [PATCH] =?UTF-8?q?feat=20=E4=BA=91=E9=97=AA=E4=BB=98=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=AF=B9=E8=B4=A6,=E6=94=AF=E6=8C=81=E5=AF=B9?= =?UTF-8?q?=E8=B4=A6=E6=96=87=E4=BB=B6=E6=89=8B=E5=8A=A8=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _doc/Task.md | 2 +- .../order/ReconcileOrderController.java | 8 +++ .../service/AliPayReconcileService.java | 36 +++++++++++-- .../service/UnionPayReconcileService.java | 24 +++++++-- .../service/WechatPayReconcileService.java | 51 +++++++++++++++++-- .../reconcile/service/ReconcileService.java | 42 ++++++++++++++- .../strategy/AlipayReconcileStrategy.java | 13 ++++- .../strategy/UnionPayReconcileStrategy.java | 13 ++++- .../strategy/WechatPayReconcileStrategy.java | 20 +++++--- .../service/func/AbsReconcileStrategy.java | 6 +++ 10 files changed, 192 insertions(+), 23 deletions(-) diff --git a/_doc/Task.md b/_doc/Task.md index 11958cecf..50eba0b11 100644 --- a/_doc/Task.md +++ b/_doc/Task.md @@ -5,7 +5,7 @@ - [x] 第二排: (饼图)显示各通道各支付方式数量和占比, 时间分为: 今日金额/昨日金额/七天内金额 - [x] 第三排: (折线图)显示各通道支付分为支付金额和退款,时间分为: 今日金额/昨日金额/七天内金额 - [x] 云闪付支持对账功能 - - [ ] 对账文件支持手动导入 +- [x] 对账文件支持手动导入 - [x] 结算台DEMO增加云闪付示例 - [x] 增加支付限额 - [x] 各通道(异步支付)支持单独的限额 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 17dc54172..6b46d592a 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 @@ -19,6 +19,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; /** * 支付对账 @@ -49,6 +50,13 @@ public class ReconcileOrderController { return Res.ok(); } + @Operation(summary = "手动上传对账单文件") + @PostMapping("/upload") + public ResResult upload(Long id, MultipartFile file){ + reconcileService.upload(id,file); + return Res.ok(); + } + @Operation(summary = "手动触发对账单比对") @PostMapping("/compare") public ResResult compare(Long id){ 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 9e1e860ef..2def9d72a 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 @@ -55,11 +55,10 @@ public class AliPayReconcileService { * 下载对账单, 并进行解析进行保存 * * @param date 对账日期 yyyy-MM-dd 格式 - * @param recordOrderId 对账订单ID */ @SneakyThrows @Transactional(rollbackFor = Exception.class) - public void downAndSave(String date, Long recordOrderId){ + public void downAndSave(String date){ try { AlipayDataDataserviceBillDownloadurlQueryModel model = new AlipayDataDataserviceBillDownloadurlQueryModel(); @@ -93,7 +92,7 @@ public class AliPayReconcileService { } } // 保存原始对账记录 - this.save(billDetails, billTotals, recordOrderId); + this.save(billDetails, billTotals); // 将原始交易明细对账记录转换通用结构并保存到上下文中 this.convertAndSave(billDetails); @@ -103,13 +102,42 @@ public class AliPayReconcileService { throw new RuntimeException(e); } } + /** + * 上传对账单解析并保存 + */ + @SneakyThrows + public void upload(byte[] bytes) { + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes),"GBK")); + List strings = IoUtil.readLines(bufferedReader, new ArrayList<>()); + List billDetails = this.parseDetail(strings); + // 保存原始对账记录 + this.saveBillDetail(billDetails); + // 将原始交易明细对账记录转换通用结构并保存到上下文中 + this.convertAndSave(billDetails); + } /** * 保存原始对账记录 */ - private void save(List billDetails, List billTotals, Long recordOrderId){ + private void save(List billDetails, List billTotals){ + this.saveBillDetail(billDetails); + this.saveBillTotal(billTotals); + } + + /** + * 保存原始对账明细记录 + */ + private void saveBillDetail(List billDetails){ + Long recordOrderId = PaymentContextLocal.get().getReconcileInfo().getReconcileOrder().getId(); billDetails.forEach(o->o.setRecordOrderId(recordOrderId)); reconcileBillDetailManager.saveAll(billDetails); + } + + /** + * 保存原始对账汇总记录 + */ + private void saveBillTotal(List billTotals){ + Long recordOrderId = PaymentContextLocal.get().getReconcileInfo().getReconcileOrder().getId(); billTotals.forEach(o->o.setRecordOrderId(recordOrderId)); reconcileBillTotalManager.saveAll(billTotals); } 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 013033dc4..2bbbc5e4e 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 @@ -19,6 +19,7 @@ import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.StrUtil; import com.egzosn.pay.union.bean.SDKConstants; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream; @@ -47,7 +48,7 @@ public class UnionPayReconcileService { /** * 下载对账单 */ - public void downAndSave(Date date, Long recordOrderId, UnionPayKit unionPayKit){ + public void downAndSave(Date date, UnionPayKit unionPayKit){ // 下载对账单 Map map = unionPayKit.downloadBill(date, RECONCILE_BILL_TYPE); String fileContent = map.get(FILE_CONTENT).toString(); @@ -81,7 +82,7 @@ public class UnionPayReconcileService { } } // 保存原始对账记录 - this.save(billDetails, recordOrderId); + this.save(billDetails); // 转换为通用对账记录对象 this.convertAndSave(billDetails); } catch (IOException e) { @@ -89,6 +90,21 @@ public class UnionPayReconcileService { } } + /** + * 解析上传的对账单 + */ + @SneakyThrows + public void upload(byte[] bytes){ + // 明细解析 + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes),"GBK")); + List strings = IoUtil.readLines(bufferedReader, new ArrayList<>()); + List billDetails = this.parseDetail(strings); + // 保存原始对账记录 + this.save(billDetails); + // 转换为通用对账记录对象 + this.convertAndSave(billDetails); + } + /** * 解析对账单明细 */ @@ -146,6 +162,7 @@ public class UnionPayReconcileService { // 默认为支付对账记录 ReconcileDetail reconcileDetail = new ReconcileDetail() + .setTitle("未知") .setRecordOrderId(billDetail.getRecordOrderId()) .setOrderId(billDetail.getOrderId()) .setType(ReconcileTradeEnum.PAY.getCode()) @@ -172,7 +189,8 @@ public class UnionPayReconcileService { /** * 保存原始对账记录 */ - private void save(List billDetails, Long recordOrderId){ + private void save(List billDetails){ + Long recordOrderId = PaymentContextLocal.get().getReconcileInfo().getReconcileOrder().getId(); billDetails.forEach(o->o.setRecordOrderId(recordOrderId)); unionReconcileBillDetailManager.saveAll(billDetails); } 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 913cd341e..5dc011fa1 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 @@ -13,8 +13,10 @@ import cn.bootx.platform.daxpay.service.core.channel.wechat.entity.WxReconcileBi 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.ReconcileDetail; +import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.ReconcileOrder; import cn.hutool.core.codec.Base64; import cn.hutool.core.date.DatePattern; +import cn.hutool.core.io.IoUtil; import cn.hutool.core.text.csv.CsvReader; import cn.hutool.core.text.csv.CsvUtil; import cn.hutool.core.util.StrUtil; @@ -24,11 +26,15 @@ import com.ijpay.wxpay.WxPayApi; import com.ijpay.wxpay.model.DownloadBillModel; import com.ijpay.wxpay.model.DownloadFundFlowModel; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import java.io.BufferedReader; import java.io.ByteArrayInputStream; +import java.io.InputStreamReader; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.Map; @@ -56,8 +62,8 @@ public class WechatPayReconcileService{ * @param date 对账日期 yyyyMMdd 格式 */ @Transactional(rollbackFor = Exception.class) - public void downAndSave(String date, Long recordOrderId, WeChatPayConfig config) { - this.downBill(date, recordOrderId, config); + public void downAndSave(String date, WeChatPayConfig config) { + this.downBill(date, config); // 资金对账单先不启用 // this.downFundFlow(date, recordOrderId, config); } @@ -66,9 +72,8 @@ public class WechatPayReconcileService{ * 下载交易账单 * * @param date 对账日期 yyyyMMdd 格式 - * @param recordOrderId 对账订单ID */ - public void downBill(String date, Long recordOrderId, WeChatPayConfig config){ + public void downBill(String date, WeChatPayConfig config){ // 下载交易账单 Map params = DownloadBillModel.builder() .mch_id(config.getWxMchId()) @@ -92,6 +97,9 @@ public class WechatPayReconcileService{ List billDetails = reader.read(billDetail, WxReconcileBillDetail.class).stream() .filter(o->Objects.equals(o.getAppId(), config.getWxAppId())) .collect(Collectors.toList()); + + Long recordOrderId = PaymentContextLocal.get().getReconcileInfo().getReconcileOrder().getId(); + billDetails.forEach(o->o.setRecordOrderId(recordOrderId)); reconcileBillDetailManager.saveAll(billDetails); @@ -103,7 +111,42 @@ public class WechatPayReconcileService{ // 将原始交易明细对账记录转换通用结构并保存到上下文中 this.convertAndSave(billDetails); + } + /** + * 上传对账单 + */ + @SneakyThrows + public void uploadBill(byte[] bytes, WeChatPayConfig config){ + BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes), "GBK")); + String result = IoUtil.read(reader); + // 过滤特殊字符 + result = result.replaceAll("`", "").replaceAll("\uFEFF", ""); + CsvReader csvRows = CsvUtil.getReader(); + + // 对账订单 + ReconcileOrder reconcileOrder = PaymentContextLocal.get() + .getReconcileInfo() + .getReconcileOrder(); + + // 获取交易记录并保存 同时过滤出当前应用的交易记录 + String billDetail = StrUtil.subBefore(result, "总交易单数", false); + List billDetails = csvRows.read(billDetail, WxReconcileBillDetail.class).stream() + // 只读取当前商户的订单 + .filter(o->Objects.equals(o.getAppId(), config.getWxAppId())) + // 只读取对账日的记录 + .filter(o->{ + String transactionTime = o.getTransactionTime(); + LocalDateTime time = LocalDateTimeUtil.parse(transactionTime, DatePattern.NORM_DATETIME_PATTERN); + return Objects.equals(reconcileOrder.getDate(), LocalDate.from(time)); + }) + .collect(Collectors.toList()); + + billDetails.forEach(o->o.setRecordOrderId(reconcileOrder.getId())); + reconcileBillDetailManager.saveAll(billDetails); + + // 将原始交易明细对账记录转换通用结构并保存到上下文中 + this.convertAndSave(billDetails); } /** 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 15c23859b..9de4eb562 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 @@ -25,6 +25,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; import java.time.LocalDate; import java.util.ArrayList; @@ -85,13 +86,47 @@ public class ReconcileService { this.downAndSave(reconcileOrder); } + /** + * 手动传输对账单 + * @param id 对账单ID + * @param file 文件 + */ + public void upload(Long id, MultipartFile file) { + ReconcileOrder reconcileOrder = reconcileOrderService.findById(id) + .orElseThrow(() -> new DataNotExistException("未找到对账订单")); + // 将对账订单写入到上下文中 + PaymentContextLocal.get().getReconcileInfo().setReconcileOrder(reconcileOrder); + AbsReconcileStrategy reconcileStrategy = ReconcileStrategyFactory.create(reconcileOrder.getChannel()); + reconcileStrategy.setRecordOrder(reconcileOrder); + reconcileStrategy.doBeforeHandler(); + try { + reconcileStrategy.upload(file); + reconcileOrder.setDown(true) + .setErrorMsg(null); + reconcileOrderService.update(reconcileOrder); + } catch (Exception e) { + log.error("上传对账单异常", e); + reconcileOrder.setErrorMsg("原因: " + e.getMessage()); + reconcileOrderService.update(reconcileOrder); + throw new RuntimeException(e); + } + // 保存转换后的通用结构对账单 + List reconcileDetails = PaymentContextLocal.get() + .getReconcileInfo() + .getReconcileDetails(); + reconcileDetailManager.saveAll(reconcileDetails); + } + /** * 下载对账单并进行保存 */ public void downAndSave(ReconcileOrder reconcileOrder) { + // 如果对账单已经存在 + if (reconcileOrder.isDown()){ + throw new PayFailureException("对账单文件已经下载或上传"); + } // 将对账订单写入到上下文中 PaymentContextLocal.get().getReconcileInfo().setReconcileOrder(reconcileOrder); - // 构建对账策略 AbsReconcileStrategy reconcileStrategy = ReconcileStrategyFactory.create(reconcileOrder.getChannel()); reconcileStrategy.setRecordOrder(reconcileOrder); @@ -131,6 +166,10 @@ public class ReconcileService { if (!reconcileOrder.isDown()){ throw new PayFailureException("请先下载对账单"); } + // 是否对比完成 + if (reconcileOrder.isCompare()){ + throw new PayFailureException("对账单比对已经完成"); + } // 查询对账单 List reconcileDetails = reconcileDetailManager.findAllByOrderId(reconcileOrder.getId()); @@ -269,4 +308,5 @@ public class ReconcileService { } return diffs; } + } 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 964561da5..387047c9c 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 @@ -14,9 +14,11 @@ import cn.bootx.platform.daxpay.service.func.AbsReconcileStrategy; import cn.bootx.platform.daxpay.service.handler.sequence.DaxPaySequenceHandler; import cn.hutool.core.date.DatePattern; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; import java.time.LocalDate; import java.time.LocalDateTime; @@ -81,13 +83,22 @@ public class AlipayReconcileStrategy extends AbsReconcileStrategy { configService.initConfig(this.config); } + /** + * 上传对账单解析并保存 + */ + @SneakyThrows + @Override + public void upload(MultipartFile file) { + reconcileService.upload(file.getBytes()); + } + /** * 下载和保存对账单 */ @Override public void downAndSave() { String date = LocalDateTimeUtil.format(this.getRecordOrder().getDate(), DatePattern.NORM_DATE_PATTERN); - reconcileService.downAndSave(date,this.getRecordOrder().getId()); + reconcileService.downAndSave(date); } /** diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/UnionPayReconcileStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/UnionPayReconcileStrategy.java index ce6015e29..69d069945 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/UnionPayReconcileStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/core/payment/reconcile/strategy/UnionPayReconcileStrategy.java @@ -16,9 +16,11 @@ import cn.bootx.platform.daxpay.service.sdk.union.api.UnionPayKit; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; import java.time.LocalDate; import java.time.LocalDateTime; @@ -74,13 +76,22 @@ public class UnionPayReconcileStrategy extends AbsReconcileStrategy { this.unionPayKit = configService.initPayService(config); } + /** + * 上传对账单解析并保存 + */ + @SneakyThrows + @Override + public void upload(MultipartFile file) { + reconcileService.upload(file.getBytes()); + } + /** * 下载对账单到本地进行保存 */ @Override public void downAndSave() { Date date = DateUtil.date(this.getRecordOrder().getDate()); - reconcileService.downAndSave(date, this.getRecordOrder().getId(), this.unionPayKit); + reconcileService.downAndSave(date, this.unionPayKit); } /** 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 ca41c5311..354cd1e26 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 @@ -14,9 +14,11 @@ import cn.bootx.platform.daxpay.service.func.AbsReconcileStrategy; import cn.bootx.platform.daxpay.service.handler.sequence.DaxPaySequenceHandler; import cn.hutool.core.date.DatePattern; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; import java.time.LocalDate; import java.time.LocalDateTime; @@ -79,22 +81,24 @@ public class WechatPayReconcileStrategy extends AbsReconcileStrategy { this.config = weChatPayConfigService.getConfig(); } + /** + * 上传对账单解析并保存 + */ + @SneakyThrows + @Override + public void upload(MultipartFile file) { + reconcileService.uploadBill(file.getBytes(),this.config); + } + /** * 下载对账单 */ @Override public void downAndSave() { String format = LocalDateTimeUtil.format(this.getRecordOrder().getDate(), DatePattern.PURE_DATE_PATTERN); - reconcileService.downAndSave(format,this.getRecordOrder().getId(), this.config); + reconcileService.downAndSave(format, this.config); } - /** - * 比对生成对账差异单 - * 1. 远程有, 本地无 补单(追加回订单/记录差异表) - * 2. 远程无, 本地有 记录差错表 - * 3. 远程有, 本地有, 但状态不一致 记录差错表 - */ - /** * 获取通用对账对象, 将流水记录转换为对账对象 */ diff --git a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsReconcileStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsReconcileStrategy.java index 9c0e6c311..735bd3e39 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsReconcileStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/cn/bootx/platform/daxpay/service/func/AbsReconcileStrategy.java @@ -5,6 +5,7 @@ import cn.bootx.platform.daxpay.service.core.order.reconcile.entity.ReconcileOrd import cn.bootx.platform.daxpay.service.core.payment.reconcile.domain.GeneralReconcileRecord; import lombok.Getter; import lombok.Setter; +import org.springframework.web.multipart.MultipartFile; import java.time.LocalDate; import java.util.List; @@ -36,6 +37,11 @@ public abstract class AbsReconcileStrategy implements PayStrategy { public void doBeforeHandler() { } + /** + * 上传对账单解析并保存 + */ + public abstract void upload(MultipartFile file); + /** * 下载对账单到本地进行保存 */