提交 d830ddd3 authored 作者: huyufan's avatar huyufan

确认收货处理相关借款逻辑

上级 467aa25d
......@@ -123,6 +123,8 @@ public enum PerformanceResultEnum implements ResultEnum {
NB_BANK_PAY_TYPE_ERROR(1802, "支付方式不支持"),
NB_BANK_ORDER_PAY_ERROR(1803, "宁波银行订单支付失败"),
GET_LOAN_RECORD(1901, "货主借款失败"),
;
private final int code;
private final String msg;
......
......@@ -14,10 +14,10 @@ public enum OwnerLoanAccountRunningWaterRecordEnum {
@Getter
@AllArgsConstructor
public enum RunWaterType {
APPROVE_WAIT(10, "借款"),
APPROVE_FROZEN(20, "冻结"),
APPROVE_CHILD_WRITE_OFF(30, "运单核销"),
APPROVE_THAW(40, "解冻"),
APPROVE_WAIT(80, "借款"),
APPROVE_FROZEN(90, "冻结"),
APPROVE_CHILD_WRITE_OFF(100, "运单核销"),
APPROVE_THAW(110, "解冻"),
;
private final Integer code;
......
......@@ -6,11 +6,13 @@ import cn.hutool.json.JSONUtil;
import com.clx.order.feign.OrderFeign;
import com.clx.order.vo.feign.FeignOrderInfoVO;
import com.clx.order.vo.pc.owner.OwnerQuotationDetailVO;
import com.clx.performance.constant.RedissonConstants;
import com.clx.performance.dao.OrderChildDao;
import com.clx.performance.dao.OwnerRunningWaterRecordDao;
import com.clx.performance.dao.loan.OwnerLoanAccountDao;
import com.clx.performance.dao.loan.OwnerLoanAccountRunningWaterRecordDao;
import com.clx.performance.dao.loan.OwnerRepaymentDao;
import com.clx.performance.dto.LoanBalanceDTO;
import com.clx.performance.enums.OrderGoodsOverWeightEnum;
import com.clx.performance.enums.OwnerAccountEnum;
import com.clx.performance.enums.PerformanceResultEnum;
......@@ -26,18 +28,29 @@ import com.clx.performance.model.loan.OwnerLoanAccountRunningWaterRecord;
import com.clx.performance.model.loan.OwnerRepayment;
import com.clx.performance.model.settle.SettlementDriverDetail;
import com.clx.performance.model.settle.SettlementOwnerDetail;
import com.clx.performance.param.app.OrderChildSaveParam;
import com.clx.performance.service.OrderChildService;
import com.clx.performance.service.loan.OwnerLoanRecordService;
import com.clx.performance.utils.spring.ApplicationContextUtils;
import com.clx.performance.vo.app.SaveOrderChildVO;
import com.clx.user.vo.feign.OwnerInfoFeignVO;
import com.msl.common.base.Optional;
import com.msl.common.exception.ServiceSystemException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
@Component
@AllArgsConstructor
......@@ -60,6 +73,8 @@ public class OrderChildLoanComponent {
private final OwnerLoanRecordService ownerLoanRecordService;
private final RedissonClient redissonClient;
/**
* 接单校验判断
*
......@@ -148,15 +163,19 @@ public class OrderChildLoanComponent {
}
//TODO 加锁
//查询审批通过并且未用完的借款
ownerLoanRecordService.getLoanBalance(orderChildPrice, ownerInfoFeignVO.getUserNo(), childNo);
LoanBalanceDTO param = new LoanBalanceDTO();
param.setOrderChildPrice(subtract.negate());
param.setOwnerUserNo(ownerLoanAccount.getOwnerUserNo());
param.setChildNo(childNo);
getLoanBalanceLock(param, ownerLoanRecordService.getLoanBalance(param));
}
/**
* 运单确认人借款相关处理执行
*
* @param settlementDriverDetail
* @param settlementOwnerDetail
*/
......@@ -182,11 +201,12 @@ public class OrderChildLoanComponent {
if (CollectionUtil.isEmpty(runningWaterRecordList)) {
//说明当初没借款,预付运费够,但是真实结算后,预付运费不够,走此逻辑
log.info("4.1 说明当初没借款,预付运费够,但是真实结算后,预付运费不够,走此逻辑");
try {
ownerLoanRecordService.getLoanBalance(settlementOwnerDetail.getSettlementFreight(), settlementDriverDetail.getDriverUserNo(), childNo);
} catch (Exception e) {
//TODO 钱不够需要流程卡死
}
LoanBalanceDTO param = new LoanBalanceDTO();
param.setOrderChildPrice(settlementOwnerDetail.getSettlementFreight());
param.setOwnerUserNo(settlementOwnerDetail.getOwnerUserNo());
param.setChildNo(childNo);
getLoanBalanceLock(param, ownerLoanRecordService.getLoanBalance(param));
//TODO 钱不够需要流程卡死
runningWaterRecordList = ownerLoanAccountRunningWaterRecordDao.getListByOrderNoAndRunningWaterType
(childNo, OwnerLoanAccountRunningWaterRecordEnum.RunWaterType.APPROVE_FROZEN.getCode());
childWriteOffOwnerLoanAccount(runningWaterRecordList);
......@@ -216,11 +236,15 @@ public class OrderChildLoanComponent {
BigDecimal subtract = alterationBalance.subtract(settlementOwnerDetail.getSettlementFreight());
// 冻结的借款不够了
try {
ownerLoanRecordService.getLoanBalance(subtract.negate(), settlementDriverDetail.getDriverUserNo(), childNo);
} catch (Exception e) {
//TODO 钱不够需要流程卡死
}
LoanBalanceDTO param = new LoanBalanceDTO();
param.setOrderChildPrice(subtract.negate());
param.setOwnerUserNo(settlementOwnerDetail.getOwnerUserNo());
param.setChildNo(childNo);
getLoanBalanceLock(param, ownerLoanRecordService.getLoanBalance(param));
//TODO 钱不够需要流程卡死
runningWaterRecordList = ownerLoanAccountRunningWaterRecordDao.getListByOrderNoAndRunningWaterType
(childNo, OwnerLoanAccountRunningWaterRecordEnum.RunWaterType.APPROVE_FROZEN.getCode());
log.info("4.5新查询出冻结借款记录:{}", JSONUtil.parse(runningWaterRecordList));
......@@ -347,4 +371,24 @@ public class OrderChildLoanComponent {
}
}
public void getLoanBalanceLock(LoanBalanceDTO dto, Consumer<LoanBalanceDTO> function) {
RLock lock = null;
try {
lock = redissonClient.getLock(RedissonConstants.ORDER_CHILD_LOAN_OWNER_USERID_LOCK + dto.getOwnerUserNo());
boolean flag = lock.tryLock(15, 30, TimeUnit.SECONDS);
if (!flag) {
throw new ServiceSystemException(PerformanceResultEnum.GET_LOAN_RECORD);
}
function.accept(dto);
} catch (Exception e) {
throw new ServiceSystemException(PerformanceResultEnum.GET_LOAN_RECORD, e.getMessage());
} finally {
if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
}
......@@ -10,4 +10,6 @@ public class RedissonConstants {
//货主违约结算单支付锁
public static final String BREAK_CONTRACT_SETTLEMENT_OWNER_BATCH_PAY_ID_LOCK = "clx-performance:breakContractSettlementOwner:batchPay:id:";
public static final String ORDER_CHILD_LOAN_OWNER_USERID_LOCK = "clx-performance:orderChild:loan:ownerUserId:";
}
package com.clx.performance.dto;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class LoanBalanceDTO {
private BigDecimal orderChildPrice;
private Long ownerUserNo;
private String childNo;
}
package com.clx.performance.service.impl.loan;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.metadata.IPage;
......@@ -14,6 +13,7 @@ import com.clx.performance.dao.loan.OwnerLoanAccountDao;
import com.clx.performance.dao.loan.OwnerLoanAccountRunningWaterRecordDao;
import com.clx.performance.dao.loan.OwnerLoanRecordDao;
import com.clx.performance.dao.loan.OwnerRepaymentDao;
import com.clx.performance.dto.LoanBalanceDTO;
import com.clx.performance.enums.PerformanceResultEnum;
import com.clx.performance.enums.RunningWaterTypeEnum;
import com.clx.performance.enums.loan.OwnerLoanAccountRunningWaterRecordEnum;
......@@ -41,7 +41,6 @@ import com.clx.user.feign.OwnerFeign;
import com.clx.user.vo.feign.OwnerInfoFeignVO;
import com.msl.common.base.Optional;
import com.msl.common.enums.ResultCodeEnum;
import com.msl.common.exception.ServiceSystemException;
import com.msl.common.result.Result;
import com.msl.common.utils.DateUtils;
import com.msl.document.api.feign.ContractEvidenceFeign;
......@@ -52,13 +51,17 @@ import com.msl.user.data.UserSessionData;
import com.msl.user.utils.TokenUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
/**
......@@ -95,6 +98,10 @@ public class OwnerLoanRecordServiceImpl implements OwnerLoanRecordService {
private final ContractTemplateFeign contractTemplateFeign;
private final PaymentFromConfig paymentFromConfig;
private final DataSourceTransactionManager dataSourceTransactionManager;
private final TransactionDefinition transactionDefinition;
@Override
public IPage<OwnerLoanRecordVO> pageOwnerLoanRecord(PageCarrierOwnerLoanRecordParam param) {
IPage<OwnerLoanRecord> page = ownerLoanRecordDao.pageOwnerLoanRecord(param);
......@@ -329,38 +336,48 @@ public class OwnerLoanRecordServiceImpl implements OwnerLoanRecordService {
@Override
@Transactional(rollbackFor = Exception.class)
public void getLoanBalance(BigDecimal orderChildPrice, Long userNo, String childNo) {
public Consumer<LoanBalanceDTO> getLoanBalance(LoanBalanceDTO param) {
BigDecimal orderChildPrice = param.getOrderChildPrice();
Long userNo = param.getOwnerUserNo();
String childNo = param.getChildNo();
log.info("执行借款,借款金额{}, 货主编号:{}, 运单号:{}", orderChildPrice, userNo, childNo);
//TODO 需要加锁处理
List<OwnerLoanRecord> updateList = new LinkedList<>();
List<OwnerLoanRecord> ownerLoanRecords = ownerLoanRecordDao.selectLoanBalance(userNo);
BigDecimal orderChildPriceTemp = orderChildPrice;
for (OwnerLoanRecord ownerLoanRecord : ownerLoanRecords) {
BigDecimal loanResidueBalance = ownerLoanRecord.getLoanResidueBalance();
log.info("当前借款金额:{},借款单号{},借款剩余金额{}", orderChildPriceTemp, ownerLoanRecord.getLoanNo(), loanResidueBalance);
if (loanResidueBalance.compareTo(orderChildPriceTemp) >= 0) {
log.info("当前借款单的剩余金额足够借款金额");
generateFrozenOwnerLoanRunningWater(ownerLoanRecord, childNo, orderChildPrice);
updateList.add(ownerLoanRecord.setLoanResidueBalance(loanResidueBalance.subtract(orderChildPriceTemp)));
orderChildPriceTemp = BigDecimal.ZERO;
break;
} else {
log.info("当前借款单的剩余金额不够抵扣借款金额,先进行扣除当前借款所有剩余");
generateFrozenOwnerLoanRunningWater(ownerLoanRecord, childNo, orderChildPrice);
updateList.add(ownerLoanRecord.setLoanResidueBalance(BigDecimal.ZERO));
orderChildPriceTemp = orderChildPriceTemp.subtract(loanResidueBalance);
TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
try {
List<OwnerLoanRecord> updateList = new LinkedList<>();
List<OwnerLoanRecord> ownerLoanRecords = ownerLoanRecordDao.selectLoanBalance(userNo);
BigDecimal orderChildPriceTemp = orderChildPrice;
for (OwnerLoanRecord ownerLoanRecord : ownerLoanRecords) {
BigDecimal loanResidueBalance = ownerLoanRecord.getLoanResidueBalance();
log.info("当前借款金额:{},借款单号{},借款剩余金额{}", orderChildPriceTemp, ownerLoanRecord.getLoanNo(), loanResidueBalance);
if (loanResidueBalance.compareTo(orderChildPriceTemp) >= 0) {
log.info("当前借款单的剩余金额足够借款金额");
generateFrozenOwnerLoanRunningWater(ownerLoanRecord, childNo, orderChildPrice);
updateList.add(ownerLoanRecord.setLoanResidueBalance(loanResidueBalance.subtract(orderChildPriceTemp)));
orderChildPriceTemp = BigDecimal.ZERO;
break;
} else {
log.info("当前借款单的剩余金额不够抵扣借款金额,先进行扣除当前借款所有剩余");
generateFrozenOwnerLoanRunningWater(ownerLoanRecord, childNo, orderChildPrice);
updateList.add(ownerLoanRecord.setLoanResidueBalance(BigDecimal.ZERO));
orderChildPriceTemp = orderChildPriceTemp.subtract(loanResidueBalance);
}
}
}
if (orderChildPriceTemp.compareTo(BigDecimal.ZERO) != 0) {
throw new ServiceSystemException(PerformanceResultEnum.ORDER_CHILD_SAVE_FAIL, "货主货款不足");
}
if (orderChildPriceTemp.compareTo(BigDecimal.ZERO) != 0) {
log.info("执行借款发现:货主货款不足,进行手动回滚事务");
dataSourceTransactionManager.rollback(transactionStatus);
for (OwnerLoanRecord update : updateList) {
ownerLoanRecordDao.updateEntityByKey(update);
}
log.info("执行借款成功,借款金额{}, 货主编号:{}, 运单号:{}", orderChildPrice, userNo, childNo);
}
for (OwnerLoanRecord update : updateList) {
ownerLoanRecordDao.updateEntityByKey(update);
}
log.info("执行借款成功,借款金额{}, 货主编号:{}, 运单号:{}", orderChildPrice, userNo, childNo);
} catch (Exception e) {
log.info("借款产生异常,异常信息:{}", ExceptionUtils.getThrowableCount(e));
dataSourceTransactionManager.rollback(transactionStatus);
}
return null;
}
public void generateFrozenOwnerLoanRunningWater(OwnerLoanRecord ownerLoanRecord, String childNo, BigDecimal orderChildPrice) {
log.info("13.生成借款冻结流水");
......
package com.clx.performance.service.loan;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.clx.performance.dto.LoanBalanceDTO;
import com.clx.performance.param.pc.loan.carrier.CarrierOwnerLoanRecordApproveParam;
import com.clx.performance.param.pc.loan.carrier.PageCarrierOwnerLoanRecordParam;
import com.clx.performance.param.pc.loan.carrier.PageOwnerLoanRecordOfOwner;
......@@ -12,7 +13,7 @@ import com.clx.performance.vo.pc.loan.carrier.OwnerOrderPaymentDetailVO;
import com.clx.performance.vo.pc.loan.owner.OwnerLoanRecordDetail;
import com.clx.performance.vo.pc.loan.carrier.CarrierTransferPaymentDetailVO;
import java.math.BigDecimal;
import java.util.function.Consumer;
/**
* @author kavin
......@@ -38,5 +39,5 @@ public interface OwnerLoanRecordService {
String savePaymentApplicationForm(ExportPaymentApplicationFormParam param);
void getLoanBalance(BigDecimal orderChildPrice, Long userNo, String childNo);
Consumer<LoanBalanceDTO> getLoanBalance(LoanBalanceDTO param);
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论