Commit 8c3791e2 by jianan

新单跟进136

parent e350da83
......@@ -12,24 +12,22 @@ import com.yd.common.result.Result;
import com.yd.csf.api.dto.CommissionExcelDTO;
import com.yd.csf.service.common.ErrorCode;
import com.yd.csf.service.dto.*;
import com.yd.csf.service.enums.CommissionStatusEnum;
import com.yd.csf.service.model.Commission;
import com.yd.csf.service.model.CommissionCompareRecord;
import com.yd.csf.service.model.CommissionEditRecord;
import com.yd.csf.service.model.CommissionExpected;
import com.yd.csf.service.service.CommissionCompareRecordService;
import com.yd.csf.service.service.CommissionEditRecordService;
import com.yd.csf.service.service.CommissionExpectedService;
import com.yd.csf.service.service.CommissionService;
import com.yd.csf.service.service.*;
import com.yd.csf.service.vo.CommissionStatisticsVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
......@@ -37,10 +35,8 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
......@@ -58,16 +54,16 @@ public class ApiCommissionController {
@Resource
private CommissionService commissionService;
@Resource
private CommissionExpectedService commissionExpectedService;
@Resource
private CommissionEditRecordService commissionEditRecordService;
@Resource
private CommissionCompareRecordService commissionCompareRecordService;
@Resource
private RedissonClient redissonClient;
@Resource
private CommissionAsyncService commissionAsyncService;
@PostMapping("/upload/excel")
......@@ -93,7 +89,23 @@ public class ApiCommissionController {
String loginUserId = currentLoginUser.getId().toString();
// 数据处理
processData(dataList, loginUserId);
List<Commission> entities = processData(dataList, loginUserId);
// 批量比对
TransactionSynchronizationManager.registerSynchronization(
new TransactionSynchronization() {
@Override
public void afterCommit() {
try {
// 重新查询最新的数据,获取已提交的数据
commissionAsyncService.commissionCompareBatch(entities);
} catch (Exception e) {
// 比对失败不影响主事务,记录日志即可
log.error("批量导入, 比对操作执行失败, error: {}", e.getMessage());
}
}
}
);
return Result.success(true);
}
......@@ -130,7 +142,7 @@ public class ApiCommissionController {
/**
* 1.处理导入的数据 2.比对预计来佣 3.保存到数据库
*/
private void processData(List<CommissionExcelDTO> dataList, String loginUserId) {
private List<Commission> processData(List<CommissionExcelDTO> dataList, String loginUserId) {
List<Commission> entities = new ArrayList<>();
for (CommissionExcelDTO data : dataList) {
// 数据验证
......@@ -141,52 +153,7 @@ public class ApiCommissionController {
// 保存来佣数据
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)
.collect(Collectors.toList());
// 根据保单号查询预计来佣
List<CommissionExpected> expectedList = commissionExpectedService.lambdaQuery()
.in(CommissionExpected::getPolicyNo, policyNoList)
.list();
for (Commission commission : entities) {
// 查询预计来佣
CommissionExpected commissionExpected;
try {
commissionExpected = commissionService.queryByCommission(commission);
// 对比预计来佣
commissionService.compareWithExpected(commission.getPremium(), commission, commissionExpected);
commissionExpectedService.updateById(commissionExpected);
} catch (Exception e) {
// 预计来佣不存在,来佣状态设置为 比对失败
commission.setStatus(CommissionStatusEnum.COMPARE_FAIL.getItemValue());
commission.setRemark(e.getMessage());
}
}
// 保存来佣数据
commissionService.saveBatch(entities);
// 更新预计来佣状态
commissionExpectedService.updateBatchById(expectedList);
return entities;
}
/**
......@@ -288,7 +255,30 @@ public class ApiCommissionController {
if (commissionUpdateRequest == null || commissionUpdateRequest.getCommissionBizId() == null) {
return Result.fail(ErrorCode.PARAMS_ERROR.getCode(), ErrorCode.PARAMS_ERROR.getMessage());
}
return Result.success(commissionService.updateCommission(commissionUpdateRequest));
// 校验入参
commissionService.validateCommissionUpdateRequest(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("系统繁忙,请稍后重试");
}
// 更新来佣记录
Result.success(commissionService.updateCommission(commissionUpdateRequest));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
log.error("更新来佣记录时,获取锁被中断", e);
return Result.fail(ErrorCode.OPERATION_ERROR.getCode(), "更新来佣记录时,获取锁被中断");
} finally {
if (lock != null && lock.isLocked() && lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
return Result.success(true);
}
/**
......
package com.yd.csf.service.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yd.auth.core.dto.AuthUserDto;
import com.yd.auth.core.utils.SecurityUtil;
import com.yd.common.enums.ResultCode;
import com.yd.common.exception.BusinessException;
import com.yd.csf.service.enums.CommissionExpectedStatusEnum;
import com.yd.csf.service.enums.CommissionStatusEnum;
import com.yd.csf.service.model.Commission;
import com.yd.csf.service.model.CommissionCompareRecord;
import com.yd.csf.service.model.CommissionExpected;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
......@@ -19,47 +33,198 @@ public class CommissionAsyncService {
private CommissionExpectedService commissionExpectedService;
@Resource
private CommissionService commissionService;
@Resource
private CommissionCompareRecordService commissionCompareRecordService;
@Async("commonAsyncExecutor")
// @Async("commonAsyncExecutor")
@Transactional(rollbackFor = Exception.class)
public void commissionCompareBatch(List<Commission> entities) {
// 比对逻辑...
log.info("开始异步比对,数据量:{}", entities.size());
// 1.根据导入的来佣获取保单号集合
List<String> policyNoList = entities.stream()
.map(Commission::getPolicyNo)
.collect(Collectors.toList());
// 2.根据保单号查询已存在的来佣记录
List<Commission> existingCommissions = commissionService.lambdaQuery()
.in(Commission::getPolicyNo, policyNoList)
.list();
// 来佣根据 保单号、来佣名称、来佣周期、货币 进行分组
Map<String, List<Commission>> commissionMap = existingCommissions.stream()
.collect(Collectors.groupingBy(
c -> c.getPolicyNo() + c.getCommissionName() + c.getCommissionPeriod() + c.getCurrency()
));
// 3.根据保单号查询预计来佣
List<CommissionExpected> expectedList = commissionExpectedService.lambdaQuery()
.in(CommissionExpected::getPolicyNo, policyNoList)
.list();
// 预计来佣根据 保单号、来佣名称、来佣周期、货币 进行映射
Map<String, CommissionExpected> expectedMap = expectedList.stream()
.collect(Collectors.toMap(
commissionExpected -> commissionExpected.getPolicyNo() + commissionExpected.getCommissionName() + commissionExpected.getCommissionPeriod() + commissionExpected.getCurrency(),
commissionExpected -> commissionExpected
));
// 执行比对...
// 4.遍历预计来佣,进行比对
for (Map.Entry<String, CommissionExpected> entry : expectedMap.entrySet()) {
// 根据 保单号、来佣名称、来佣周期、货币 分组
String key = entry.getKey();
CommissionExpected commissionExpected = entry.getValue();
// 从已存在的来佣记录中获取当前来佣记录
List<Commission> existingCommissionsByKey = commissionMap.getOrDefault(key, new ArrayList<>());
// 进行比对
doCompareBatch(commissionExpected, existingCommissionsByKey);
}
}
public void commissionCompare(Commission commission) {
log.info("开始执行比对事务,来佣ID: {}, 保单号: {}",
commission.getId(), commission.getPolicyNo());
private void doCompareBatch(CommissionExpected commissionExpected, List<Commission> existingCommissions) {
// region 计算预计来佣属性
// 统计已入账金额、已入账比例
BigDecimal paidRatio = BigDecimal.ZERO;
BigDecimal paidAmount = BigDecimal.ZERO;
for (Commission item : existingCommissions) {
paidRatio = paidRatio.add(item.getCurrentCommissionRatio());
paidAmount = paidAmount.add(item.getAmount());
}
CommissionExpected commissionExpected;
try {
commissionExpected = commissionService.queryByCommission(commission);
// 对比预计来佣
commissionService.compareWithExpected(commission.getPremium(), commission, commissionExpected);
// 更新预计来佣已入账金额、已入账比例
commissionExpected.setPaidAmount(paidAmount);
commissionExpected.setPaidRatio(paidRatio);
// endregion 计算预计来佣属性
// 获取当前登录用户
AuthUserDto currentLoginUser = SecurityUtil.getCurrentLoginUser();
String loginUserId = currentLoginUser.getId().toString();
// 比对记录
List<CommissionCompareRecord> compareRecords = new ArrayList<>();
// 计算比对状态
if (paidRatio.compareTo(commissionExpected.getCommissionRatio()) == 0) {
// 等于预计比例时,所有来佣设置为比对成功
for (Commission existingCommission : existingCommissions) {
existingCommission.setStatus(CommissionStatusEnum.COMPARE_SUCCESS.getItemValue());
// 创建比对记录
compareRecords.add(commissionService.getNewCompareRecord(existingCommission, commissionExpected, currentLoginUser));
}
// 对应预计来佣设置为已来佣
commissionExpected.setStatus(CommissionExpectedStatusEnum.COMPARED.getItemValue());
// 待入账金额设置为 0
commissionExpected.setPaidAmount(paidAmount.setScale(2, RoundingMode.HALF_UP));
commissionExpected.setPaidRatio(paidRatio);
// 更新预计来佣
commissionExpectedService.updateById(commissionExpected);
// 更新已比对来佣记录
if (CollectionUtils.isNotEmpty(existingCommissions)) {
commissionService.updateBatchById(existingCommissions);
}
// 保存比对记录
commissionCompareRecordService.saveBatch(compareRecords);
} else {
// 比对失败时,所有来佣设置为比对失败
for (Commission existingCommission : existingCommissions) {
existingCommission.setStatus(CommissionStatusEnum.COMPARE_FAIL.getItemValue());
// 创建比对记录
compareRecords.add(commissionService.getNewCompareRecord(existingCommission, commissionExpected, currentLoginUser));
}
// 对应预计来佣设置为部分来佣
commissionExpected.setStatus(CommissionExpectedStatusEnum.PARTIAL.getItemValue());
// 更新预计来佣
commissionExpectedService.updateById(commissionExpected);
// 更新已比对来佣记录
if (CollectionUtils.isNotEmpty(existingCommissions)) {
commissionService.updateBatchById(existingCommissions);
}
// 保存比对记录
commissionCompareRecordService.saveBatch(compareRecords);
}
}
@Transactional(rollbackFor = Exception.class)
public void commissionCompare(String commissionBizId, String policyNo, String commissionName, Integer commissionPeriod, String currency, String premium) {
log.info("开始执行比对事务,来佣ID: {}, 保单号: {}",
commissionBizId, policyNo);
// 比对成功,更新状态
commission.setStatus(CommissionStatusEnum.COMPARE_SUCCESS.getItemValue());
// 查询所有已存在的来佣记录
List<Commission> existingCommissions = commissionService.list(new QueryWrapper<Commission>()
.eq("policy_no", policyNo)
.eq("commission_name", commissionName)
.eq("commission_period", commissionPeriod)
.eq("currency", currency));
} catch (Exception e) {
// 预计来佣不存在或比对失败
commission.setStatus(CommissionStatusEnum.COMPARE_FAIL.getItemValue());
commission.setRemark(e.getMessage());
log.warn("来佣比对失败,保单号: {},原因: {}",
commission.getPolicyNo(), e.getMessage());
// 当前 commission 记录
Commission commission = existingCommissions.stream()
.filter(c -> c.getCommissionBizId().equals(commissionBizId))
.findFirst()
.orElse(null);
if (commission == null) {
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "未找到该来佣记录");
}
// 查询对应预计来佣
CommissionExpected commissionExpected = commissionService.queryByCommission(
commission.getPolicyNo(),
commission.getCommissionName(),
commission.getCommissionPeriod(),
commission.getCurrency(),
premium);
doCompare(existingCommissions, commissionExpected, commission);
}
private void doCompare(List<Commission> existingCommissions, CommissionExpected commissionExpected, Commission commission) {
// region 计算预计来佣属性
// 统计已入账金额、已入账比例
BigDecimal paidRatio = BigDecimal.ZERO;
BigDecimal paidAmount = BigDecimal.ZERO;
for (Commission item : existingCommissions) {
paidRatio = paidRatio.add(item.getCurrentCommissionRatio());
paidAmount = paidAmount.add(item.getAmount());
}
// 更新来佣的比对状态(在比对事务中)
commissionService.updateById(commission);
// 更新预计来佣已入账金额、已入账比例
commissionExpected.setPaidAmount(paidAmount);
commissionExpected.setPaidRatio(paidRatio);
// endregion 计算预计来佣属性
// 获取当前登录用户
AuthUserDto currentLoginUser = SecurityUtil.getCurrentLoginUser();
String loginUserId = currentLoginUser.getId().toString();
// 计算比对状态
if (paidRatio.compareTo(commissionExpected.getCommissionRatio()) == 0) {
// 等于预计比例时,所有来佣设置为比对成功
for (Commission existingCommission : existingCommissions) {
existingCommission.setStatus(CommissionStatusEnum.COMPARE_SUCCESS.getItemValue());
}
// 对应预计来佣设置为已来佣
commissionExpected.setStatus(CommissionExpectedStatusEnum.COMPARED.getItemValue());
// 待入账金额设置为 0
commissionExpected.setPaidAmount(paidAmount.setScale(2, RoundingMode.HALF_UP));
commissionExpected.setPaidRatio(paidRatio);
// 更新预计来佣
commissionExpectedService.updateById(commissionExpected);
// 更新已比对来佣记录
if (CollectionUtils.isNotEmpty(existingCommissions)) {
commissionService.updateBatchById(existingCommissions);
}
// 保存比对记录
commissionService.saveCompareRecord(commission, commissionExpected, currentLoginUser);
} else {
// 不等于预计比例时,设置为比对失败
commission.setStatus(CommissionStatusEnum.COMPARE_FAIL.getItemValue());
// 更新来佣
commissionService.updateById(commission);
// 对应预计来佣设置为部分来佣
commissionExpected.setStatus(CommissionExpectedStatusEnum.PARTIAL.getItemValue());
// 更新预计来佣
commissionExpectedService.updateById(commissionExpected);
// 保存比对记录
commissionService.saveCompareRecord(commission, commissionExpected, currentLoginUser);
}
}
}
package com.yd.csf.service.service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yd.auth.core.dto.AuthUserDto;
import com.yd.csf.service.dto.*;
import com.yd.csf.service.model.Commission;
import com.baomidou.mybatisplus.extension.service.IService;
import com.yd.csf.service.model.CommissionCompareRecord;
import com.yd.csf.service.model.CommissionExpected;
import com.yd.csf.service.vo.CommissionStatisticsVO;
import com.yd.csf.service.vo.CommissionVO;
import java.util.List;
import java.util.Map;
/**
* @author Zhang Jianan
......@@ -40,5 +40,15 @@ public interface CommissionService extends IService<Commission> {
CommissionStatisticsVO getCommissionStatistics(List<Long> commissionIds);
CommissionExpected queryByCommission(Commission commission);
CommissionExpected queryByCommission(String policyNo, String commissionName, Integer commissionPeriod, String currency, String premium);
void calculatePaidAmountByCommissionList(Commission commission, CommissionExpected one);
void validateCommissionUpdateRequest(CommissionUpdateRequest commissionUpdateRequest);
void saveUpdateCommissionRecord(Commission commission, CommissionUpdateRequest commissionUpdateRequest, AuthUserDto currentLoginUser);
void saveCompareRecord(Commission commission, CommissionExpected commissionExpected, AuthUserDto currentLoginUser);
CommissionCompareRecord getNewCompareRecord(Commission existingCommission, CommissionExpected commissionExpected, AuthUserDto currentLoginUser);
}
......@@ -12,7 +12,6 @@ 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;
......@@ -26,8 +25,6 @@ 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;
......@@ -38,7 +35,6 @@ 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;
......@@ -70,8 +66,7 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
private CommissionCompareRecordService commissionCompareRecordService;
@Resource
private CommissionAsyncService commissionAsyncService;
@Resource
private RedissonClient redissonClient;
@Override
public QueryWrapper<Commission> getQueryWrapper(CommissionQueryRequest commissionQueryRequest) {
......@@ -119,74 +114,26 @@ 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();
String commissionBizId = commissionUpdateRequest.getCommissionBizId();
Commission commission = this.getOne(new QueryWrapper<Commission>()
.eq("commission_biz_id", commissionBizId));
// 查询旧数据
Commission commission = this.getByCommissionBizId(commissionBizId);
if (commission == null) {
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "未找到该来佣记录");
}
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);
}
}
}
);
}
BigDecimal amount = commission.getAmount();
BigDecimal requestAmount = commissionUpdateRequest.getAmount();
return updateResult;
// 1. 执行主更新事务(这个方法将在当前事务中执行)
// 计算当前来佣比例
BigDecimal currentCommissionRatio = this.calculateCurrentCommissionRatio(
commissionUpdateRequest.getAmount(),
commissionUpdateRequest.getPremium(),
commissionUpdateRequest.getExchangeRate());
} 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();
......@@ -195,18 +142,66 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
saveUpdateCommissionRecord(commission, commissionUpdateRequest, currentLoginUser);
// 更新属性
BeanUtils.copyProperties(commissionUpdateRequest, commission, "id", "commissionBizId");
BeanUtils.copyProperties(commissionUpdateRequest, commission, "commissionBizId");
commission.setCurrentCommissionRatio(currentCommissionRatio);
commission.setUpdaterId(loginUserId);
commission.setUpdateTime(new Date());
// 先更新来佣属性(在主事务中)
// 执行更新操作(这个方法将在当前事务中执行)
this.updateById(commission);
// 返回true表示主事务成功
// 没改金额,则不比对
if (amount.compareTo(requestAmount) != 0) {
// 2. 注册事务同步器,在主事务提交后执行比对
TransactionSynchronizationManager.registerSynchronization(
new TransactionSynchronization() {
@Override
public void afterCommit() {
try {
// 重新查询最新的数据,获取已提交的数据
commissionAsyncService.commissionCompare(
commission.getCommissionBizId(),
commission.getPolicyNo(),
commission.getCommissionName(),
commission.getCommissionPeriod(),
commission.getCurrency(),
commissionUpdateRequest.getPremium()
);
} catch (Exception e) {
// 比对失败不影响主事务,记录日志即可
log.error("主事务提交后,比对操作执行失败,commissionBizId: {}",
commissionUpdateRequest.getCommissionBizId(), e);
}
}
}
);
}
return true;
}
private void saveUpdateCommissionRecord(Commission commission, CommissionUpdateRequest commissionUpdateRequest, AuthUserDto currentLoginUser) {
@Override
public void validateCommissionUpdateRequest(CommissionUpdateRequest commissionUpdateRequest) {
// 校验入参
if (ObjectUtils.isEmpty(commissionUpdateRequest.getCommissionBizId())) {
log.error("来佣业务id不能为空:{}", commissionUpdateRequest.getCommissionBizId());
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "来佣业务id不能为空");
}
if (ObjectUtils.isEmpty(commissionUpdateRequest.getPremium())) {
log.error("保费不能为空:{}", commissionUpdateRequest.getPremium());
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "保费不能为空");
}
if (ObjectUtils.isEmpty(commissionUpdateRequest.getAmount())) {
log.error("当前入账金额不能为空,来佣业务id:{}", commissionUpdateRequest.getCommissionBizId());
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "当前入账金额不能为空");
}
if (ObjectUtils.isEmpty(commissionUpdateRequest.getExchangeRate())) {
log.error("当前结算汇率不能为空,来佣业务id:{}", commissionUpdateRequest.getCommissionBizId());
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "当前结算汇率不能为空");
}
}
@Override
public void saveUpdateCommissionRecord(Commission commission, CommissionUpdateRequest commissionUpdateRequest, AuthUserDto currentLoginUser) {
// 保存修改记录
List<CommissionEditRecord> commissionEditRecords = new ArrayList<>();
......@@ -279,18 +274,38 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
}
@Override
public CommissionExpected queryByCommission(Commission commission) {
public CommissionExpected queryByCommission(String policyNo, String commissionName, Integer commissionPeriod, String currency, String premium) {
QueryWrapper<CommissionExpected> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("policy_no", commission.getPolicyNo());
queryWrapper.eq("commission_name", commission.getCommissionName());
queryWrapper.eq("commission_period", commission.getCommissionPeriod());
queryWrapper.eq("currency", commission.getCurrency());
queryWrapper.eq("policy_no", policyNo);
queryWrapper.eq("commission_name", commissionName);
queryWrapper.eq("commission_period", commissionPeriod);
queryWrapper.eq("currency", currency);
CommissionExpected one = commissionExpectedService.getOne(queryWrapper);
if (ObjectUtils.isEmpty(one)) {
String errorMsg = String.format("未找到当前来佣对应的预计来佣,保单号:%s, 来佣名称:%s, 来佣期数:%s, 币种:%s",
commission.getPolicyNo(), commission.getCommissionName(), commission.getCommissionPeriod(), commission.getCurrency());
policyNo, commissionName, commissionPeriod, currency);
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), errorMsg);
}
// 计算预计来佣金额 (统一试算币种:HKD)
if (one.getExpectedAmount() == null) {
BigDecimal expectedAmount = new BigDecimal(premium)
.multiply(one.getCommissionRatio());
if ("USD".equals(one.getCurrency())) {
expectedAmount = expectedAmount.multiply(one.getDefaultExchangeRate());
}
one.setExpectedAmount(expectedAmount.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP));
}
return one;
}
/**
* 根据对应的所有来佣记录,统计已入账金额、已入账比例
*
* @param commission
* @param one
*/
@Override
public void calculatePaidAmountByCommissionList(Commission commission, CommissionExpected one) {
// 查询当前来佣对应的所有来佣记录
QueryWrapper<Commission> queryWrapperCommission = new QueryWrapper<>();
queryWrapperCommission.eq("policy_no", commission.getPolicyNo());
......@@ -309,16 +324,6 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
one.setPaidRatio(paidRatio);
}
}
// 计算预计来佣金额 (统一试算币种:HKD)
if (one.getExpectedAmount() == null) {
BigDecimal expectedAmount = new BigDecimal(commission.getPremium())
.multiply(one.getCommissionRatio());
if ("USD".equals(one.getCurrency())) {
expectedAmount = expectedAmount.multiply(one.getDefaultExchangeRate());
}
one.setExpectedAmount(expectedAmount.divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_UP));
}
return one;
}
@Override
......@@ -519,34 +524,39 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
// 生成新单编号
String commissionBizId = RandomStringGenerator.generateBizId16(CommonEnum.UID_TYPE_COMMISSION.getCode());
commission.setCommissionBizId(commissionBizId);
// 保费为空时,查询保单初始保费或支付保费,为空时默认0
if (ObjectUtils.isEmpty(commission.getPremium())) {
Object object = policy.getInitialPremium() != null ? policy.getInitialPremium() : policy.getPaymentPremium();
if (object != null) {
commission.setPremium(object.toString());
} else {
commission.setPremium(BigDecimal.ZERO.toString());
}
}
// 查询预计来佣
// 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());
commission.setUpdaterId(loginUserId);
commission.setUpdateTime(new Date());
// 保存来佣
this.save(commission);
// 注册事务同步器,在主事务提交后执行比对
TransactionSynchronizationManager.registerSynchronization(
new TransactionSynchronization() {
@Override
public void afterCommit() {
try {
// 重新查询最新的数据,获取已提交的数据
commissionAsyncService.commissionCompare(
commission.getCommissionBizId(),
commission.getPolicyNo(),
commission.getCommissionName(),
commission.getCommissionPeriod(),
commission.getCurrency(),
commissionAddRequest.getPremium()
);
} catch (Exception e) {
// 比对失败不影响主事务,记录日志即可
log.error("主事务提交后,比对操作执行失败,commissionBizId: {}",
commissionBizId, e);
}
}
}
);
return this.save(commission);
return true;
}
@Override
......@@ -567,22 +577,7 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
log.error("预计来佣的来佣比例不能为空,预计来佣业务id:{}", expected.getCommissionExpectedBizId());
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "预计来佣的来佣比例不能为空");
}
if (ObjectUtils.isEmpty(expected.getDefaultExchangeRate())) {
log.error("预计来佣的默认汇率不能为空,预计来佣业务id:{}", expected.getCommissionExpectedBizId());
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "预计来佣的默认汇率不能为空");
}
if (ObjectUtils.isEmpty(premium)) {
log.error("保费不能为空,来佣业务id:{}", commission.getCommissionBizId());
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "保费不能为空");
}
if (ObjectUtils.isEmpty(commission.getAmount())) {
log.error("当前入账金额不能为空,来佣业务id:{}", commission.getCommissionBizId());
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "当前入账金额不能为空");
}
if (ObjectUtils.isEmpty(commission.getExchangeRate())) {
log.error("当前结算汇率不能为空,来佣业务id:{}", commission.getCommissionBizId());
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "当前结算汇率不能为空");
}
// 当前来佣比例=当前入账金额/结算汇率/保费 * 100
BigDecimal currentCommissionRatio = commission.getAmount()
......@@ -592,10 +587,6 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
;
// 预计来佣比例
BigDecimal expectedCommissionRatio = expected.getCommissionRatio();
// 预计总金额
BigDecimal expectedAmount = expected.getExpectedAmount();
// 已入账金额
BigDecimal paidAmount = expected.getPaidAmount();
if (currentCommissionRatio.compareTo(expectedCommissionRatio) == 0) {
// 一致,来佣状态设置为 比对成功
......@@ -620,19 +611,29 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
// // 当期剩余来佣比例 = 预计来佣来佣比例 - 当期已入账来佣比例
// commission.setPeriodPendingRatio(expectedCommissionRatio.subtract(commission.getPeriodPaidRatio()).setScale(2, RoundingMode.HALF_UP));
// 达到预计比例时,待入账金额设置为 0
if (commission.getPeriodPendingRatio().compareTo(BigDecimal.ZERO) == 0) {
commission.setPendingAmount(BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP));
expected.setPaidAmount(paidAmount.setScale(2, RoundingMode.HALF_UP));
expected.setPaidRatio(commission.getPeriodPaidRatio());
}
// 保存比对记录
saveCompareRecord(commission, expected);
// saveCompareRecord(commission, expected);
}
}
private void saveCompareRecord(Commission commission, CommissionExpected expected) {
public BigDecimal calculateCurrentCommissionRatio(BigDecimal amount, String premium, String exchangeRate) {
if (ObjectUtils.isEmpty(premium)) {
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "保费不能为空");
}
if (ObjectUtils.isEmpty(amount)) {
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "当前入账金额不能为空");
}
if (ObjectUtils.isEmpty(exchangeRate)) {
throw new BusinessException(ResultCode.NULL_ERROR.getCode(), "当前结算汇率不能为空");
}
// 当前来佣比例=当前入账金额/结算汇率/保费 * 100
return amount.divide(new BigDecimal(premium), 4, RoundingMode.HALF_UP)
.divide(new BigDecimal(exchangeRate), 4, RoundingMode.HALF_UP)
.multiply(new BigDecimal(100));
}
@Override
public void saveCompareRecord(Commission commission, CommissionExpected expected, AuthUserDto currentLoginUser) {
CommissionCompareRecord commissionCompareRecord = new CommissionCompareRecord();
commissionCompareRecord.setCommissionExpectedBizId(expected.getCommissionExpectedBizId());
commissionCompareRecord.setCommissionBizId(commission.getCommissionBizId());
......@@ -647,6 +648,22 @@ public class CommissionServiceImpl extends ServiceImpl<CommissionMapper, Commiss
commissionCompareRecordService.save(commissionCompareRecord);
}
@Override
public CommissionCompareRecord getNewCompareRecord(Commission commission, CommissionExpected expected, AuthUserDto currentLoginUser) {
CommissionCompareRecord commissionCompareRecord = new CommissionCompareRecord();
commissionCompareRecord.setCommissionExpectedBizId(expected.getCommissionExpectedBizId());
commissionCompareRecord.setCommissionBizId(commission.getCommissionBizId());
commissionCompareRecord.setCommissionPeriod(commission.getCommissionPeriod());
commissionCompareRecord.setTotalPeriod(commission.getTotalPeriod());
commissionCompareRecord.setAmount(commission.getAmount());
commissionCompareRecord.setCurrency(commission.getCurrency());
commissionCompareRecord.setExchangeRate(commission.getExchangeRate());
commissionCompareRecord.setStatus(commission.getStatus());
commissionCompareRecord.setRemark(commission.getRemark());
commissionCompareRecord.setCreateTime(commission.getCreateTime());
return commissionCompareRecord;
}
/**
* 查询列表
*
......
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