Commit e350da83 by jianan

新单跟进135

parent 4a99383b
......@@ -28,6 +28,7 @@ import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
......@@ -137,6 +138,28 @@ public class ApiCommissionController {
entities.add(entity);
}
// 保存来佣数据
commissionService.saveBatch(entities);
// todo 6. 异步触发比对任务(事务提交后执行)
// TransactionSynchronizationManager.registerSynchronization(
// new TransactionSynchronization() {
// @Override
// public void afterCommit() {
// // 主事务提交后再执行异步任务
// commissionComareBatch(entities);
// }
// }
// );
}
/**
* 异步执行来佣对比(有独立事务)
*/
@Async("commonAsyncExecutor")
@Transactional(rollbackFor = Exception.class)
public void commissionComareBatch(List<Commission> entities) {
// 根据导入的来佣获取保单号集合
List<String> policyNoList = entities.stream()
.map(Commission::getPolicyNo)
......@@ -146,12 +169,7 @@ public class ApiCommissionController {
.in(CommissionExpected::getPolicyNo, policyNoList)
.list();
// 校验导入的来佣是否与预计来佣一致
for (Commission commission : entities) {
String policyNo = commission.getPolicyNo();
Integer commissionPeriod = commission.getCommissionPeriod();
String commissionName = commission.getCommissionName();
// 查询预计来佣
CommissionExpected commissionExpected;
try {
......@@ -165,22 +183,12 @@ public class ApiCommissionController {
commission.setRemark(e.getMessage());
}
}
// 保存来佣数据
commissionService.saveBatch(entities);
// 更新预计来佣状态
commissionExpectedService.updateBatchById(expectedList);
}
private static CommissionExpected getCommissionExpected(List<CommissionExpected> expectedList, String policyNo, Integer commissionPeriod, String commissionName) {
return expectedList.stream()
.filter(item -> item.getPolicyNo().equals(policyNo)
&& commissionPeriod.equals(item.getCommissionPeriod())
&& commissionName.equals(item.getCommissionName()))
.findFirst()
.orElse(null);
}
/**
* 生成可出账(发佣)记录,支持手动复选框选择
*
......
package com.yd.csf.service.service;
import com.yd.csf.service.enums.CommissionStatusEnum;
import com.yd.csf.service.model.Commission;
import com.yd.csf.service.model.CommissionExpected;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
@Service
@Slf4j
public class CommissionAsyncService {
@Resource
private CommissionExpectedService commissionExpectedService;
@Resource
private CommissionService commissionService;
@Async("commonAsyncExecutor")
@Transactional(rollbackFor = Exception.class)
public void commissionCompareBatch(List<Commission> entities) {
// 比对逻辑...
log.info("开始异步比对,数据量:{}", entities.size());
List<String> policyNoList = entities.stream()
.map(Commission::getPolicyNo)
.collect(Collectors.toList());
List<CommissionExpected> expectedList = commissionExpectedService.lambdaQuery()
.in(CommissionExpected::getPolicyNo, policyNoList)
.list();
// 执行比对...
}
public void commissionCompare(Commission commission) {
log.info("开始执行比对事务,来佣ID: {}, 保单号: {}",
commission.getId(), commission.getPolicyNo());
CommissionExpected commissionExpected;
try {
commissionExpected = commissionService.queryByCommission(commission);
// 对比预计来佣
commissionService.compareWithExpected(commission.getPremium(), commission, commissionExpected);
commissionExpectedService.updateById(commissionExpected);
// 比对成功,更新状态
commission.setStatus(CommissionStatusEnum.COMPARE_SUCCESS.getItemValue());
} catch (Exception e) {
// 预计来佣不存在或比对失败
commission.setStatus(CommissionStatusEnum.COMPARE_FAIL.getItemValue());
commission.setRemark(e.getMessage());
log.warn("来佣比对失败,保单号: {},原因: {}",
commission.getPolicyNo(), e.getMessage());
}
// 更新来佣的比对状态(在比对事务中)
commissionService.updateById(commission);
}
}
......@@ -12,6 +12,7 @@ import com.yd.common.enums.CommonEnum;
import com.yd.common.enums.ResultCode;
import com.yd.common.exception.BusinessException;
import com.yd.common.utils.RandomStringGenerator;
import com.yd.common.utils.RedisUtil;
import com.yd.csf.service.dto.*;
import com.yd.csf.service.enums.CommissionExpectedStatusEnum;
import com.yd.csf.service.enums.CommissionStatusEnum;
......@@ -25,14 +26,19 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
......@@ -62,7 +68,10 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
private CommissionEditRecordService commissionEditRecordService;
@Resource
private CommissionCompareRecordService commissionCompareRecordService;
@Resource
private CommissionAsyncService commissionAsyncService;
@Resource
private RedissonClient redissonClient;
@Override
public QueryWrapper<Commission> getQueryWrapper(CommissionQueryRequest commissionQueryRequest) {
......@@ -110,13 +119,74 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
}
@Override
@Transactional(rollbackFor = Exception.class)
@Transactional(rollbackFor = Exception.class) // 主事务
public Boolean updateCommission(CommissionUpdateRequest commissionUpdateRequest) {
String lockKey = "COMMISSION_LOCK:" + commissionUpdateRequest.getCommissionBizId();
RLock lock = redissonClient.getLock(lockKey);
try {
// 竞争锁
boolean res = lock.tryLock(3, 15, TimeUnit.SECONDS);
if (!res) {
log.warn("获取分布式锁失败,commissionBizId: {}", commissionUpdateRequest.getCommissionBizId());
throw new BusinessException("系统繁忙,请稍后重试");
}
String commissionBizId = commissionUpdateRequest.getCommissionBizId();
Commission commission = this.getOne(new QueryWrapper<Commission>().eq("commission_biz_id", commissionBizId));
Commission commission = this.getOne(new QueryWrapper<Commission>()
.eq("commission_biz_id", commissionBizId));
if (commission == null) {
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "未找到该来佣记录");
}
BigDecimal amount = commission.getAmount();
BigDecimal requestAmount = commissionUpdateRequest.getAmount();
// 1. 执行主更新事务(这个方法将在当前事务中执行)
Boolean updateResult = doUpdateCommissionInTransaction(commission, commissionUpdateRequest);
// 没改金额,则不比对
if (amount.compareTo(requestAmount) != 0) {
// 2. 注册事务同步器,在主事务提交后执行比对
TransactionSynchronizationManager.registerSynchronization(
new TransactionSynchronization() {
@Override
public void afterCommit() {
try {
// 重新查询最新的来佣数据,确保获取已提交的数据
Commission freshCommission = getOne(new QueryWrapper<Commission>()
.eq("commission_biz_id", commissionUpdateRequest.getCommissionBizId()));
if (freshCommission != null) {
// 3. 执行独立的比对事务
commissionAsyncService.commissionCompare(freshCommission);
}
} catch (Exception e) {
// 比对失败不影响主事务,记录日志即可
log.error("主事务提交后,比对操作执行失败,commissionBizId: {}",
commissionUpdateRequest.getCommissionBizId(), e);
}
}
}
);
}
return updateResult;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("更新来佣记录时,获取锁被中断", e);
throw new BusinessException("操作被中断");
} finally {
if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
}
/**
* 主事务中的更新操作
*/
private Boolean doUpdateCommissionInTransaction(Commission commission, CommissionUpdateRequest commissionUpdateRequest) {
// 获取当前登录用户
AuthUserDto currentLoginUser = SecurityUtil.getCurrentLoginUser();
String loginUserId = currentLoginUser.getId().toString();
......@@ -128,23 +198,12 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
BeanUtils.copyProperties(commissionUpdateRequest, commission, "id", "commissionBizId");
commission.setUpdaterId(loginUserId);
commission.setUpdateTime(new Date());
// 先更新来佣属性
// 先更新来佣属性(在主事务中)
this.updateById(commission);
// 查询预计来佣
CommissionExpected commissionExpected;
try {
commissionExpected = queryByCommission(commission);
// 对比预计来佣
compareWithExpected(commission.getPremium(), commission, commissionExpected);
commissionExpectedService.updateById(commissionExpected);
} catch (Exception e) {
// 预计来佣不存在,来佣状态设置为 比对失败
commission.setStatus(CommissionStatusEnum.COMPARE_FAIL.getItemValue());
commission.setRemark(e.getMessage());
}
// 更新比对信息
return this.updateById(commission);
// 返回true表示主事务成功
return true;
}
private void saveUpdateCommissionRecord(Commission commission, CommissionUpdateRequest commissionUpdateRequest, AuthUserDto currentLoginUser) {
......@@ -470,18 +529,17 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
}
}
// 查询预计来佣
// 查询预计来佣
CommissionExpected commissionExpected;
try {
commissionExpected = queryByCommission(commission);
// 对比预计来佣
compareWithExpected(commission.getPremium(), commission, commissionExpected);
commissionExpectedService.updateById(commissionExpected);
} catch (Exception e) {
// 预计来佣不存在,来佣状态设置为 比对失败
commission.setStatus(CommissionStatusEnum.COMPARE_FAIL.getItemValue());
commission.setRemark(e.getMessage());
}
// CommissionExpected commissionExpected;
// try {
// commissionExpected = queryByCommission(commission);
// // 对比预计来佣
// compareWithExpected(commission.getPremium(), commission, commissionExpected);
// commissionExpectedService.updateById(commissionExpected);
// } catch (Exception e) {
// // 预计来佣不存在,来佣状态设置为 比对失败
// commission.setStatus(CommissionStatusEnum.COMPARE_FAIL.getItemValue());
// commission.setRemark(e.getMessage());
// }
commission.setCreatorId(loginUserId);
commission.setCreateTime(new Date());
......@@ -528,7 +586,7 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
// 当前来佣比例=当前入账金额/结算汇率/保费 * 100
BigDecimal currentCommissionRatio = commission.getAmount()
.divide(new BigDecimal(premium), 2, RoundingMode.HALF_UP)
.divide(new BigDecimal(premium), 4, RoundingMode.HALF_UP)
.divide(new BigDecimal(commission.getExchangeRate()), 4, RoundingMode.HALF_UP)
.multiply(new BigDecimal(100))
;
......@@ -558,9 +616,9 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
// 当前来佣比例
commission.setCurrentCommissionRatio(currentCommissionRatio);
// 当期已入账来佣比例 = 当前来佣比例 + 已入账来佣比例
commission.setPeriodPaidRatio(currentCommissionRatio.add(ObjectUtils.defaultIfNull(expected.getPaidRatio(), BigDecimal.ZERO)).setScale(2, RoundingMode.HALF_UP));
// 当期剩余来佣比例 = 预计来佣来佣比例 - 当期已入账来佣比例
commission.setPeriodPendingRatio(expectedCommissionRatio.subtract(commission.getPeriodPaidRatio()).setScale(2, RoundingMode.HALF_UP));
// commission.setPeriodPaidRatio(currentCommissionRatio.add(ObjectUtils.defaultIfNull(expected.getPaidRatio(), BigDecimal.ZERO)).setScale(2, RoundingMode.HALF_UP));
// // 当期剩余来佣比例 = 预计来佣来佣比例 - 当期已入账来佣比例
// commission.setPeriodPendingRatio(expectedCommissionRatio.subtract(commission.getPeriodPaidRatio()).setScale(2, RoundingMode.HALF_UP));
// 达到预计比例时,待入账金额设置为 0
if (commission.getPeriodPendingRatio().compareTo(BigDecimal.ZERO) == 0) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment