Commit c641b365 by jianan

应付明细10

parent 9fe9be79
...@@ -25,6 +25,7 @@ import com.yd.csf.api.service.ApiBasicLawCalculateService; ...@@ -25,6 +25,7 @@ import com.yd.csf.api.service.ApiBasicLawCalculateService;
import com.yd.csf.api.service.ApiCommissionConditionService; import com.yd.csf.api.service.ApiCommissionConditionService;
import com.yd.csf.api.service.ApiExpectedFortuneLogService; import com.yd.csf.api.service.ApiExpectedFortuneLogService;
import com.yd.csf.api.service.ApiExpectedFortuneService; import com.yd.csf.api.service.ApiExpectedFortuneService;
import com.yd.csf.service.component.DictCacheService;
import com.yd.csf.feign.request.expectedfortune.*; import com.yd.csf.feign.request.expectedfortune.*;
import com.yd.csf.feign.response.expectedfortune.ApiExpectedFortunePageResponse; import com.yd.csf.feign.response.expectedfortune.ApiExpectedFortunePageResponse;
import com.yd.csf.feign.response.expectedfortune.ApiGenerateExpectedFortuneResponse; import com.yd.csf.feign.response.expectedfortune.ApiGenerateExpectedFortuneResponse;
...@@ -100,6 +101,8 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService ...@@ -100,6 +101,8 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
@Autowired @Autowired
private RedisUtil redisUtil; private RedisUtil redisUtil;
@Autowired @Autowired
private DictCacheService dictCacheService;
@Autowired
private ApiExpectedFortuneLogService apiExpectedFortuneLogService; private ApiExpectedFortuneLogService apiExpectedFortuneLogService;
@Autowired @Autowired
private PolicyBrokerService policyBrokerService; private PolicyBrokerService policyBrokerService;
...@@ -438,12 +441,9 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService ...@@ -438,12 +441,9 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
} }
} }
} }
//批量设置应付款编号、发佣类型 //批量设置应付款编号、发佣类型、默认结算汇率、港币金额
List<ExpectedFortune> expectedFortuneList = updatePayableNoBatch(policyNo);
//默认结算汇率、港币金额
String policyCurrency = queryPolicyAndBrokerDtoList.get(0).getCurrency(); String policyCurrency = queryPolicyAndBrokerDtoList.get(0).getCurrency();
updateHkdAmountBatch(expectedFortuneList, policyCurrency, announcementRatioList); updatePayableNoAndHkdAmountBatch(policyNo, policyCurrency, announcementRatioList);
//执行成功完毕,也要销毁redis缓存 //执行成功完毕,也要销毁redis缓存
redisUtil.deleteObject(RedisConstants.EXPECTED_FORTUNE + policyNo); redisUtil.deleteObject(RedisConstants.EXPECTED_FORTUNE + policyNo);
...@@ -472,61 +472,6 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService ...@@ -472,61 +472,6 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
}); });
} }
@Transactional(rollbackFor = Exception.class)
public void updateHkdAmountBatch(List<ExpectedFortune> expectedFortuneList, String policyCurrency, List<ApiAnnouncementCommissionRatioListResponse> announcementRatioList) {
log.info("------------------------开始计算默认结算汇率、港币金额----------------------");
if (!CollectionUtils.isEmpty(announcementRatioList)) {
ApiAnnouncementCommissionRatioListResponse announcementRatio = announcementRatioList.get(0);
String currency = announcementRatio.getCurrency();
log.info("结算币种(发放币种):{}", currency);
BigDecimal originalToHkdRate = queryExchangeRateByFeign(policyCurrency, "HKD");
log.info("结算汇率(原币种 -> 港币汇率):{}", originalToHkdRate);
BigDecimal hkdToPayoutRate = queryExchangeRateByFeign("HKD", currency);
log.info("港币 -> 发放币种汇率:{}", hkdToPayoutRate);
for (ExpectedFortune expectedFortune : expectedFortuneList) {
ExpectedFortune updateObj = new ExpectedFortune();
updateObj.setId(expectedFortune.getId());
//原币种
updateObj.setOriginalCurrency(policyCurrency);
//原币种金额
BigDecimal ruleAmount = expectedFortune.getRuleAmount();
updateObj.setOriginalAmount(ruleAmount);
//原币种 -> 港币汇率
updateObj.setOriginalToHkdRate(originalToHkdRate);
//保单币种
updateObj.setRuleCurrency(policyCurrency);
//默认保单币种 -> 港币汇率
updateObj.setDefaultExchangeRate(originalToHkdRate);
//应发港币金额(估)(标准发佣金额 * 默认保单币种 -> 港币汇率)
BigDecimal hkdAmount = ruleAmount.multiply(originalToHkdRate);
updateObj.setHkdAmount(hkdAmount);
//发放币种
updateObj.setPayoutCurrency(currency);
//发放币种金额
updateObj.setPayoutAmount(hkdAmount.multiply(hkdToPayoutRate));
//港币 -> 发放币种汇率
updateObj.setHkdToPayoutRate(hkdToPayoutRate);
//默认值
updateObj.setPaidRuleAmount(BigDecimal.ZERO);
updateObj.setUnpaidRuleAmount(ruleAmount);
updateObj.setUnpaidRuleAmountHkd(hkdAmount);
updateObj.setPaidAmount(BigDecimal.ZERO);
updateObj.setPaidRatio(BigDecimal.ZERO);
updateObj.setUnpaidAmount(expectedFortune.getHkdAmount());
updateObj.setUnpaidRatio(BigDecimal.valueOf(100));
iExpectedFortuneService.updateById(updateObj);
}
}
}
@Override @Override
public Result executeSync(List<QueryPolicyAndBrokerDto> queryPolicyAndBrokerDtoList, List<CommissionRuleBinding> commissionRuleBindingList, String policyNo) { public Result executeSync(List<QueryPolicyAndBrokerDto> queryPolicyAndBrokerDtoList, List<CommissionRuleBinding> commissionRuleBindingList, String policyNo) {
return null; return null;
...@@ -629,12 +574,10 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService ...@@ -629,12 +574,10 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
} }
} }
} }
//批量设置应付款编号
List<ExpectedFortune> expectedFortuneList = updatePayableNoBatch(policyNo);
//默认结算汇率、港币金额 //批量设置应付款编号、默认结算汇率、港币金额
String policyCurrency = queryPolicyAndBrokerDtoList.get(0).getCurrency(); String policyCurrency = queryPolicyAndBrokerDtoList.get(0).getCurrency();
updateHkdAmountBatch(expectedFortuneList, policyCurrency, announcementRatioList); updatePayableNoAndHkdAmountBatch(policyNo, policyCurrency, announcementRatioList);
//执行成功完毕,也要销毁redis缓存 //执行成功完毕,也要销毁redis缓存
redisUtil.deleteObject(RedisConstants.EXPECTED_FORTUNE + policyNo); redisUtil.deleteObject(RedisConstants.EXPECTED_FORTUNE + policyNo);
...@@ -680,31 +623,81 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService ...@@ -680,31 +623,81 @@ public class ApiExpectedFortuneServiceImpl implements ApiExpectedFortuneService
return commissionRuleBindingList; return commissionRuleBindingList;
} }
@Transactional(rollbackFor = Exception.class) /**
private List<ExpectedFortune> updatePayableNoBatch(String policyNo) { * 批量更新应付款编号、发佣类型、默认结算汇率、港币金额
*/
private void updatePayableNoAndHkdAmountBatch(String policyNo, String policyCurrency,
List<ApiAnnouncementCommissionRatioListResponse> announcementRatioList) {
//查询当前保单号的所有预计发佣记录 //查询当前保单号的所有预计发佣记录
List<ExpectedFortune> expectedFortuneList = iExpectedFortuneService.queryList(policyNo); List<ExpectedFortune> expectedFortuneList = iExpectedFortuneService.queryList(policyNo);
//查询redis缓存的字典列表信息 //查询redis缓存的字典列表信息
List<GetDictItemListByDictTypeResponse> dictTypeResponses = redisUtil.getCacheObject(RedisConstants.DICT_LIST); List<GetDictItemListByDictTypeResponse> dictTypeResponses = dictCacheService.getDictList("csf_fortune_type");
//批量更新应付款编号,每个item递增 log.info("------------------------开始计算默认结算汇率、港币金额----------------------");
ExpectedFortune expectedFortune;
List<ExpectedFortune> updateList = new ArrayList<>(); //计算汇率(只在announcementRatioList非空时)
for (int i = 0; i < expectedFortuneList.size(); i++) { String currency = null;
expectedFortune = expectedFortuneList.get(i); BigDecimal originalToHkdRate = null;
BigDecimal hkdToPayoutRate = null;
if (!CollectionUtils.isEmpty(announcementRatioList)) {
ApiAnnouncementCommissionRatioListResponse announcementRatio = announcementRatioList.get(0);
currency = announcementRatio.getCurrency();
log.info("结算币种(发放币种):{}", currency);
originalToHkdRate = queryExchangeRateByFeign(policyCurrency, "HKD");
log.info("结算汇率(原币种 -> 港币汇率):{}", originalToHkdRate);
hkdToPayoutRate = queryExchangeRateByFeign("HKD", currency);
log.info("港币 -> 发放币种汇率:{}", hkdToPayoutRate);
}
List<ExpectedFortune> updateList = new ArrayList<>();
for (ExpectedFortune expectedFortune : expectedFortuneList) {
ExpectedFortune updateObj = new ExpectedFortune(); ExpectedFortune updateObj = new ExpectedFortune();
updateObj.setId(expectedFortune.getId()); updateObj.setId(expectedFortune.getId());
//设置发佣类型
updateObj.setFortuneType(GetDictItemListByDictTypeResponse.getItemValue(dictTypeResponses, updateObj.setFortuneType(GetDictItemListByDictTypeResponse.getItemValue(dictTypeResponses,
"csf_fortune_type", expectedFortune.getFortuneName())); "csf_fortune_type", expectedFortune.getFortuneName()));
//设置应付款编号
updateObj.setPayableNo(iExpectedFortuneService.getPayableNo(updateObj.getFortuneType(), policyNo, expectedFortune.getId())); updateObj.setPayableNo(iExpectedFortuneService.getPayableNo(updateObj.getFortuneType(), policyNo, expectedFortune.getId()));
//设置默认结算汇率、港币金额
if (!CollectionUtils.isEmpty(announcementRatioList)) {
//原币种
updateObj.setOriginalCurrency(policyCurrency);
//原币种金额
BigDecimal ruleAmount = expectedFortune.getRuleAmount();
updateObj.setOriginalAmount(ruleAmount);
//原币种 -> 港币汇率
updateObj.setOriginalToHkdRate(originalToHkdRate);
//保单币种
updateObj.setRuleCurrency(policyCurrency);
//默认保单币种 -> 港币汇率
updateObj.setDefaultExchangeRate(originalToHkdRate);
//应发港币金额(估)(标准发佣金额 * 默认保单币种 -> 港币汇率)
BigDecimal hkdAmount = ruleAmount.multiply(originalToHkdRate);
updateObj.setHkdAmount(hkdAmount);
//发放币种
updateObj.setPayoutCurrency(currency);
//发放币种金额
updateObj.setPayoutAmount(hkdAmount.multiply(hkdToPayoutRate));
//港币 -> 发放币种汇率
updateObj.setHkdToPayoutRate(hkdToPayoutRate);
//默认值
updateObj.setPaidRuleAmount(BigDecimal.ZERO);
updateObj.setUnpaidRuleAmount(ruleAmount);
updateObj.setUnpaidRuleAmountHkd(hkdAmount);
updateObj.setPaidAmount(BigDecimal.ZERO);
updateObj.setPaidRatio(BigDecimal.ZERO);
updateObj.setUnpaidAmount(expectedFortune.getHkdAmount());
updateObj.setUnpaidRatio(BigDecimal.valueOf(100));
}
updateList.add(updateObj); updateList.add(updateObj);
} }
iExpectedFortuneService.updateBatchById(updateList); iExpectedFortuneService.updateBatchById(updateList);
return expectedFortuneList;
} }
/** /**
......
package com.yd.csf.service.component;
import com.yd.common.constant.RedisConstants;
import com.yd.common.utils.RedisUtil;
import com.yd.user.feign.client.sysdict.ApiSysDictFeignClient;
import com.yd.user.feign.request.sysdict.GetDictTypeListRequest;
import com.yd.user.feign.response.sysdict.GetDictItemListByDictTypeResponse;
import com.yd.user.feign.response.sysdict.GetDictTypeListResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@Component
public class DictCacheService {
@Resource
private RedisUtil redisUtil;
@Resource
private ApiSysDictFeignClient apiSysDictFeignClient;
/**
* 获取字典列表,缓存未命中或缺少指定类型时,按需从Feign拉取并合并写入Redis
*
* @param dictTypes 需要的字典类型编码
*/
public List<GetDictItemListByDictTypeResponse> getDictList(String... dictTypes) {
if (dictTypes == null || dictTypes.length == 0) {
return Collections.emptyList();
}
// 快速路径:从Redis获取缓存
List<GetDictItemListByDictTypeResponse> cached = redisUtil.getCacheObject(RedisConstants.DICT_LIST);
// 收集需要拉取的dictType
Set<String> neededTypes = new HashSet<>(Arrays.asList(dictTypes));
if (CollectionUtils.isEmpty(cached)) {
// 缓存完全为空
return fetchAndCache(neededTypes, Collections.emptyList());
} else {
// 检查缓存中已有哪些类型
Set<String> cachedTypes = cached.stream()
.filter(Objects::nonNull)
.map(GetDictItemListByDictTypeResponse::getDictType)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
Set<String> missingTypes = new HashSet<>(neededTypes);
missingTypes.removeAll(cachedTypes);
if (missingTypes.isEmpty()) {
return cached;
}
return fetchAndCache(missingTypes, cached);
}
}
/**
* 加锁从Feign拉取缺失的字典类型,合并到已有缓存并写回Redis
*/
private List<GetDictItemListByDictTypeResponse> fetchAndCache(Set<String> missingTypes, List<GetDictItemListByDictTypeResponse> existingCache) {
synchronized (this) {
// 双重检查:再次从Redis读取,防止并发时重复拉取
List<GetDictItemListByDictTypeResponse> cached = redisUtil.getCacheObject(RedisConstants.DICT_LIST);
if (!CollectionUtils.isEmpty(cached)) {
Set<String> cachedTypes = cached.stream()
.filter(Objects::nonNull)
.map(GetDictItemListByDictTypeResponse::getDictType)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
missingTypes.removeAll(cachedTypes);
if (missingTypes.isEmpty()) {
return cached;
}
existingCache = cached;
}
// 从Feign拉取缺失类型
List<GetDictItemListByDictTypeResponse> fetched = fetchFromFeign(missingTypes);
// 合并并去重
List<GetDictItemListByDictTypeResponse> merged = mergeCache(existingCache, fetched);
if (!CollectionUtils.isEmpty(merged)) {
redisUtil.setCacheObject(RedisConstants.DICT_LIST, merged);
}
return merged;
}
}
/**
* 调用Feign拉取指定字典类型的数据
*/
private List<GetDictItemListByDictTypeResponse> fetchFromFeign(Set<String> dictTypes) {
try {
GetDictTypeListRequest request = new GetDictTypeListRequest();
request.setTypeList(new ArrayList<>(dictTypes));
List<GetDictTypeListResponse> dictTypeResponses = apiSysDictFeignClient.getByDictTypeList(request).getData();
if (CollectionUtils.isEmpty(dictTypeResponses)) {
log.warn("Feign返回空字典列表, 请求类型: {}", dictTypes);
return Collections.emptyList();
}
return dictTypeResponses.stream()
.filter(Objects::nonNull)
.filter(dtr -> dtr.getDictItemList() != null)
.flatMap(dtr -> dtr.getDictItemList().stream())
.collect(Collectors.toList());
} catch (Exception e) {
log.error("从Feign拉取字典数据失败, 请求类型: {}", dictTypes, e);
return Collections.emptyList();
}
}
/**
* 合并已有缓存与新拉取数据,按 dictType + itemValue 去重
*/
private List<GetDictItemListByDictTypeResponse> mergeCache(
List<GetDictItemListByDictTypeResponse> existing,
List<GetDictItemListByDictTypeResponse> fetched) {
Map<String, GetDictItemListByDictTypeResponse> merged = new LinkedHashMap<>();
// 先放入已有缓存
for (GetDictItemListByDictTypeResponse item : existing) {
if (item != null && item.getDictType() != null && item.getItemValue() != null) {
String key = item.getDictType() + ":" + item.getItemValue();
merged.put(key, item);
}
}
// 再放入新拉取数据(覆盖相同key的旧值)
for (GetDictItemListByDictTypeResponse item : fetched) {
if (item != null && item.getDictType() != null && item.getItemValue() != null) {
String key = item.getDictType() + ":" + item.getItemValue();
merged.put(key, item);
}
}
return new ArrayList<>(merged.values());
}
}
...@@ -22,6 +22,7 @@ import com.yd.common.exception.BusinessException; ...@@ -22,6 +22,7 @@ import com.yd.common.exception.BusinessException;
import com.yd.common.result.Result; import com.yd.common.result.Result;
import com.yd.common.utils.RandomStringGenerator; import com.yd.common.utils.RandomStringGenerator;
import com.yd.common.utils.RedisUtil; import com.yd.common.utils.RedisUtil;
import com.yd.csf.service.component.DictCacheService;
import com.yd.csf.service.component.ReceivableService; import com.yd.csf.service.component.ReceivableService;
import com.yd.csf.service.dto.*; import com.yd.csf.service.dto.*;
import com.yd.csf.service.enums.CommissionExpectedStatusEnum; import com.yd.csf.service.enums.CommissionExpectedStatusEnum;
...@@ -94,6 +95,8 @@ public class CommissionExpectedServiceImpl extends ServiceImpl<CommissionExpecte ...@@ -94,6 +95,8 @@ public class CommissionExpectedServiceImpl extends ServiceImpl<CommissionExpecte
private CustomerService customerService; private CustomerService customerService;
@Resource @Resource
private CommissionExpectedService commissionExpectedService; private CommissionExpectedService commissionExpectedService;
@Resource
private DictCacheService dictCacheService;
// 用于对象转换的ObjectMapper // 用于对象转换的ObjectMapper
private static final ObjectMapper objectMapper = new ObjectMapper(); private static final ObjectMapper objectMapper = new ObjectMapper();
...@@ -1094,7 +1097,7 @@ public class CommissionExpectedServiceImpl extends ServiceImpl<CommissionExpecte ...@@ -1094,7 +1097,7 @@ public class CommissionExpectedServiceImpl extends ServiceImpl<CommissionExpecte
throw new BusinessException("保单供款年期不能为空"); throw new BusinessException("保单供款年期不能为空");
} }
//查询redis缓存的字典列表信息 //查询redis缓存的字典列表信息
List<GetDictItemListByDictTypeResponse> dictTypeResponses = redisUtil.getCacheObject(RedisConstants.DICT_LIST); List<GetDictItemListByDictTypeResponse> dictTypeResponses = dictCacheService.getDictList("csf_commission_type");
if (StringUtils.isNotBlank(productLaunchBizId)) { if (StringUtils.isNotBlank(productLaunchBizId)) {
List<ApiExpectedSpeciesListResponse> expectedSpeciesList = queryExpectedSpeciesByFeign(productLaunchBizId); List<ApiExpectedSpeciesListResponse> expectedSpeciesList = queryExpectedSpeciesByFeign(productLaunchBizId);
......
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