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

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

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