fix 分转元和元转分改为BigDecimal, 防止精度丢失

This commit is contained in:
DaxPay
2024-05-23 20:37:28 +08:00
parent 204a143b0f
commit 703051a83e
15 changed files with 212 additions and 141 deletions

View File

@@ -18,7 +18,8 @@ public enum PaymentTypeEnum {
PAY("pay","支付"),
REFUND("refund","退款"),
TRANSFER("transfer","转账");
TRANSFER("transfer","转账"),
ALLOCATION("allocation","分账");
private final String code;
private final String name;

View File

@@ -8,6 +8,7 @@ import cn.daxpay.single.service.code.AliPayCode;
import cn.daxpay.single.service.common.local.PaymentContextLocal;
import cn.daxpay.single.service.core.order.allocation.entity.AllocationOrder;
import cn.daxpay.single.service.core.order.allocation.entity.AllocationOrderDetail;
import cn.daxpay.single.util.PayUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import com.alipay.api.AlipayResponse;
@@ -55,7 +56,7 @@ public class AliPayAllocationService {
List<OpenApiRoyaltyDetailInfoPojo> royaltyParameters = orderDetails.stream()
.map(o -> {
OpenApiRoyaltyDetailInfoPojo infoPojo = new OpenApiRoyaltyDetailInfoPojo();
infoPojo.setAmount(String.valueOf(o.getAmount() / 100.0));
infoPojo.setAmount(PayUtil.conversionAmount(o.getAmount()).toString());
infoPojo.setTransIn(o.getReceiverAccount());
return infoPojo;
})
@@ -89,7 +90,7 @@ public class AliPayAllocationService {
List<OpenApiRoyaltyDetailInfoPojo> royaltyParameters = orderDetails.stream()
.map(o -> {
OpenApiRoyaltyDetailInfoPojo infoPojo = new OpenApiRoyaltyDetailInfoPojo();
infoPojo.setAmount(String.valueOf(o.getAmount() / 100.0));
infoPojo.setAmount(PayUtil.conversionAmount(o.getAmount()).toString());
infoPojo.setTransIn(o.getReceiverAccount());
return infoPojo;
})

View File

@@ -12,9 +12,10 @@ import cn.daxpay.single.service.core.channel.alipay.dao.AliReconcileBillTotalMan
import cn.daxpay.single.service.core.channel.alipay.entity.AliReconcileBillDetail;
import cn.daxpay.single.service.core.channel.alipay.entity.AliReconcileBillTotal;
import cn.daxpay.single.service.core.order.reconcile.dao.ReconcileFileManager;
import cn.daxpay.single.service.core.order.reconcile.entity.ReconcileTradeDetail;
import cn.daxpay.single.service.core.order.reconcile.entity.ReconcileFile;
import cn.daxpay.single.service.core.order.reconcile.entity.ReconcileOrder;
import cn.daxpay.single.service.core.order.reconcile.entity.ReconcileTradeDetail;
import cn.daxpay.single.util.PayUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.text.csv.CsvReader;
@@ -39,6 +40,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@@ -174,9 +176,7 @@ public class AliPayReconcileService {
*/
private ReconcileTradeDetail convert(AliReconcileBillDetail billDetail){
// 金额
String orderAmount = billDetail.getOrderAmount();
double v = Double.parseDouble(orderAmount) * 100;
int amount = Math.abs(((int) v));
int amount = PayUtil.convertCentAmount(new BigDecimal(billDetail.getOrderAmount()));
// 默认为支付对账记录
ReconcileTradeDetail reconcileTradeDetail = new ReconcileTradeDetail()

View File

@@ -6,6 +6,7 @@ import cn.daxpay.single.service.code.AliPayCode;
import cn.daxpay.single.service.common.context.RefundLocal;
import cn.daxpay.single.service.common.local.PaymentContextLocal;
import cn.daxpay.single.service.core.order.refund.entity.RefundOrder;
import cn.daxpay.single.util.PayUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.response.AlipayTradeRefundResponse;
@@ -36,7 +37,7 @@ public class AliPayRefundService {
refundModel.setOutTradeNo(refundOrder.getOrderNo());
refundModel.setOutRequestNo(refundOrder.getRefundNo());
// 金额转换
String refundAmount = String.valueOf(refundOrder.getAmount()*0.01);
String refundAmount = PayUtil.conversionAmount(refundOrder.getAmount()).toString();
refundModel.setRefundAmount(refundAmount);
// 设置退款信息

View File

@@ -6,8 +6,8 @@ import cn.daxpay.single.param.channel.AliPayParam;
import cn.daxpay.single.param.payment.pay.PayParam;
import cn.daxpay.single.service.code.AliPayCode;
import cn.daxpay.single.service.code.AliPayWay;
import cn.daxpay.single.service.common.context.PayLocal;
import cn.daxpay.single.service.common.context.NoticeLocal;
import cn.daxpay.single.service.common.context.PayLocal;
import cn.daxpay.single.service.common.local.PaymentContextLocal;
import cn.daxpay.single.service.core.channel.alipay.entity.AliPayConfig;
import cn.daxpay.single.service.core.order.pay.entity.PayOrder;
@@ -71,7 +71,7 @@ public class AliPayService {
* 调起支付
*/
public void pay(PayOrder payOrder, AliPayParam aliPayParam, AliPayConfig alipayConfig) {
Integer amount = payOrder.getAmount();
String amount = PayUtil.conversionAmount(payOrder.getAmount()).toString();
String payBody = null;
// 异步线程存储
PayLocal payInfo = PaymentContextLocal.get().getPayInfo();
@@ -102,12 +102,12 @@ public class AliPayService {
/**
* wap支付
*/
public String wapPay(int amount, PayOrder payOrder, AliPayConfig alipayConfig) {
public String wapPay(String amount, PayOrder payOrder, AliPayConfig alipayConfig) {
NoticeLocal noticeInfo = PaymentContextLocal.get().getNoticeInfo();
AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
model.setSubject(payOrder.getTitle());
model.setOutTradeNo(payOrder.getOrderNo());
model.setTotalAmount(String.valueOf(amount*0.01));
model.setTotalAmount(amount);
// 过期时间
model.setTimeExpire(PayUtil.getAliTimeExpire(payOrder.getExpiredTime()));
model.setProductCode(AliPayCode.QUICK_WAP_PAY);
@@ -141,7 +141,7 @@ public class AliPayService {
/**
* app支付
*/
public String appPay(int amount, PayOrder payOrder, AliPayConfig alipayConfig) {
public String appPay(String amount, PayOrder payOrder, AliPayConfig alipayConfig) {
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
model.setSubject(payOrder.getTitle());
@@ -149,7 +149,7 @@ public class AliPayService {
model.setOutTradeNo(payOrder.getOrderNo());
// 过期时间
model.setTimeExpire(PayUtil.getAliTimeExpire(payOrder.getExpiredTime()));
model.setTotalAmount(String.valueOf(amount*0.01));
model.setTotalAmount(amount);
// 是否分账
if (payOrder.getAllocation()){
ExtendParams extendParams = new ExtendParams();
@@ -171,14 +171,14 @@ public class AliPayService {
/**
* PC支付
*/
public String webPay(int amount, PayOrder payOrder, AliPayConfig alipayConfig) {
public String webPay(String amount, PayOrder payOrder, AliPayConfig alipayConfig) {
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
model.setSubject(payOrder.getTitle());
model.setOutTradeNo(payOrder.getOrderNo());
// 过期时间
model.setTimeExpire(PayUtil.getAliTimeExpire(payOrder.getExpiredTime()));
model.setTotalAmount(String.valueOf(amount*0.01));
model.setTotalAmount(amount);
// 目前仅支持FAST_INSTANT_TRADE_PAY
model.setProductCode(AliPayCode.FAST_INSTANT_TRADE_PAY);
@@ -209,11 +209,11 @@ public class AliPayService {
/**
* 二维码支付(扫码支付)
*/
public String qrCodePay(int amount, PayOrder payOrder, AliPayConfig alipayConfig) {
public String qrCodePay(String amount, PayOrder payOrder, AliPayConfig alipayConfig) {
AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
model.setSubject(payOrder.getTitle());
model.setOutTradeNo(payOrder.getOrderNo());
model.setTotalAmount(String.valueOf(amount*0.01));
model.setTotalAmount(amount);
// 是否分账
if (payOrder.getAllocation()){
ExtendParams extendParams = new ExtendParams();
@@ -237,7 +237,7 @@ public class AliPayService {
/**
* 付款码支付
*/
public void barCode(int amount, PayOrder payOrder, AliPayParam aliPayParam, AliPayConfig alipayConfig) {
public void barCode(String amount, PayOrder payOrder, AliPayParam aliPayParam, AliPayConfig alipayConfig) {
PayLocal payInfo = PaymentContextLocal.get().getPayInfo();
AlipayTradePayModel model = new AlipayTradePayModel();
@@ -253,7 +253,7 @@ public class AliPayService {
}
// 过期时间
model.setTimeExpire(PayUtil.getAliTimeExpire(payOrder.getExpiredTime()));
model.setTotalAmount(String.valueOf(amount*0.01));
model.setTotalAmount(amount);
try {
AlipayTradePayResponse response = AliPayApi.tradePayToResponse(model, alipayConfig.getNotifyUrl());

View File

@@ -7,6 +7,7 @@ import cn.daxpay.single.service.common.local.PaymentContextLocal;
import cn.daxpay.single.service.core.order.refund.entity.RefundOrder;
import cn.daxpay.single.service.sdk.union.api.UnionPayKit;
import cn.daxpay.single.service.sdk.union.bean.UnionRefundOrder;
import cn.daxpay.single.util.PayUtil;
import com.egzosn.pay.union.bean.UnionRefundResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -31,8 +32,8 @@ public class UnionPayRefundService {
public void refund(RefundOrder refundOrder, UnionPayKit unionPayKit) {
// 金额转换
BigDecimal refundAmount = BigDecimal.valueOf(refundOrder.getAmount() * 0.01);
BigDecimal orderAmount = BigDecimal.valueOf(refundOrder.getOrderAmount() * 0.01);
BigDecimal refundAmount = PayUtil.conversionAmount(refundOrder.getAmount());
BigDecimal orderAmount =PayUtil.conversionAmount(refundOrder.getOrderAmount());
UnionRefundOrder unionRefundOrder = new UnionRefundOrder();
unionRefundOrder.setRefundNo(refundOrder.getRefundNo());

View File

@@ -12,6 +12,7 @@ import cn.daxpay.single.service.core.channel.union.entity.UnionPayConfig;
import cn.daxpay.single.service.core.order.pay.entity.PayOrder;
import cn.daxpay.single.service.sdk.union.api.UnionPayKit;
import cn.daxpay.single.service.sdk.union.bean.UnionPayOrder;
import cn.daxpay.single.util.PayUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
@@ -66,9 +67,8 @@ public class UnionPayService {
* 支付接口
*/
public void pay(PayOrder payOrder, UnionPayParam unionPayParam, UnionPayKit unionPayKit){
Integer amount = payOrder.getAmount();
BigDecimal totalFee = BigDecimal.valueOf(amount * 0.01);
PayLocal payInfo = PaymentContextLocal.get().getPayInfo();;
BigDecimal totalFee = PayUtil.conversionAmount(payOrder.getAmount());
PayLocal payInfo = PaymentContextLocal.get().getPayInfo();
String payBody = null;
PayMethodEnum payMethodEnum = PayMethodEnum.findByCode(payOrder.getMethod());
@@ -198,6 +198,5 @@ public class UnionPayService {
String errMsg = MapUtil.getStr(result, UnionPayCode.RESP_MSG);
throw new PayFailureException(errMsg);
}
}
}

View File

@@ -14,9 +14,10 @@ import cn.daxpay.single.service.core.channel.wechat.entity.WxReconcileBillDetail
import cn.daxpay.single.service.core.channel.wechat.entity.WxReconcileBillTotal;
import cn.daxpay.single.service.core.channel.wechat.entity.WxReconcileFundFlowDetail;
import cn.daxpay.single.service.core.order.reconcile.dao.ReconcileFileManager;
import cn.daxpay.single.service.core.order.reconcile.entity.ReconcileTradeDetail;
import cn.daxpay.single.service.core.order.reconcile.entity.ReconcileFile;
import cn.daxpay.single.service.core.order.reconcile.entity.ReconcileOrder;
import cn.daxpay.single.service.core.order.reconcile.entity.ReconcileTradeDetail;
import cn.daxpay.single.util.PayUtil;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.io.IoUtil;
@@ -41,6 +42,7 @@ import org.springframework.transaction.annotation.Transactional;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
@@ -195,9 +197,7 @@ public class WechatPayReconcileService{
// 支付
if (Objects.equals(billDetail.getStatus(), "SUCCESS")){
// 金额
String orderAmount = billDetail.getOrderAmount();
double v = Double.parseDouble(orderAmount) * 100;
int amount = Math.abs(((int) v));
int amount = PayUtil.convertCentAmount(new BigDecimal( billDetail.getOrderAmount()));
reconcileTradeDetail.setType(ReconcileTradeEnum.PAY.getCode())
.setAmount(amount);
}

View File

@@ -3,19 +3,15 @@ package cn.daxpay.single.service.core.payment.allocation.service;
import cn.bootx.platform.common.core.exception.DataNotExistException;
import cn.bootx.platform.common.core.exception.RepetitiveOperationException;
import cn.bootx.platform.common.core.util.CollUtil;
import cn.daxpay.single.code.AllocDetailResultEnum;
import cn.daxpay.single.code.AllocOrderResultEnum;
import cn.daxpay.single.code.AllocOrderStatusEnum;
import cn.daxpay.single.code.PayOrderAllocStatusEnum;
import cn.daxpay.single.exception.pay.PayFailureException;
import cn.daxpay.single.param.payment.allocation.AllocFinishParam;
import cn.daxpay.single.param.payment.allocation.AllocSyncParam;
import cn.daxpay.single.param.payment.allocation.AllocationParam;
import cn.daxpay.single.param.payment.allocation.QueryAllocOrderParam;
import cn.daxpay.single.result.allocation.AllocOrderDetailResult;
import cn.daxpay.single.result.allocation.AllocOrderResult;
import cn.daxpay.single.result.allocation.AllocationResult;
import cn.daxpay.single.result.allocation.AllocationSyncResult;
import cn.daxpay.single.service.common.local.PaymentContextLocal;
import cn.daxpay.single.service.core.order.allocation.convert.AllocationConvert;
import cn.daxpay.single.service.core.order.allocation.dao.AllocationOrderDetailManager;
@@ -31,7 +27,6 @@ import cn.daxpay.single.service.core.order.pay.service.PayOrderQueryService;
import cn.daxpay.single.service.core.payment.allocation.dao.AllocationGroupManager;
import cn.daxpay.single.service.core.payment.allocation.entity.AllocationGroup;
import cn.daxpay.single.service.core.payment.allocation.factory.AllocationFactory;
import cn.daxpay.single.service.core.payment.notice.service.ClientNoticeService;
import cn.daxpay.single.service.dto.allocation.AllocationGroupReceiverResult;
import cn.daxpay.single.service.func.AbsAllocationStrategy;
import com.baomidou.lock.LockInfo;
@@ -39,8 +34,6 @@ import com.baomidou.lock.LockTemplate;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.List;
@@ -71,9 +64,9 @@ public class AllocationService {
private final PayOrderQueryService payOrderQueryService;
private final LockTemplate lockTemplate;
private final AllocationOrderExtraManager allocationOrderExtraManager;
private final ClientNoticeService clientNoticeService;
private final LockTemplate lockTemplate;
/**
@@ -249,101 +242,6 @@ public class AllocationService {
.setStatus(allocationOrder.getStatus());
}
/**
* 分账同步, 开启一个新的事务, 不受外部抛出异常的影响
*/
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public AllocationSyncResult sync(AllocSyncParam param) {
// 获取分账订单
AllocationOrder allocationOrder = null;
if (Objects.nonNull(param.getAllocationNo())){
allocationOrder = allocationOrderManager.findByAllocationNo(param.getAllocationNo())
.orElseThrow(() -> new DataNotExistException("分账单不存在"));
}
if (Objects.isNull(allocationOrder)){
allocationOrder = allocationOrderManager.findByAllocationNo(param.getBizAllocationNo())
.orElseThrow(() -> new DataNotExistException("分账单不存在"));
}
this.sync(allocationOrder);
return new AllocationSyncResult();
}
/**
* 分账同步
*/
public void sync(AllocationOrder allocationOrder){
LockInfo lock = lockTemplate.lock("payment:allocation:" + allocationOrder.getOrderId(),10000,200);
if (Objects.isNull(lock)){
throw new RepetitiveOperationException("分账同步中,请勿重复操作");
}
try {
List<AllocationOrderDetail> detailList = allocationOrderDetailManager.findAllByOrderId(allocationOrder.getId());
// 获取分账策略
AbsAllocationStrategy allocationStrategy = AllocationFactory.create(allocationOrder.getChannel());
allocationStrategy.initParam(allocationOrder, detailList);
// 分账完结预处理
allocationStrategy.doBeforeHandler();
allocationStrategy.doSync();
// TODO 保存分账同步记录
// 根据订单明细更新订单的状态和处理结果
this.updateOrderStatus(allocationOrder, detailList);
} finally {
lockTemplate.releaseLock(lock);
}
}
/**
* 根据订单明细更新订单的状态和处理结果, 如果订单是分账结束或失败, 不更新状态
* TODO 是否多次同步会产生多次变动, 注意处理多次推送通知的问题, 目前是
*/
private void updateOrderStatus(AllocationOrder allocationOrder, List<AllocationOrderDetail> details){
// 如果是分账结束或失败, 不更新状态
String status = allocationOrder.getStatus();
// 如果是分账结束或失败, 不进行对订单进行处理
List<String> list = Arrays.asList(AllocOrderStatusEnum.FINISH.getCode(), AllocOrderStatusEnum.FINISH_FAILED.getCode());
if (!list.contains(status)){
// 判断明细状态. 获取成功和失败的
long successCount = details.stream()
.map(AllocationOrderDetail::getResult)
.filter(AllocDetailResultEnum.SUCCESS.getCode()::equals)
.count();
long failCount = details.stream()
.map(AllocationOrderDetail::getResult)
.filter(AllocDetailResultEnum.FAIL.getCode()::equals)
.count();
// 成功和失败都为0 表示进行中
if (successCount == 0 && failCount == 0){
allocationOrder.setStatus(AllocOrderStatusEnum.ALLOCATION_PROCESSING.getCode())
.setResult(AllocOrderResultEnum.ALL_PENDING.getCode());
} else {
if (failCount == details.size()){
// 全部失败
allocationOrder.setStatus(AllocOrderStatusEnum.ALLOCATION_END.getCode())
.setResult(AllocOrderResultEnum.ALL_FAILED.getCode());
} else if (successCount == details.size()){
// 全部成功
allocationOrder.setStatus(AllocOrderStatusEnum.ALLOCATION_END.getCode())
.setResult(AllocOrderResultEnum.ALL_SUCCESS.getCode());
} else {
// 部分成功
allocationOrder.setStatus(AllocOrderStatusEnum.ALLOCATION_END.getCode())
.setResult(AllocOrderResultEnum.PART_SUCCESS.getCode());
}
}
}
allocationOrderDetailManager.updateAllById(details);
allocationOrderManager.updateById(allocationOrder);
// 如果状态为完成, 发送通知
if (Objects.equals(AllocOrderStatusEnum.ALLOCATION_END.getCode(), allocationOrder.getStatus())){
// 发送通知
clientNoticeService.registerAllocNotice(allocationOrder, null, details);
}
}
/**
* 获取并检查支付订单
*/

View File

@@ -0,0 +1,141 @@
package cn.daxpay.single.service.core.payment.allocation.service;
import cn.bootx.platform.common.core.exception.DataNotExistException;
import cn.bootx.platform.common.core.exception.RepetitiveOperationException;
import cn.daxpay.single.code.AllocDetailResultEnum;
import cn.daxpay.single.code.AllocOrderResultEnum;
import cn.daxpay.single.code.AllocOrderStatusEnum;
import cn.daxpay.single.param.payment.allocation.AllocSyncParam;
import cn.daxpay.single.result.allocation.AllocationSyncResult;
import cn.daxpay.single.service.core.order.allocation.dao.AllocationOrderDetailManager;
import cn.daxpay.single.service.core.order.allocation.dao.AllocationOrderManager;
import cn.daxpay.single.service.core.order.allocation.entity.AllocationOrder;
import cn.daxpay.single.service.core.order.allocation.entity.AllocationOrderDetail;
import cn.daxpay.single.service.core.payment.allocation.factory.AllocationFactory;
import cn.daxpay.single.service.core.payment.notice.service.ClientNoticeService;
import cn.daxpay.single.service.func.AbsAllocationStrategy;
import com.baomidou.lock.LockInfo;
import com.baomidou.lock.LockTemplate;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
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 ClientNoticeService clientNoticeService;
private final AllocationOrderManager allocationOrderManager;
private final LockTemplate lockTemplate;
private final AllocationOrderDetailManager allocationOrderDetailManager;
/**
* 分账同步, 开启一个新的事务, 不受外部抛出异常的影响
*/
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public AllocationSyncResult sync(AllocSyncParam param) {
// 获取分账订单
AllocationOrder allocationOrder = null;
if (Objects.nonNull(param.getAllocationNo())){
allocationOrder = allocationOrderManager.findByAllocationNo(param.getAllocationNo())
.orElseThrow(() -> new DataNotExistException("分账单不存在"));
}
if (Objects.isNull(allocationOrder)){
allocationOrder = allocationOrderManager.findByAllocationNo(param.getBizAllocationNo())
.orElseThrow(() -> new DataNotExistException("分账单不存在"));
}
this.sync(allocationOrder);
return new AllocationSyncResult();
}
/**
* 分账同步
*/
public void sync(AllocationOrder allocationOrder){
LockInfo lock = lockTemplate.lock("payment:allocation:" + allocationOrder.getOrderId(),10000,200);
if (Objects.isNull(lock)){
throw new RepetitiveOperationException("分账同步中,请勿重复操作");
}
try {
List<AllocationOrderDetail> detailList = allocationOrderDetailManager.findAllByOrderId(allocationOrder.getId());
// 获取分账策略
AbsAllocationStrategy allocationStrategy = AllocationFactory.create(allocationOrder.getChannel());
allocationStrategy.initParam(allocationOrder, detailList);
// 分账完结预处理
allocationStrategy.doBeforeHandler();
allocationStrategy.doSync();
// TODO 保存分账同步记录
// 根据订单明细更新订单的状态和处理结果
this.updateOrderStatus(allocationOrder, detailList);
} finally {
lockTemplate.releaseLock(lock);
}
}
/**
* 根据订单明细更新订单的状态和处理结果, 如果订单是分账结束或失败, 不更新状态
* TODO 是否多次同步会产生多次变动, 注意处理多次推送通知的问题, 目前是
*/
private void updateOrderStatus(AllocationOrder allocationOrder, List<AllocationOrderDetail> details){
// 如果是分账结束或失败, 不更新状态
String status = allocationOrder.getStatus();
// 如果是分账结束或失败, 不进行对订单进行处理
List<String> list = Arrays.asList(AllocOrderStatusEnum.FINISH.getCode(), AllocOrderStatusEnum.FINISH_FAILED.getCode());
if (!list.contains(status)){
// 判断明细状态. 获取成功和失败的
long successCount = details.stream()
.map(AllocationOrderDetail::getResult)
.filter(AllocDetailResultEnum.SUCCESS.getCode()::equals)
.count();
long failCount = details.stream()
.map(AllocationOrderDetail::getResult)
.filter(AllocDetailResultEnum.FAIL.getCode()::equals)
.count();
// 成功和失败都为0 表示进行中
if (successCount == 0 && failCount == 0){
allocationOrder.setStatus(AllocOrderStatusEnum.ALLOCATION_PROCESSING.getCode())
.setResult(AllocOrderResultEnum.ALL_PENDING.getCode());
} else {
if (failCount == details.size()){
// 全部失败
allocationOrder.setStatus(AllocOrderStatusEnum.ALLOCATION_END.getCode())
.setResult(AllocOrderResultEnum.ALL_FAILED.getCode());
} else if (successCount == details.size()){
// 全部成功
allocationOrder.setStatus(AllocOrderStatusEnum.ALLOCATION_END.getCode())
.setResult(AllocOrderResultEnum.ALL_SUCCESS.getCode());
} else {
// 部分成功
allocationOrder.setStatus(AllocOrderStatusEnum.ALLOCATION_END.getCode())
.setResult(AllocOrderResultEnum.PART_SUCCESS.getCode());
}
}
}
allocationOrderDetailManager.updateAllById(details);
allocationOrderManager.updateById(allocationOrder);
// 如果状态为完成, 发送通知
if (Objects.equals(AllocOrderStatusEnum.ALLOCATION_END.getCode(), allocationOrder.getStatus())){
// 发送通知
clientNoticeService.registerAllocNotice(allocationOrder, null, details);
}
}
}

View File

@@ -2,6 +2,7 @@ package cn.daxpay.single.service.core.record.sync.entity;
import cn.bootx.platform.common.core.function.EntityBaseFunction;
import cn.bootx.platform.common.mybatisplus.base.MpCreateEntity;
import cn.daxpay.single.code.AllocOrderStatusEnum;
import cn.daxpay.single.code.PayChannelEnum;
import cn.daxpay.single.code.RefundSyncStatusEnum;
import cn.daxpay.single.code.PaySyncStatusEnum;
@@ -46,6 +47,7 @@ public class PaySyncRecord extends MpCreateEntity implements EntityBaseFunction<
* 三方支付返回状态
* @see PaySyncStatusEnum
* @see RefundSyncStatusEnum
* @see AllocOrderStatusEnum
*/
@DbColumn(comment = "网关返回状态")
private String outTradeStatus;

View File

@@ -1,12 +1,12 @@
package cn.daxpay.single.service.handler.excel;
import cn.daxpay.single.util.PayUtil;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* 金额分转元
@@ -23,8 +23,7 @@ public class AmountConverter implements Converter<Integer> {
if (value == null){
return new WriteCellData<>("");
}
BigDecimal divide = BigDecimal.valueOf(value)
.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP);
BigDecimal divide = PayUtil.conversionAmount(value);
return new WriteCellData<>(divide);
}
}

View File

@@ -4,6 +4,7 @@ import cn.daxpay.single.code.AllocOrderStatusEnum;
import cn.daxpay.single.service.core.order.allocation.dao.AllocationOrderManager;
import cn.daxpay.single.service.core.order.allocation.entity.AllocationOrder;
import cn.daxpay.single.service.core.payment.allocation.service.AllocationService;
import cn.daxpay.single.service.core.payment.allocation.service.AllocationSyncService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
@@ -23,6 +24,7 @@ public class AllocationSyncTask implements Job {
private final AllocationOrderManager allocationOrderManager;
private final AllocationSyncService allocationSyncService;
private final AllocationService allocationService;
/**
@@ -34,7 +36,7 @@ public class AllocationSyncTask implements Job {
try {
// 分账中走同步逻辑
if (allocationOrder.getStatus().equals(AllocOrderStatusEnum.ALLOCATION_PROCESSING.getCode())) {
allocationService.sync(allocationOrder);
allocationSyncService.sync(allocationOrder);
}
// 如果分账结束, 调用自动完结逻辑
if (allocationOrder.getStatus().equals(AllocOrderStatusEnum.ALLOCATION_END.getCode())) {