mirror of
https://gitee.com/dromara/dax-pay.git
synced 2025-10-13 21:30:25 +00:00
feat 分账同步功能开发
This commit is contained in:
@@ -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<AllocDetail> 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<AllocDetail> 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<String, AllocOrderDetail> detailMap = allocOrderDetails.stream()
|
||||
// .collect(Collectors.toMap(AllocOrderDetail::getReceiverAccount, Function.identity(), CollectorsFunction::retainLatest));
|
||||
// List<RoyaltyDetail> 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<AllocDetail> 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<String, AllocDetail> detailMap = allocOrderDetails.stream()
|
||||
.collect(Collectors.toMap(AllocDetail::getReceiverAccount, Function.identity(), CollectorsFunction::retainLatest));
|
||||
List<RoyaltyDetail> 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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证错误信息
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
@@ -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 {
|
||||
}
|
@@ -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;
|
@@ -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;
|
||||
}
|
@@ -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<PageResult<AllocOrderVo>> page(PageParam pageParam, AllocOrderQuery param){
|
||||
@@ -64,13 +69,23 @@ public class AllocOrderController {
|
||||
return Res.ok(queryService.findDetailById(id));
|
||||
}
|
||||
|
||||
@Operation(summary = "分账重试")
|
||||
@PostMapping("/retry")
|
||||
public Result<Void> retry(@NotNull(message = "分账单ID不可为空") Long id){
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "分账完结")
|
||||
@PostMapping("/finish")
|
||||
public Result<Void> finish(String allocNo){
|
||||
AllocFinishParam param = new AllocFinishParam();
|
||||
param.setAllocNo(allocNo);
|
||||
allocationService.finish(param);
|
||||
public Result<Void> finish(@NotNull(message = "分账单ID不可为空")Long id){
|
||||
allocationService.finish(id);
|
||||
return Res.ok();
|
||||
}
|
||||
|
||||
@Operation(summary = "分账同步")
|
||||
@PostMapping("/sync")
|
||||
public Result<Void> sync(@NotNull(message = "分账单ID不可为空") Long id){
|
||||
allocationSyncService.sync(id);
|
||||
return Res.ok();
|
||||
}
|
||||
}
|
||||
|
@@ -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<AllocationResult> finish(AllocFinishParam param){
|
||||
public DaxResult<AllocationResult> finish(@RequestBody AllocFinishParam param){
|
||||
return DaxRes.ok(allocationService.finish(param));
|
||||
}
|
||||
|
||||
@Operation(summary = "分账写你查询接口")
|
||||
@Operation(summary = "分账同步接口")
|
||||
@PostMapping("/sync")
|
||||
public DaxResult<AllocSyncResult> sync(@RequestBody AllocSyncParam param){
|
||||
return DaxRes.ok(allocationSyncService.sync(param));
|
||||
}
|
||||
|
||||
@Operation(summary = "分账订单查询接口")
|
||||
@PostMapping("/query")
|
||||
public DaxResult<AllocOrderResult> query(@RequestBody QueryAllocOrderParam param){
|
||||
return DaxRes.ok(allocationService.queryAllocOrder(param));
|
||||
|
@@ -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<AllocDetail> 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<AllocDetail> details = allocationAssistService.getDetails(order.getId());
|
||||
List<AllocDetail> 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<AllocDetail> details = allocationAssistService.getDetails(allocOrder.getId());
|
||||
List<AllocDetail> details = allocOrderQueryService.getDetails(allocOrder.getId());
|
||||
|
||||
// 创建分账策略并初始化
|
||||
AbsAllocationStrategy allocationStrategy = PaymentStrategyFactory.create(allocOrder.getChannel(),AbsAllocationStrategy.class);
|
||||
|
@@ -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<AllocDetail> 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<AllocDetail> details){
|
||||
// 如果是分账结束或失败, 不更新状态
|
||||
String status = allocOrder.getStatus();
|
||||
|
||||
// 如果是分账结束或失败, 不进行对订单进行处理
|
||||
List<String> 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);
|
||||
}
|
||||
}
|
@@ -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<AllocDetail> getDetails(Long allocOrderId){
|
||||
List<AllocDetail> 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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<AllocDetail> getDetails(Long allocOrderId){
|
||||
List<AllocDetail> details = allocOrderDetailManager.findAllByOrderId(allocOrderId);
|
||||
// 过滤掉忽略的条目
|
||||
return details.stream()
|
||||
.filter(detail -> !Objects.equals(detail.getResult(), AllocDetailResultEnum.IGNORE.getCode()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
@@ -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();
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user