From 13c28069ecc0f2ab5979dd269f4c6cd219ad93a2 Mon Sep 17 00:00:00 2001 From: DaxPay Date: Mon, 16 Dec 2024 16:34:45 +0800 Subject: [PATCH] =?UTF-8?q?feat=20=E5=88=86=E8=B4=A6=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../allocation/AliPayAllocationService.java | 83 ++++---- .../strategy/AliAllocationStrategy.java | 9 + .../strategy/WechatAllocationStrategy.java | 9 + .../daxpay/core/enums/TradeTypeEnum.java | 4 +- .../transaction/AllocSyncParam.java | 26 +++ .../transaction/AllocationParam.java | 24 +++ .../allocation/transaction/ReceiverParam.java | 34 ---- .../result/allocation/AllocSyncResult.java | 16 ++ .../{order => }/AllocationResult.java | 2 +- .../bo/allocation/AllocSyncResultBo.java | 16 ++ .../allocation/AllocOrderController.java | 25 ++- .../unipay/UniAllocationController.java | 16 +- .../service/allocation/AllocationService.java | 49 ++++- .../allocation/AllocationSyncService.java | 187 ++++++++++++++++++ .../order/AllocOrderQueryService.java | 39 ++++ .../allocation/order/AllocOrderService.java | 61 +++++- .../order/AllocationAssistService.java | 124 ------------ .../strategy/AbsAllocationStrategy.java | 7 + 18 files changed, 514 insertions(+), 217 deletions(-) create mode 100644 daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/param/allocation/transaction/AllocSyncParam.java delete mode 100644 daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/param/allocation/transaction/ReceiverParam.java create mode 100644 daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/result/allocation/AllocSyncResult.java rename daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/result/allocation/{order => }/AllocationResult.java (92%) create mode 100644 daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/bo/allocation/AllocSyncResultBo.java create mode 100644 daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/AllocationSyncService.java delete mode 100644 daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/order/AllocationAssistService.java diff --git a/daxpay-single-channel/daxpay-single-alipay/src/main/java/org/dromara/daxpay/channel/alipay/service/allocation/AliPayAllocationService.java b/daxpay-single-channel/daxpay-single-alipay/src/main/java/org/dromara/daxpay/channel/alipay/service/allocation/AliPayAllocationService.java index d9bf9c45..dd87dd01 100644 --- a/daxpay-single-channel/daxpay-single-alipay/src/main/java/org/dromara/daxpay/channel/alipay/service/allocation/AliPayAllocationService.java +++ b/daxpay-single-channel/daxpay-single-alipay/src/main/java/org/dromara/daxpay/channel/alipay/service/allocation/AliPayAllocationService.java @@ -1,29 +1,37 @@ package org.dromara.daxpay.channel.alipay.service.allocation; import cn.bootx.platform.common.mybatisplus.base.MpIdEntity; +import cn.bootx.platform.common.mybatisplus.function.CollectorsFunction; +import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONUtil; import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayResponse; -import com.alipay.api.domain.AlipayTradeOrderSettleModel; -import com.alipay.api.domain.OpenApiRoyaltyDetailInfoPojo; -import com.alipay.api.domain.SettleExtendParams; +import com.alipay.api.domain.*; +import com.alipay.api.request.AlipayTradeOrderSettleQueryRequest; import com.alipay.api.request.AlipayTradeOrderSettleRequest; +import com.alipay.api.response.AlipayTradeOrderSettleQueryResponse; import com.alipay.api.response.AlipayTradeOrderSettleResponse; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.daxpay.channel.alipay.code.AliPayCode; import org.dromara.daxpay.channel.alipay.service.config.AliPayConfigService; import org.dromara.daxpay.core.enums.AllocDetailResultEnum; +import org.dromara.daxpay.core.exception.OperationFailException; import org.dromara.daxpay.core.exception.TradeFailException; import org.dromara.daxpay.core.util.PayUtil; import org.dromara.daxpay.service.bo.allocation.AllocStartResultBo; +import org.dromara.daxpay.service.bo.allocation.AllocSyncResultBo; import org.dromara.daxpay.service.entity.allocation.transaction.AllocDetail; import org.dromara.daxpay.service.entity.allocation.transaction.AllocOrder; import org.springframework.stereotype.Service; +import java.time.LocalDateTime; import java.util.Comparator; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.function.Function; import java.util.stream.Collectors; /** @@ -60,7 +68,7 @@ public class AliPayAllocationService { model.setRoyaltyParameters(royaltyParameters); AlipayTradeOrderSettleRequest request = new AlipayTradeOrderSettleRequest(); request.setBizModel(model); - AlipayTradeOrderSettleResponse response = null; + AlipayTradeOrderSettleResponse response; try { response = aliPayConfigService.execute(request); this.verifyErrorMsg(response); @@ -79,7 +87,7 @@ public class AliPayAllocationService { public void finish(AllocOrder allocOrder, List orderDetails){ // 分账主体参数 AlipayTradeOrderSettleModel model = new AlipayTradeOrderSettleModel(); - model.setOutRequestNo(String.valueOf(allocOrder.getAllocNo())); + model.setOutRequestNo(allocOrder.getAllocNo()); model.setTradeNo(allocOrder.getOutOrderNo()); model.setRoyaltyMode(AliPayCode.ALLOC_ASYNC); // 分账完结参数 @@ -113,37 +121,40 @@ public class AliPayAllocationService { /** * 分账状态同步 */ -// @SneakyThrows -// public AllocRemoteSyncResult sync(AllocOrder allocOrder, List allocOrderDetails, AliPayConfig config){ -// AlipayClient alipayClient = aliPayConfigService.getAlipayClient(config); -// AlipayTradeOrderSettleQueryModel model = new AlipayTradeOrderSettleQueryModel(); -// model.setTradeNo(allocOrder.getOutOrderNo()); -// model.setOutRequestNo(allocOrder.getAllocNo()); -// AlipayTradeOrderSettleQueryRequest request = new AlipayTradeOrderSettleQueryRequest(); -// request.setBizModel(model); -// AlipayTradeOrderSettleQueryResponse response = alipayClient.execute(request); -// // 验证 -// this.verifyErrorMsg(response); -// Map detailMap = allocOrderDetails.stream() -// .collect(Collectors.toMap(AllocOrderDetail::getReceiverAccount, Function.identity(), CollectorsFunction::retainLatest)); -// List royaltyDetailList = response.getRoyaltyDetailList(); -// for (RoyaltyDetail receiver : royaltyDetailList) { -// AllocOrderDetail detail = detailMap.get(receiver.getTransIn()); -// if (Objects.nonNull(detail)) { -// detail.setResult(this.getDetailResultEnum(receiver.getState()).getCode()); -// detail.setErrorCode(receiver.getErrorCode()); -// detail.setErrorMsg(receiver.getErrorDesc()); -// // 如果是完成, 更新时间 -// if (AllocDetailResultEnum.SUCCESS.getCode().equals(detail.getResult())){ -// LocalDateTime finishTime = LocalDateTimeUtil.of(receiver.getExecuteDt()); -// detail.setFinishTime(finishTime) -// .setErrorMsg(null) -// .setErrorCode(null); -// } -// } -// } -// return new AllocRemoteSyncResult().setSyncInfo(JSONUtil.toJsonStr(response)); -// } + public AllocSyncResultBo sync(AllocOrder allocOrder, List allocOrderDetails){ + AlipayTradeOrderSettleQueryModel model = new AlipayTradeOrderSettleQueryModel(); + model.setOutRequestNo(allocOrder.getAllocNo()); + model.setTradeNo(allocOrder.getOutOrderNo()); + AlipayTradeOrderSettleQueryRequest request = new AlipayTradeOrderSettleQueryRequest(); + request.setBizModel(model); + AlipayTradeOrderSettleQueryResponse response; + try { + response = aliPayConfigService.execute(request); + } catch (AlipayApiException e) { + throw new OperationFailException(e.getMessage()); + } + // 验证 + this.verifyErrorMsg(response); + Map detailMap = allocOrderDetails.stream() + .collect(Collectors.toMap(AllocDetail::getReceiverAccount, Function.identity(), CollectorsFunction::retainLatest)); + List royaltyDetailList = response.getRoyaltyDetailList(); + for (RoyaltyDetail receiver : royaltyDetailList) { + var detail = detailMap.get(receiver.getTransIn()); + if (Objects.nonNull(detail)) { + detail.setResult(this.getDetailResultEnum(receiver.getState()).getCode()); + detail.setErrorCode(receiver.getErrorCode()); + detail.setErrorMsg(receiver.getErrorDesc()); + // 如果是完成, 更新时间 + if (AllocDetailResultEnum.SUCCESS.getCode().equals(detail.getResult())){ + LocalDateTime finishTime = LocalDateTimeUtil.of(receiver.getExecuteDt()); + detail.setFinishTime(finishTime) + .setErrorMsg(null) + .setErrorCode(null); + } + } + } + return new AllocSyncResultBo().setSyncInfo(JSONUtil.toJsonStr(response)); + } /** * 验证错误信息 diff --git a/daxpay-single-channel/daxpay-single-alipay/src/main/java/org/dromara/daxpay/channel/alipay/strategy/AliAllocationStrategy.java b/daxpay-single-channel/daxpay-single-alipay/src/main/java/org/dromara/daxpay/channel/alipay/strategy/AliAllocationStrategy.java index 9518195b..34b9fbdb 100644 --- a/daxpay-single-channel/daxpay-single-alipay/src/main/java/org/dromara/daxpay/channel/alipay/strategy/AliAllocationStrategy.java +++ b/daxpay-single-channel/daxpay-single-alipay/src/main/java/org/dromara/daxpay/channel/alipay/strategy/AliAllocationStrategy.java @@ -5,6 +5,7 @@ import lombok.extern.slf4j.Slf4j; import org.dromara.daxpay.channel.alipay.service.allocation.AliPayAllocationService; import org.dromara.daxpay.core.enums.ChannelEnum; import org.dromara.daxpay.service.bo.allocation.AllocStartResultBo; +import org.dromara.daxpay.service.bo.allocation.AllocSyncResultBo; import org.dromara.daxpay.service.strategy.AbsAllocationStrategy; import org.springframework.stereotype.Component; @@ -43,4 +44,12 @@ public class AliAllocationStrategy extends AbsAllocationStrategy { public void finish() { aliPayAllocationService.finish(getOrder(), getDetails()); } + + /** + * 同步状态 + */ + @Override + public AllocSyncResultBo doSync() { + return aliPayAllocationService.sync(getOrder(), getDetails()); + } } diff --git a/daxpay-single-channel/daxpay-single-wechat/src/main/java/org/dromara/daxpay/channel/wechat/strategy/WechatAllocationStrategy.java b/daxpay-single-channel/daxpay-single-wechat/src/main/java/org/dromara/daxpay/channel/wechat/strategy/WechatAllocationStrategy.java index 47e59ae8..ebe43344 100644 --- a/daxpay-single-channel/daxpay-single-wechat/src/main/java/org/dromara/daxpay/channel/wechat/strategy/WechatAllocationStrategy.java +++ b/daxpay-single-channel/daxpay-single-wechat/src/main/java/org/dromara/daxpay/channel/wechat/strategy/WechatAllocationStrategy.java @@ -4,6 +4,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.daxpay.core.enums.ChannelEnum; import org.dromara.daxpay.service.bo.allocation.AllocStartResultBo; +import org.dromara.daxpay.service.bo.allocation.AllocSyncResultBo; import org.dromara.daxpay.service.strategy.AbsAllocationStrategy; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -46,4 +47,12 @@ public class WechatAllocationStrategy extends AbsAllocationStrategy { } + /** + * 同步状态 + */ + @Override + public AllocSyncResultBo doSync() { + return null; + } + } diff --git a/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/enums/TradeTypeEnum.java b/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/enums/TradeTypeEnum.java index 6a35ac39..9f9198c0 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/enums/TradeTypeEnum.java +++ b/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/enums/TradeTypeEnum.java @@ -18,7 +18,9 @@ public enum TradeTypeEnum { PAY("pay","支付"), REFUND("refund","退款"), - TRANSFER("transfer","转账"),; + TRANSFER("transfer","转账"), + ALLOCATION("allocation","分账"), + ; private final String code; private final String name; diff --git a/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/param/allocation/transaction/AllocSyncParam.java b/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/param/allocation/transaction/AllocSyncParam.java new file mode 100644 index 00000000..8b83a0fc --- /dev/null +++ b/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/param/allocation/transaction/AllocSyncParam.java @@ -0,0 +1,26 @@ +package org.dromara.daxpay.core.param.allocation.transaction; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Size; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.dromara.daxpay.core.param.PaymentCommonParam; + +/** + * 分账同步请求参数 + * @author xxm + * @since 2024/4/12 + */ +@EqualsAndHashCode(callSuper = true) +@Data +@Schema(title = "分账同步请求参数") +public class AllocSyncParam extends PaymentCommonParam { + + @Schema(description = "分账号") + @Size(max = 32, message = "分账号不可超过32位") + private String allocNo; + + @Schema(description = "商户分账号") + @Size(max = 100, message = "商户分账号不可超过100位") + private String bizAllocNo; +} diff --git a/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/param/allocation/transaction/AllocationParam.java b/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/param/allocation/transaction/AllocationParam.java index f195314e..b2c9afeb 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/param/allocation/transaction/AllocationParam.java +++ b/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/param/allocation/transaction/AllocationParam.java @@ -2,13 +2,16 @@ package org.dromara.daxpay.core.param.allocation.transaction; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.Valid; +import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import org.dromara.daxpay.core.param.PaymentCommonParam; +import java.math.BigDecimal; import java.util.List; /** @@ -64,4 +67,25 @@ public class AllocationParam extends PaymentCommonParam { @Schema(description = "商户扩展参数") private String attach; + /** + * 分账接收方列表 + */ + @Data + @Accessors(chain = true) + @Schema(title = "分账接收方列表") + public static class ReceiverParam { + + /** 分账接收方编号 */ + @Schema(description = "分账接收方编号") + @NotBlank(message = "分账接收方编号必填") + @Size(max = 32, message = "分账接收方编号不可超过32位") + private String receiverNo; + + /** 分账金额 */ + @Schema(description = "分账金额") + @NotNull(message = "分账金额必填") + @Min(value = 1,message = "分账金额至少为0.01元") + private BigDecimal amount; + } + } diff --git a/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/param/allocation/transaction/ReceiverParam.java b/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/param/allocation/transaction/ReceiverParam.java deleted file mode 100644 index 70510480..00000000 --- a/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/param/allocation/transaction/ReceiverParam.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.dromara.daxpay.core.param.allocation.transaction; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; -import jakarta.validation.constraints.Size; -import lombok.Data; -import lombok.experimental.Accessors; - -import java.math.BigDecimal; - -/** - * 分账接收方列表 - * @author xxm - * @since 2024/5/21 - */ -@Data -@Accessors(chain = true) -@Schema(title = "分账接收方列表") -public class ReceiverParam { - - /** 分账接收方编号 */ - @Schema(description = "分账接收方编号") - @NotBlank(message = "分账接收方编号必填") - @Size(max = 32, message = "分账接收方编号不可超过32位") - private String receiverNo; - - /** 分账金额 */ - @Schema(description = "分账金额") - @NotNull(message = "分账金额必填") - @Min(value = 1,message = "分账金额至少为0.01元") - private BigDecimal amount; -} diff --git a/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/result/allocation/AllocSyncResult.java b/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/result/allocation/AllocSyncResult.java new file mode 100644 index 00000000..5d4d102a --- /dev/null +++ b/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/result/allocation/AllocSyncResult.java @@ -0,0 +1,16 @@ +package org.dromara.daxpay.core.result.allocation; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 分账同步接口返回类 + * @author xxm + * @since 2024/5/20 + */ +@Data +@Accessors(chain = true) +@Schema(title = "分账同步接口") +public class AllocSyncResult { +} diff --git a/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/result/allocation/order/AllocationResult.java b/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/result/allocation/AllocationResult.java similarity index 92% rename from daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/result/allocation/order/AllocationResult.java rename to daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/result/allocation/AllocationResult.java index 30830348..80a8f390 100644 --- a/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/result/allocation/order/AllocationResult.java +++ b/daxpay-single/daxpay-single-core/src/main/java/org/dromara/daxpay/core/result/allocation/AllocationResult.java @@ -1,4 +1,4 @@ -package org.dromara.daxpay.core.result.allocation.order; +package org.dromara.daxpay.core.result.allocation; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/bo/allocation/AllocSyncResultBo.java b/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/bo/allocation/AllocSyncResultBo.java new file mode 100644 index 00000000..cedc0fc1 --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/bo/allocation/AllocSyncResultBo.java @@ -0,0 +1,16 @@ +package org.dromara.daxpay.service.bo.allocation; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * 分账同步结果 + * @author xxm + * @since 2024/5/23 + */ +@Data +@Accessors(chain = true) +public class AllocSyncResultBo { + /** 同步时网关返回的对象, 序列化为json字符串 */ + private String syncInfo; +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/controller/allocation/AllocOrderController.java b/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/controller/allocation/AllocOrderController.java index 9548e80b..36f7054f 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/controller/allocation/AllocOrderController.java +++ b/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/controller/allocation/AllocOrderController.java @@ -8,13 +8,15 @@ import cn.bootx.platform.core.rest.result.Result; import com.fhs.core.trans.anno.TransMethodResult; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.NotNull; import lombok.RequiredArgsConstructor; -import org.dromara.daxpay.core.param.allocation.transaction.AllocFinishParam; import org.dromara.daxpay.service.param.order.allocation.AllocOrderQuery; import org.dromara.daxpay.service.result.allocation.order.AllocDetailVo; import org.dromara.daxpay.service.result.allocation.order.AllocOrderVo; import org.dromara.daxpay.service.service.allocation.AllocationService; +import org.dromara.daxpay.service.service.allocation.AllocationSyncService; import org.dromara.daxpay.service.service.allocation.order.AllocOrderQueryService; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -27,6 +29,7 @@ import java.util.List; * @author xxm * @since 2024/4/7 */ +@Validated @Tag(name = "分账订单控制器") @RestController @RequestGroup(groupCode = "AllocOrder", groupName = "分账订单", moduleCode = "Alloc", moduleName = "分账管理" ) @@ -38,6 +41,8 @@ public class AllocOrderController { private final AllocationService allocationService; + private final AllocationSyncService allocationSyncService; + @Operation(summary = "分页") @GetMapping("/page") public Result> page(PageParam pageParam, AllocOrderQuery param){ @@ -64,13 +69,23 @@ public class AllocOrderController { return Res.ok(queryService.findDetailById(id)); } + @Operation(summary = "分账重试") + @PostMapping("/retry") + public Result retry(@NotNull(message = "分账单ID不可为空") Long id){ + return Res.ok(); + } @Operation(summary = "分账完结") @PostMapping("/finish") - public Result finish(String allocNo){ - AllocFinishParam param = new AllocFinishParam(); - param.setAllocNo(allocNo); - allocationService.finish(param); + public Result finish(@NotNull(message = "分账单ID不可为空")Long id){ + allocationService.finish(id); + return Res.ok(); + } + + @Operation(summary = "分账同步") + @PostMapping("/sync") + public Result sync(@NotNull(message = "分账单ID不可为空") Long id){ + allocationSyncService.sync(id); return Res.ok(); } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/controller/unipay/UniAllocationController.java b/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/controller/unipay/UniAllocationController.java index 7e9f51de..6f8a4888 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/controller/unipay/UniAllocationController.java +++ b/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/controller/unipay/UniAllocationController.java @@ -8,15 +8,18 @@ import org.dromara.daxpay.core.param.allocation.receiver.AllocReceiverAddParam; import org.dromara.daxpay.core.param.allocation.receiver.AllocReceiverQueryParam; import org.dromara.daxpay.core.param.allocation.receiver.AllocReceiverRemoveParam; import org.dromara.daxpay.core.param.allocation.transaction.AllocFinishParam; +import org.dromara.daxpay.core.param.allocation.transaction.AllocSyncParam; import org.dromara.daxpay.core.param.allocation.transaction.AllocationParam; import org.dromara.daxpay.core.param.allocation.transaction.QueryAllocOrderParam; import org.dromara.daxpay.core.result.DaxResult; +import org.dromara.daxpay.core.result.allocation.AllocSyncResult; import org.dromara.daxpay.core.result.allocation.order.AllocOrderResult; -import org.dromara.daxpay.core.result.allocation.order.AllocationResult; +import org.dromara.daxpay.core.result.allocation.AllocationResult; import org.dromara.daxpay.core.result.allocation.receiver.AllocReceiverResult; import org.dromara.daxpay.core.util.DaxRes; import org.dromara.daxpay.service.common.anno.PaymentVerify; import org.dromara.daxpay.service.service.allocation.AllocationService; +import org.dromara.daxpay.service.service.allocation.AllocationSyncService; import org.dromara.daxpay.service.service.allocation.receiver.AllocReceiverService; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -37,6 +40,7 @@ import org.springframework.web.bind.annotation.RestController; public class UniAllocationController { private final AllocReceiverService allocReceiverService; private final AllocationService allocationService; + private final AllocationSyncService allocationSyncService; @Operation(summary = "发起分账接口") @PostMapping("/start") @@ -46,11 +50,17 @@ public class UniAllocationController { @Operation(summary = "分账完结接口") @PostMapping("/finish") - public DaxResult finish(AllocFinishParam param){ + public DaxResult finish(@RequestBody AllocFinishParam param){ return DaxRes.ok(allocationService.finish(param)); } - @Operation(summary = "分账写你查询接口") + @Operation(summary = "分账同步接口") + @PostMapping("/sync") + public DaxResult sync(@RequestBody AllocSyncParam param){ + return DaxRes.ok(allocationSyncService.sync(param)); + } + + @Operation(summary = "分账订单查询接口") @PostMapping("/query") public DaxResult query(@RequestBody QueryAllocOrderParam param){ return DaxRes.ok(allocationService.queryAllocOrder(param)); diff --git a/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/AllocationService.java b/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/AllocationService.java index 2e2db826..ebd0bd28 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/AllocationService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/AllocationService.java @@ -13,17 +13,19 @@ import org.dromara.daxpay.core.exception.TradeStatusErrorException; import org.dromara.daxpay.core.param.allocation.transaction.AllocFinishParam; import org.dromara.daxpay.core.param.allocation.transaction.AllocationParam; import org.dromara.daxpay.core.param.allocation.transaction.QueryAllocOrderParam; +import org.dromara.daxpay.core.result.allocation.AllocationResult; import org.dromara.daxpay.core.result.allocation.order.AllocOrderResult; -import org.dromara.daxpay.core.result.allocation.order.AllocationResult; import org.dromara.daxpay.service.bo.allocation.AllocStartResultBo; import org.dromara.daxpay.service.convert.allocation.AllocOrderConvert; import org.dromara.daxpay.service.dao.allocation.transaction.AllocDetailManager; import org.dromara.daxpay.service.dao.allocation.transaction.AllocOrderManager; +import org.dromara.daxpay.service.entity.allocation.transaction.AllocAndDetail; import org.dromara.daxpay.service.entity.allocation.transaction.AllocDetail; import org.dromara.daxpay.service.entity.allocation.transaction.AllocOrder; -import org.dromara.daxpay.service.entity.allocation.transaction.AllocAndDetail; import org.dromara.daxpay.service.entity.order.pay.PayOrder; -import org.dromara.daxpay.service.service.allocation.order.AllocationAssistService; +import org.dromara.daxpay.service.service.allocation.order.AllocOrderQueryService; +import org.dromara.daxpay.service.service.allocation.order.AllocOrderService; +import org.dromara.daxpay.service.service.assist.PaymentAssistService; import org.dromara.daxpay.service.strategy.AbsAllocationStrategy; import org.dromara.daxpay.service.util.PaymentStrategyFactory; import org.springframework.stereotype.Service; @@ -51,10 +53,15 @@ public class AllocationService { private final AllocDetailManager allocOrderDetailManager; - private final AllocationAssistService allocationAssistService; private final LockTemplate lockTemplate; + private final PaymentAssistService paymentAssistService; + + private final AllocOrderQueryService allocOrderQueryService; + + private final AllocOrderService allocOrderService; + /** * 开启分账 多次请求只会分账一次 * 优先级 分账接收方列表 > 分账组编号 > 默认分账组 @@ -67,7 +74,7 @@ public class AllocationService { return this.retryAlloc(param, allocOrder); } else { // 首次分账 - PayOrder payOrder = allocationAssistService.getAndCheckPayOrder(param); + PayOrder payOrder = allocOrderQueryService.getAndCheckPayOrder(param); return this.allocation(param, payOrder); } } @@ -82,7 +89,7 @@ public class AllocationService { } try { // 构建分账订单相关信息 - AllocAndDetail orderAndDetail = allocationAssistService.checkAndCreateAlloc(param, payOrder); + AllocAndDetail orderAndDetail = allocOrderService.checkAndCreateAlloc(param, payOrder); // 检查是否需要进行分账 var order = orderAndDetail.transaction(); List details = orderAndDetail.details(); @@ -123,6 +130,19 @@ public class AllocationService { } } + /** + * 分账重试 + */ + public AllocationResult retryAlloc(Long id){ + var allocOrder = allocationOrderManager.findById(id).orElseThrow(() -> new DataNotExistException("分账单不存在")); + AllocationParam param = new AllocationParam(); + param.setNotifyUrl(allocOrder.getNotifyUrl()) + .setAttach(allocOrder.getAttach()) + .setReqTime(allocOrder.getReqTime()); + param.setClientIp(allocOrder.getClientIp()); + return retryAlloc(param, allocOrder); + } + /** * 重新分账 */ @@ -139,14 +159,14 @@ public class AllocationService { if (!list.contains(order.getStatus())){ throw new TradeStatusErrorException("分账单状态错误,无法重试"); } - List details = allocationAssistService.getDetails(order.getId()); + List details = allocOrderQueryService.getDetails(order.getId()); // 创建分账策略并初始化 var allocationStrategy = PaymentStrategyFactory.create(order.getChannel(),AbsAllocationStrategy.class); allocationStrategy.initParam(order, details); // 分账预处理 allocationStrategy.doBeforeHandler(); // 更新分账单信息 - allocationAssistService.updateOrder(param, order); + allocOrderService.updateOrder(param, order); try { // 重复分账处理 allocationStrategy.start(); @@ -168,6 +188,17 @@ public class AllocationService { } } + + /** + * 分账完结 + */ + public AllocationResult finish(Long id) { + AllocOrder allocOrder = allocationOrderManager.findById(id) + .orElseThrow(() -> new DataNotExistException("未查询到分账单信息")); + paymentAssistService.initMchApp(allocOrder.getAppId()); + return this.finish(allocOrder); + } + /** * 分账完结 */ @@ -191,7 +222,7 @@ public class AllocationService { if (!Arrays.asList(ALLOC_END.getCode(),FINISH_FAILED.getCode()).contains(allocOrder.getStatus())) { throw new TradeStatusErrorException("分账单状态错误"); } - List details = allocationAssistService.getDetails(allocOrder.getId()); + List details = allocOrderQueryService.getDetails(allocOrder.getId()); // 创建分账策略并初始化 AbsAllocationStrategy allocationStrategy = PaymentStrategyFactory.create(allocOrder.getChannel(),AbsAllocationStrategy.class); diff --git a/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/AllocationSyncService.java b/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/AllocationSyncService.java new file mode 100644 index 00000000..c4b8d61c --- /dev/null +++ b/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/AllocationSyncService.java @@ -0,0 +1,187 @@ +package org.dromara.daxpay.service.service.allocation; + +import cn.bootx.platform.core.exception.DataNotExistException; +import cn.bootx.platform.core.exception.RepetitiveOperationException; +import com.baomidou.lock.LockInfo; +import com.baomidou.lock.LockTemplate; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.dromara.daxpay.core.enums.AllocDetailResultEnum; +import org.dromara.daxpay.core.enums.AllocationResultEnum; +import org.dromara.daxpay.core.enums.AllocationStatusEnum; +import org.dromara.daxpay.core.enums.TradeTypeEnum; +import org.dromara.daxpay.core.param.allocation.transaction.AllocSyncParam; +import org.dromara.daxpay.core.result.allocation.AllocSyncResult; +import org.dromara.daxpay.service.bo.allocation.AllocSyncResultBo; +import org.dromara.daxpay.service.common.local.PaymentContextLocal; +import org.dromara.daxpay.service.dao.allocation.transaction.AllocDetailManager; +import org.dromara.daxpay.service.dao.allocation.transaction.AllocOrderManager; +import org.dromara.daxpay.service.entity.allocation.transaction.AllocDetail; +import org.dromara.daxpay.service.entity.allocation.transaction.AllocOrder; +import org.dromara.daxpay.service.entity.record.sync.TradeSyncRecord; +import org.dromara.daxpay.service.service.assist.PaymentAssistService; +import org.dromara.daxpay.service.service.record.sync.TradeSyncRecordService; +import org.dromara.daxpay.service.strategy.AbsAllocationStrategy; +import org.dromara.daxpay.service.util.PaymentStrategyFactory; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +/** + * 对账同步 + * @author xxm + * @since 2024/5/23 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class AllocationSyncService { + + private final AllocOrderManager allocationOrderManager; + + private final AllocDetailManager allocOrderDetailManager; + + private final TradeSyncRecordService paySyncRecordService; + + private final LockTemplate lockTemplate; + private final PaymentAssistService paymentAssistService; + + /** + * 分账同步 + */ + @Transactional(rollbackFor = Exception.class) + public void sync(Long id) { + AllocOrder allocOrder = allocationOrderManager.findById(id) + .orElseThrow(() -> new DataNotExistException("分账单不存在")); + // 如果类型为忽略, 不进行同步处理 + if (Objects.equals(allocOrder.getStatus(), AllocationStatusEnum.IGNORE.getCode())){ + return; + } + paymentAssistService.initMchApp(allocOrder.getAppId()); + // 调用同步逻辑 + this.sync(allocOrder); + } + + /** + * 分账同步 + */ + @Transactional(rollbackFor = Exception.class) + public AllocSyncResult sync(AllocSyncParam param) { + // 获取分账订单 + AllocOrder allocOrder = null; + if (Objects.nonNull(param.getAllocNo())){ + allocOrder = allocationOrderManager.findByAllocNo(param.getAllocNo(),param.getAppId()) + .orElseThrow(() -> new DataNotExistException("分账单不存在")); + } + if (Objects.isNull(allocOrder)){ + allocOrder = allocationOrderManager.findByAllocNo(param.getBizAllocNo(),param.getAppId()) + .orElseThrow(() -> new DataNotExistException("分账单不存在")); + } + // 如果类型为忽略, 不进行同步处理 + if (Objects.equals(allocOrder.getStatus(), AllocationStatusEnum.IGNORE.getCode())){ + return new AllocSyncResult(); + } + + // 调用同步逻辑 + this.sync(allocOrder); + return new AllocSyncResult(); + } + + /** + * 分账同步 + */ + @Transactional(rollbackFor = Exception.class) + public void sync(AllocOrder allocOrder){ + LockInfo lock = lockTemplate.lock("payment:allocation:" + allocOrder.getOrderId(),10000,200); + if (Objects.isNull(lock)){ + throw new RepetitiveOperationException("分账同步中,请勿重复操作"); + } + try { + List detailList = allocOrderDetailManager.findAllByOrderId(allocOrder.getId()); + // 获取分账策略 + var allocationStrategy = PaymentStrategyFactory.create(allocOrder.getChannel(),AbsAllocationStrategy.class); + allocationStrategy.initParam(allocOrder, detailList); + // 分账完结预处理 + allocationStrategy.doBeforeHandler(); + // 执行同步操作, 分账明细的状态变更会在这个里面 + AllocSyncResultBo allocSyncResultBo = allocationStrategy.doSync(); + // 保存分账同步记录 + this.saveRecord(allocOrder, allocSyncResultBo); + // 根据订单明细更新订单的状态和处理结果 + allocOrder.setErrorMsg(null).setErrorCode(null); + this.updateOrderStatus(allocOrder, detailList); + } finally { + lockTemplate.releaseLock(lock); + } + } + + /** + * 根据订单明细更新订单的状态和处理结果, 如果订单是分账结束或失败, 不更新状态 + * TODO 是否多次同步会产生多次变动, 注意处理多次推送通知的问题, 目前是 + */ + private void updateOrderStatus(AllocOrder allocOrder, List details){ + // 如果是分账结束或失败, 不更新状态 + String status = allocOrder.getStatus(); + + // 如果是分账结束或失败, 不进行对订单进行处理 + List list = Arrays.asList(AllocationStatusEnum.FINISH.getCode(), AllocationStatusEnum.FINISH_FAILED.getCode()); + if (!list.contains(status)){ + // 判断明细状态. 获取成功和失败的 + long successCount = details.stream() + .map(AllocDetail::getResult) + .filter(AllocDetailResultEnum.SUCCESS.getCode()::equals) + .count(); + long failCount = details.stream() + .map(AllocDetail::getResult) + .filter(AllocDetailResultEnum.FAIL.getCode()::equals) + .count(); + + // 成功和失败都为0 表示进行中 + if (successCount == 0 && failCount == 0){ + allocOrder.setStatus(AllocationStatusEnum.PROCESSING.getCode()) + .setResult(AllocationResultEnum.ALL_PENDING.getCode()); + } else { + if (failCount == details.size()){ + // 全部失败 + allocOrder.setStatus(AllocationStatusEnum.ALLOC_END.getCode()) + .setResult(AllocationResultEnum.ALL_FAILED.getCode()); + } else if (successCount == details.size()){ + // 全部成功 + allocOrder.setStatus(AllocationStatusEnum.ALLOC_END.getCode()) + .setResult(AllocationResultEnum.ALL_SUCCESS.getCode()); + } else { + // 部分成功 + allocOrder.setStatus(AllocationStatusEnum.ALLOC_END.getCode()) + .setResult(AllocationResultEnum.PART_SUCCESS.getCode()); + } + } + } + allocOrderDetailManager.updateAllById(details); + allocationOrderManager.updateById(allocOrder); + + // 如果状态为完成, 发送通知 + if (Objects.equals(AllocationStatusEnum.ALLOC_END.getCode(), allocOrder.getStatus())){ + // 发送通知 +// clientNoticeService.registerAllocNotice(allocOrder, details); + } + } + + + /** + * 保存同步记录 + */ + private void saveRecord(AllocOrder order, AllocSyncResultBo syncResult){ + TradeSyncRecord syncRecord = new TradeSyncRecord() + .setBizTradeNo(order.getBizAllocNo()) + .setTradeNo(order.getAllocNo()) + .setOutTradeNo(order.getOutAllocNo()) + .setTradeType(TradeTypeEnum.ALLOCATION.getCode()) + .setChannel(order.getChannel()) + .setSyncInfo(syncResult.getSyncInfo()) + .setClientIp(PaymentContextLocal.get().getClientInfo().getClientIp()); + paySyncRecordService.saveRecord(syncRecord); + } +} diff --git a/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/order/AllocOrderQueryService.java b/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/order/AllocOrderQueryService.java index 3d465dbc..3acdfbfe 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/order/AllocOrderQueryService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/order/AllocOrderQueryService.java @@ -6,16 +6,26 @@ import cn.bootx.platform.core.rest.param.PageParam; import cn.bootx.platform.core.rest.result.PageResult; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.dromara.daxpay.core.enums.AllocDetailResultEnum; +import org.dromara.daxpay.core.enums.PayAllocStatusEnum; +import org.dromara.daxpay.core.exception.OperationUnsupportedException; +import org.dromara.daxpay.core.exception.TradeNotExistException; +import org.dromara.daxpay.core.exception.TradeStatusErrorException; +import org.dromara.daxpay.core.param.allocation.transaction.AllocationParam; import org.dromara.daxpay.service.dao.allocation.transaction.AllocDetailManager; import org.dromara.daxpay.service.dao.allocation.transaction.AllocOrderManager; import org.dromara.daxpay.service.entity.allocation.transaction.AllocDetail; import org.dromara.daxpay.service.entity.allocation.transaction.AllocOrder; +import org.dromara.daxpay.service.entity.order.pay.PayOrder; import org.dromara.daxpay.service.param.order.allocation.AllocOrderQuery; import org.dromara.daxpay.service.result.allocation.order.AllocDetailVo; import org.dromara.daxpay.service.result.allocation.order.AllocOrderVo; +import org.dromara.daxpay.service.service.order.pay.PayOrderQueryService; import org.springframework.stereotype.Service; import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; /** * 分账订单查询服务类 @@ -30,6 +40,7 @@ public class AllocOrderQueryService { private final AllocDetailManager allocOrderDetailManager; private final AllocOrderManager allocationOrderManager; + private final PayOrderQueryService payOrderQueryService; /** * 分页查询 @@ -59,5 +70,33 @@ public class AllocOrderQueryService { return allocOrderDetailManager.findById(id).map(AllocDetail::toResult).orElseThrow(() -> new DataNotExistException("分账订单明细不存在")); } + /** + * 获取发起分账或完结的明细 + */ + public List getDetails(Long allocOrderId){ + List details = allocOrderDetailManager.findAllByOrderId(allocOrderId); + // 过滤掉忽略的条目 + return details.stream() + .filter(detail -> !Objects.equals(detail.getResult(), AllocDetailResultEnum.IGNORE.getCode())) + .collect(Collectors.toList()); + } + + /** + * 获取并检查支付订单 + */ + public PayOrder getAndCheckPayOrder(AllocationParam param) { + // 查询支付单 + PayOrder payOrder = payOrderQueryService.findByBizOrOrderNo(param.getOrderNo(), param.getBizOrderNo(), param.getAppId()) + .orElseThrow(() -> new TradeNotExistException("支付单不存在")); + // 判断订单是否可以分账 + if (!payOrder.getAllocation()){ + throw new OperationUnsupportedException("该订单不允许分账"); + } + // 判断分账状态 + if (Objects.equals(PayAllocStatusEnum.ALLOCATION.getCode(), payOrder.getAllocStatus())){ + throw new TradeStatusErrorException("该订单已分账完成"); + } + return payOrder; + } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/order/AllocOrderService.java b/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/order/AllocOrderService.java index 4a191e58..48823dd7 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/order/AllocOrderService.java +++ b/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/order/AllocOrderService.java @@ -2,6 +2,7 @@ package org.dromara.daxpay.service.service.allocation.order; import cn.bootx.platform.core.exception.ValidationFailedException; import cn.bootx.platform.core.util.BigDecimalUtil; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.IdUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -9,18 +10,22 @@ import org.dromara.daxpay.core.enums.AllocDetailResultEnum; import org.dromara.daxpay.core.enums.AllocationResultEnum; import org.dromara.daxpay.core.enums.AllocationStatusEnum; import org.dromara.daxpay.core.enums.PayAllocStatusEnum; -import org.dromara.daxpay.core.param.allocation.transaction.ReceiverParam; +import org.dromara.daxpay.core.exception.DataErrorException; import org.dromara.daxpay.core.param.allocation.transaction.AllocationParam; +import org.dromara.daxpay.core.param.allocation.transaction.AllocationParam.ReceiverParam; import org.dromara.daxpay.core.util.TradeNoGenerateUtil; -import org.dromara.daxpay.service.entity.allocation.transaction.AllocDetail; -import org.dromara.daxpay.service.entity.allocation.transaction.AllocOrder; -import org.dromara.daxpay.service.result.allocation.receiver.AllocGroupReceiverVo; +import org.dromara.daxpay.service.dao.allocation.receiver.AllocGroupManager; import org.dromara.daxpay.service.dao.allocation.receiver.AllocReceiverManager; import org.dromara.daxpay.service.dao.allocation.transaction.AllocDetailManager; import org.dromara.daxpay.service.dao.allocation.transaction.AllocOrderManager; import org.dromara.daxpay.service.dao.order.pay.PayOrderManager; +import org.dromara.daxpay.service.entity.allocation.receiver.AllocGroup; import org.dromara.daxpay.service.entity.allocation.transaction.AllocAndDetail; +import org.dromara.daxpay.service.entity.allocation.transaction.AllocDetail; +import org.dromara.daxpay.service.entity.allocation.transaction.AllocOrder; import org.dromara.daxpay.service.entity.order.pay.PayOrder; +import org.dromara.daxpay.service.result.allocation.receiver.AllocGroupReceiverVo; +import org.dromara.daxpay.service.service.allocation.receiver.AllocGroupService; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -45,6 +50,10 @@ public class AllocOrderService { private final AllocOrderManager transactionManager; + private final AllocGroupManager groupManager; + + private final AllocGroupService allocGroupService; + private final AllocDetailManager transactionDetailManager; private final PayOrderManager payOrderManager; @@ -181,5 +190,49 @@ public class AllocOrderService { transactionManager.save(allocOrder); return new AllocAndDetail(allocOrder,details); } + + /** + * 根据新传入的分账订单更新订单信息 + */ + @Transactional(rollbackFor = Exception.class) + public void updateOrder(AllocationParam allocationParam, AllocOrder orderExtra) { + // 扩展信息 + orderExtra.setClientIp(allocationParam.getClientIp()) + .setNotifyUrl(allocationParam.getNotifyUrl()) + .setAttach(allocationParam.getAttach()) + .setReqTime(allocationParam.getReqTime()); + transactionManager.updateById(orderExtra); + } + + + /** + * 检查并构建分账订单相关信息 + */ + @Transactional(rollbackFor = Exception.class) + public AllocAndDetail checkAndCreateAlloc(AllocationParam param, PayOrder payOrder){ + // 创建分账单和明细并保存, 同时更新支付订单状态 使用事务 + AllocAndDetail orderAndDetail; + // 判断是否传输了分账接收方列表 + if (CollUtil.isNotEmpty(param.getReceivers())) { + orderAndDetail = this.createAndUpdate(param, payOrder); + } else { + AllocGroup allocationGroup; + if (Objects.nonNull(param.getGroupNo())){ + // 指定分账组 + allocationGroup = groupManager.findByGroupNo(param.getGroupNo(),param.getAppId()).orElseThrow(() -> new DataErrorException("未查询到分账组")); + } else { + // 默认分账组 + allocationGroup = groupManager.findDefaultGroup(payOrder.getChannel(),param.getAppId()).orElseThrow(() -> new DataErrorException("未查询到默认分账组")); + } + // 判断通道类型是否一致 + if (!Objects.equals(allocationGroup.getChannel(), payOrder.getChannel())){ + throw new ValidationFailedException("分账接收方列表存在非本通道的数据"); + } + + var receiversByGroups = allocGroupService.findReceiversByGroups(allocationGroup.getId()); + orderAndDetail = this.createAndUpdate(param ,payOrder, receiversByGroups); + } + return orderAndDetail; + } } diff --git a/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/order/AllocationAssistService.java b/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/order/AllocationAssistService.java deleted file mode 100644 index 98273dde..00000000 --- a/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/service/allocation/order/AllocationAssistService.java +++ /dev/null @@ -1,124 +0,0 @@ -package org.dromara.daxpay.service.service.allocation.order; - -import cn.bootx.platform.core.exception.ValidationFailedException; -import cn.hutool.core.collection.CollUtil; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.dromara.daxpay.core.enums.AllocDetailResultEnum; -import org.dromara.daxpay.core.enums.PayAllocStatusEnum; -import org.dromara.daxpay.core.exception.DataErrorException; -import org.dromara.daxpay.core.exception.OperationUnsupportedException; -import org.dromara.daxpay.core.exception.TradeNotExistException; -import org.dromara.daxpay.core.exception.TradeStatusErrorException; -import org.dromara.daxpay.core.param.allocation.transaction.AllocationParam; -import org.dromara.daxpay.service.dao.allocation.receiver.AllocGroupManager; -import org.dromara.daxpay.service.dao.allocation.transaction.AllocDetailManager; -import org.dromara.daxpay.service.dao.allocation.transaction.AllocOrderManager; -import org.dromara.daxpay.service.entity.allocation.receiver.AllocGroup; -import org.dromara.daxpay.service.entity.allocation.transaction.AllocOrder; -import org.dromara.daxpay.service.entity.allocation.transaction.AllocDetail; -import org.dromara.daxpay.service.entity.allocation.transaction.AllocAndDetail; -import org.dromara.daxpay.service.entity.order.pay.PayOrder; -import org.dromara.daxpay.service.service.allocation.receiver.AllocGroupService; -import org.dromara.daxpay.service.service.order.pay.PayOrderQueryService; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -/** - * 分账支撑方法 - * @author xxm - * @since 2024/5/22 - */ -@Slf4j -@Service -@RequiredArgsConstructor -public class AllocationAssistService { - - private final AllocOrderManager transactionManager; - - private final PayOrderQueryService payOrderQueryService; - - private final AllocGroupManager groupManager; - - private final AllocGroupService allocationGroupService; - - private final AllocOrderService allocOrderService; - - private final AllocDetailManager allocOrderDetailManager; - - - /** - * 根据新传入的分账订单更新订单信息 - */ - @Transactional(rollbackFor = Exception.class) - public void updateOrder(AllocationParam allocationParam, AllocOrder orderExtra) { - // 扩展信息 - orderExtra.setClientIp(allocationParam.getClientIp()) - .setNotifyUrl(allocationParam.getNotifyUrl()) - .setAttach(allocationParam.getAttach()) - .setReqTime(allocationParam.getReqTime()); - transactionManager.updateById(orderExtra); - } - - /** - * 获取并检查支付订单 - */ - public PayOrder getAndCheckPayOrder(AllocationParam param) { - // 查询支付单 - PayOrder payOrder = payOrderQueryService.findByBizOrOrderNo(param.getOrderNo(), param.getBizOrderNo(), param.getAppId()) - .orElseThrow(() -> new TradeNotExistException("支付单不存在")); - // 判断订单是否可以分账 - if (!payOrder.getAllocation()){ - throw new OperationUnsupportedException("该订单不允许分账"); - } - // 判断分账状态 - if (Objects.equals(PayAllocStatusEnum.ALLOCATION.getCode(), payOrder.getAllocStatus())){ - throw new TradeStatusErrorException("该订单已分账完成"); - } - return payOrder; - } - - /** - * 构建分账订单相关信息 - */ - public AllocAndDetail checkAndCreateAlloc(AllocationParam param, PayOrder payOrder){ - // 创建分账单和明细并保存, 同时更新支付订单状态 使用事务 - AllocAndDetail orderAndDetail; - // 判断是否传输了分账接收方列表 - if (CollUtil.isNotEmpty(param.getReceivers())) { - orderAndDetail = allocOrderService.createAndUpdate(param, payOrder); - } else { - AllocGroup allocationGroup; - if (Objects.nonNull(param.getGroupNo())){ - // 指定分账组 - allocationGroup = groupManager.findByGroupNo(param.getGroupNo(),param.getAppId()).orElseThrow(() -> new DataErrorException("未查询到分账组")); - } else { - // 默认分账组 - allocationGroup = groupManager.findDefaultGroup(payOrder.getChannel(),param.getAppId()).orElseThrow(() -> new DataErrorException("未查询到默认分账组")); - } - // 判断通道类型是否一致 - if (!Objects.equals(allocationGroup.getChannel(), payOrder.getChannel())){ - throw new ValidationFailedException("分账接收方列表存在非本通道的数据"); - } - - var receiversByGroups = allocationGroupService.findReceiversByGroups(allocationGroup.getId()); - orderAndDetail = allocOrderService.createAndUpdate(param ,payOrder, receiversByGroups); - } - return orderAndDetail; - } - - /** - * 获取发起分账或完结的明细 - */ - public List getDetails(Long allocOrderId){ - List details = allocOrderDetailManager.findAllByOrderId(allocOrderId); - // 过滤掉忽略的条目 - return details.stream() - .filter(detail -> !Objects.equals(detail.getResult(), AllocDetailResultEnum.IGNORE.getCode())) - .collect(Collectors.toList()); - } -} diff --git a/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/strategy/AbsAllocationStrategy.java b/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/strategy/AbsAllocationStrategy.java index 352455b7..8a9d1a5f 100644 --- a/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/strategy/AbsAllocationStrategy.java +++ b/daxpay-single/daxpay-single-service/src/main/java/org/dromara/daxpay/service/strategy/AbsAllocationStrategy.java @@ -3,6 +3,7 @@ package org.dromara.daxpay.service.strategy; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; +import org.dromara.daxpay.service.bo.allocation.AllocSyncResultBo; import org.dromara.daxpay.service.bo.allocation.AllocStartResultBo; import org.dromara.daxpay.service.entity.allocation.transaction.AllocDetail; import org.dromara.daxpay.service.entity.allocation.transaction.AllocOrder; @@ -47,4 +48,10 @@ public abstract class AbsAllocationStrategy implements PaymentStrategy{ */ public abstract void finish(); + + /** + * 同步状态 + */ + public abstract AllocSyncResultBo doSync(); + }