package com.finance.system.service.impl;
|
|
import com.alibaba.fastjson2.JSONArray;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.finance.common.enums.BasicDataFieldEnum;
|
import com.finance.common.enums.CalculateTypeEnum;
|
import com.finance.common.enums.IndicatorItemEnum;
|
import com.finance.common.enums.ShowStatusEnum;
|
import com.finance.common.enums.ValueTypeEnum;
|
import com.finance.common.exception.ServiceException;
|
import com.finance.common.utils.CalculateUtil;
|
import com.finance.common.utils.CollUtils;
|
import com.finance.common.utils.StringUtils;
|
import com.finance.system.domain.TbBasicData;
|
import com.finance.system.domain.TbBasicDataConfig;
|
import com.finance.system.domain.TbBasicDataConfigDetail;
|
import com.finance.system.domain.TbBasicDataField;
|
import com.finance.system.domain.TbField;
|
import com.finance.system.domain.TbScore;
|
import com.finance.system.dto.CalculateItemDTO;
|
import com.finance.system.mapper.TbBasicDataMapper;
|
import com.finance.system.service.AsyncService;
|
import com.finance.system.service.TbBasicDataCategoryService;
|
import com.finance.system.service.TbBasicDataConfigDetailService;
|
import com.finance.system.service.TbBasicDataConfigService;
|
import com.finance.system.service.TbBasicDataFieldService;
|
import com.finance.system.service.TbScoreService;
|
import com.finance.system.vo.BasicDataConfigVO;
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Map.Entry;
|
import java.util.Objects;
|
import java.util.Optional;
|
import java.util.function.Function;
|
import java.util.stream.Collectors;
|
import lombok.RequiredArgsConstructor;
|
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.stereotype.Service;
|
|
/**
|
* @author mitao
|
* @date 2024/7/5
|
*/
|
@Service
|
@RequiredArgsConstructor
|
public class AsyncServiceImpl implements AsyncService {
|
|
private final TbScoreService tbScoreService;
|
private final TbBasicDataFieldService tbBasicDataFieldService;
|
private final TbBasicDataConfigService tbBasicDataConfigService;
|
private final TbBasicDataCategoryService tbBasicDataCategoryService;
|
private final TbBasicDataConfigDetailService tbBasicDataConfigDetailService;
|
private final TbBasicDataMapper tbBasicDataMapper;
|
|
@Async
|
@Override
|
public void calculateScore(TbBasicData tbBasicData, List<TbBasicDataField> fields) {
|
List<TbScore> scoreList = new ArrayList<>();
|
// 计算得分
|
List<TbBasicDataConfig> list = tbBasicDataConfigService.lambdaQuery()
|
.eq(TbBasicDataConfig::getStatus, ShowStatusEnum.SHOW).list();
|
if (CollectionUtils.isEmpty(list)) {
|
throw new ServiceException("计算得分失败,平台未配置得分计算规则");
|
}
|
List<TbBasicDataConfig> numCalculates = list.stream()
|
.filter(item -> CalculateTypeEnum.NUMBER.equals(item.getCalculateType()))
|
.collect(Collectors.toList());
|
List<TbBasicDataConfig> textAndPercentages = list.stream()
|
.filter(item -> !CalculateTypeEnum.NUMBER.equals(item.getCalculateType()))
|
.collect(Collectors.toList());
|
tbScoreService.remove(
|
new LambdaQueryWrapper<TbScore>().eq(TbScore::getBasicDataId, tbBasicData.getId()));
|
Map<Long, TbBasicDataField> basicDataFieldMap = fields.stream()
|
.collect(Collectors.toMap(TbBasicDataField::getFieldId, e -> e));
|
if (CollUtils.isNotEmpty(numCalculates)) {
|
for (TbBasicDataConfig item : numCalculates) {
|
String numberCalculateFormula = item.getNumberCalculateFormula();
|
List<CalculateItemDTO> calculateItemDTOS = JSONArray.parseArray(
|
numberCalculateFormula,
|
CalculateItemDTO.class);
|
for (CalculateItemDTO dto : calculateItemDTOS) {
|
if (ValueTypeEnum.FIELD.equals(dto.getValueType())) {
|
TbBasicDataField tbBasicDataField = basicDataFieldMap.get(
|
Long.valueOf(dto.getContent()));
|
if (Objects.nonNull(tbBasicDataField)) {
|
dto.setContent(tbBasicDataField.getFieldValue());
|
}
|
}
|
}
|
String numberCalculateFormulaStr = calculateItemDTOS.stream()
|
.map(CalculateItemDTO::getContent).collect(Collectors.joining());
|
double score = CalculateUtil.calculate(numberCalculateFormulaStr);
|
if (Objects.nonNull(item.getMaxScore()) && score > item.getMaxScore()) {
|
score = item.getMaxScore();
|
}
|
TbScore tbScore = new TbScore();
|
tbScore.setBasicDataId(tbBasicData.getId());
|
tbScore.setScore(score);
|
tbScore.setBasicDataConfigId(item.getId());
|
scoreList.add(tbScore);
|
}
|
}
|
if (CollUtils.isNotEmpty(textAndPercentages)) {
|
for (TbBasicDataConfig textAndPercentage : textAndPercentages) {
|
TbScore tbScore = new TbScore();
|
List<TbBasicDataConfigDetail> details = tbBasicDataConfigDetailService.lambdaQuery()
|
.eq(TbBasicDataConfigDetail::getBasicDataConfigId,
|
textAndPercentage.getId())
|
.list();
|
Map<String, String> scoreMap = details.stream().collect(
|
Collectors.toMap(TbBasicDataConfigDetail::getKey,
|
TbBasicDataConfigDetail::getValue));
|
if (CollectionUtils.isNotEmpty(details)) {
|
TbBasicDataField textAndPercentageData = basicDataFieldMap.get(
|
Long.valueOf(textAndPercentage.getFieldIdStr()));
|
if (Objects.nonNull(textAndPercentageData)) {
|
if (CalculateTypeEnum.TEXT.equals(textAndPercentage.getCalculateType())) {
|
String score = scoreMap.get(textAndPercentageData.getFieldValue());
|
tbScore.setBasicDataId(tbBasicData.getId());
|
tbScore.setScore(Double.parseDouble(score));
|
tbScore.setBasicDataConfigId(textAndPercentage.getId());
|
scoreList.add(tbScore);
|
}
|
if (CalculateTypeEnum.PERCENTAGE.equals(
|
textAndPercentage.getCalculateType())) {
|
for (Entry<String, String> stringStringEntry : scoreMap.entrySet()) {
|
String[] split = stringStringEntry.getKey().split("_");
|
double v = Double.parseDouble(
|
textAndPercentageData.getFieldValue());
|
double min = Double.parseDouble(split[0]);
|
double max = Double.parseDouble(split[1]);
|
if (v >= min && v <= max) {
|
tbScore.setScore(
|
Double.parseDouble(stringStringEntry.getValue()));
|
}
|
}
|
// 如果都不匹配,得分为0
|
if (Objects.isNull(tbScore.getScore())) {
|
tbScore.setScore(0D);
|
}
|
tbScore.setBasicDataId(tbBasicData.getId());
|
tbScore.setBasicDataConfigId(textAndPercentage.getId());
|
scoreList.add(tbScore);
|
}
|
}
|
}
|
}
|
}
|
tbScoreService.saveBatch(scoreList);
|
}
|
|
@Async("asyncTaskExecutor")
|
@Override
|
public void asyncTask() {
|
long startTime = System.currentTimeMillis();
|
try {
|
// 模拟耗时
|
Thread.sleep(3000);
|
} catch (InterruptedException e) {
|
e.printStackTrace();
|
}
|
long endTime = System.currentTimeMillis();
|
System.out.println(Thread.currentThread().getName() + ":void asyncTask(),耗时:" + (endTime
|
- startTime));
|
}
|
|
@Override
|
public void calculateScoreWithFixedRules(TbBasicData tbBasicData,
|
List<TbBasicDataField> fields, List<TbField> fieldList) {
|
List<BasicDataConfigVO> fixedRulesConfigList = tbBasicDataConfigService.getFixedRulesConfigList();
|
// 查询四川省的基础数据
|
TbBasicData provinceBasicData = tbBasicDataMapper.selectOne(
|
Wrappers.lambdaQuery(TbBasicData.class)
|
.eq(TbBasicData::getDeptAreaCode, "510000")
|
.eq(TbBasicData::getQuarter, tbBasicData.getQuarter()));
|
if (Objects.isNull(provinceBasicData)) {
|
throw new ServiceException("四川省未上传该季度基础数据,请联系管理员");
|
}
|
List<TbBasicDataField> provinceFields = tbBasicDataFieldService.lambdaQuery()
|
.eq(TbBasicDataField::getBasicDataId, provinceBasicData.getId()).list();
|
// 四川省的基础数据字段
|
Map<Long, TbBasicDataField> provinceFieldsMap = provinceFields.stream()
|
.collect(Collectors.toMap(TbBasicDataField::getFieldId, Function.identity()));
|
// 待计算的基础数据字段
|
Map<Long, TbBasicDataField> deptFieldsMap = fields.stream()
|
.collect(Collectors.toMap(TbBasicDataField::getFieldId, Function.identity()));
|
List<TbScore> scoreList = new ArrayList<>();
|
for (BasicDataConfigVO vo : fixedRulesConfigList) {
|
double score = 0D;
|
// 1:财政经济形势-收入占GDP比重-地方一般公共预算收入占GDP的比重;
|
if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM1.getCode()) {
|
// 获取所需字段
|
TbBasicDataField provinceField = provinceFieldsMap.get(
|
BasicDataFieldEnum.BASIC_DATA_FIELD2.getCode());
|
TbBasicDataField deptField = deptFieldsMap.get(
|
BasicDataFieldEnum.BASIC_DATA_FIELD2.getCode());
|
score = getScore(deptField.getFieldValue(), tbBasicData.getCurrentGdp(),
|
provinceField.getFieldValue(), provinceBasicData.getCurrentGdp(), vo);
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM2.getCode()) {
|
// 2:财政经济形势-收入执行率-地方一般公共预算收入执行进度(地方一般公共预算收入/年初预算或调整预算);
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM3.getCode()) {
|
// 3:财政经济形势-收入执行率-政府性基金预算收入执行进度(政府性基金预算收入/年初预算或调整预算)
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM4.getCode()) {
|
// 4:财政经济形势-收入质量-税收收入占地方一般公共预算收入比重
|
// 获取所需字段
|
TbBasicDataField provinceField = provinceFieldsMap.get(
|
BasicDataFieldEnum.BASIC_DATA_FIELD3.getCode());
|
TbBasicDataField deptField = deptFieldsMap.get(
|
BasicDataFieldEnum.BASIC_DATA_FIELD3.getCode());
|
TbBasicDataField provinceField2 = provinceFieldsMap.get(
|
BasicDataFieldEnum.BASIC_DATA_FIELD2.getCode());
|
TbBasicDataField deptField2 = deptFieldsMap.get(
|
BasicDataFieldEnum.BASIC_DATA_FIELD2.getCode());
|
score = getScore(deptField.getFieldValue(), deptField2.getFieldValue(),
|
provinceField.getFieldValue(), provinceField2.getFieldValue(), vo);
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM5.getCode()) {
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM6.getCode()) {
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM7.getCode()) {
|
TbField field = getFieldByFieldName(fieldList, "(一)一般公共预算",
|
"上级补助收入", "",
|
"执行数");
|
|
TbField field2 = getFieldByFieldName(fieldList, "(一)一般公共预算",
|
"综合财力(本级收入+上级补助-上解+下级上解收入-补助下级支出)", "",
|
"执行数");
|
if (Objects.nonNull(field) && Objects.nonNull(field2)) {
|
TbBasicDataField provinceField = provinceFieldsMap.get(field.getId());
|
TbBasicDataField deptField = deptFieldsMap.get(field.getId());
|
TbBasicDataField provinceField2 = provinceFieldsMap.get(field2.getId());
|
TbBasicDataField deptField2 = deptFieldsMap.get(field2.getId());
|
score = getScore(deptField.getFieldValue(), deptField2.getFieldValue(),
|
provinceField.getFieldValue(), provinceField2.getFieldValue(), vo);
|
}
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM8.getCode()) {
|
TbField field = getFieldByFieldName(fieldList, "(四)“三保”保障情况",
|
"地方标准“三保”支出(以地方实际结构填列,含国标)", "保基本民生",
|
"保基本民生");
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM9.getCode()) {
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM10.getCode()) {
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM11.getCode()) {
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM12.getCode()) {
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM13.getCode()) {
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM14.getCode()) {
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM15.getCode()) {
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM16.getCode()) {
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM17.getCode()) {
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM18.getCode()) {
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM19.getCode()) {
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM20.getCode()) {
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM21.getCode()) {
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM22.getCode()) {
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM23.getCode()) {
|
|
} else if (vo.getId().intValue() == IndicatorItemEnum.INDICATOR_ITEM24.getCode()) {
|
|
}
|
TbScore tbScore = new TbScore();
|
tbScore.setScore((double) score);
|
tbScore.setBasicDataId(tbBasicData.getId());
|
tbScore.setBasicDataConfigId(vo.getId());
|
scoreList.add(tbScore);
|
}
|
}
|
|
/**
|
* 通用计算公式获取得分
|
*
|
* @param deptDividendValueStr 部门被除数字段值
|
* @param deptDivisorValueStr 部门除数字段值
|
* @param provinceDividendValueStr 省份被除数字段值
|
* @param provinceDivisorValueStr 省份除数字段值
|
* @param vo 基础数据配置
|
* @return 得分
|
*/
|
private Double getScore(String deptDividendValueStr, String deptDivisorValueStr,
|
String provinceDividendValueStr, String provinceDivisorValueStr, BasicDataConfigVO vo) {
|
BigDecimal score = BigDecimal.ZERO;
|
BigDecimal provinceDividendValue = BigDecimal.valueOf(
|
Long.parseLong(provinceDividendValueStr));
|
BigDecimal provinceDivisorValue = BigDecimal.valueOf(
|
Long.parseLong(provinceDivisorValueStr));
|
BigDecimal deptDividendValue = BigDecimal.valueOf(
|
Long.parseLong(deptDividendValueStr));
|
BigDecimal deptDivisorValue = BigDecimal.valueOf(
|
Long.parseLong(deptDivisorValueStr));
|
// 开始计算
|
BigDecimal deptDivided = BigDecimal.ZERO;
|
|
if (deptDivisorValue.compareTo(BigDecimal.ZERO) > 0) {
|
deptDivided = deptDividendValue.divide(deptDivisorValue, 2, RoundingMode.HALF_UP);
|
}
|
BigDecimal provinceDivided = BigDecimal.ZERO;
|
|
if (provinceDivisorValue.compareTo(BigDecimal.ZERO) > 0) {
|
provinceDivided = provinceDividendValue.divide(provinceDivisorValue, 2,
|
RoundingMode.HALF_UP);
|
}
|
if (deptDivided.compareTo(provinceDivided) < 0) {
|
score = deptDivided.subtract(provinceDivided)
|
.multiply(BigDecimal.valueOf(100L))
|
.add(BigDecimal.valueOf(vo.getMaxScore()));
|
score = score.compareTo(BigDecimal.ZERO) >= 0 ? score : BigDecimal.ZERO;
|
} else {
|
score = BigDecimal.valueOf(vo.getMaxScore());
|
}
|
return score.doubleValue();
|
}
|
|
private TbField getFieldByFieldName(List<TbField> fieldList, String categoryOne,
|
String categoryTwo,
|
String categoryThree,
|
String fieldStr) {
|
TbField field = null;
|
if (!fieldList.isEmpty()) {
|
/*
|
判断字段有几级分类,如果字段如果fieldStr与categoryTwo不同,说明该字段有二级分类。
|
如果字段如果fieldStr与categoryThree不同,说明该字段有三级分类。
|
res = 1 表示只有一级分类 res=2 表示该字段有二级分类,res=3表示该字段有三级分类
|
*/
|
int res = StringUtils.isNotBlank(categoryThree) ? 3
|
: StringUtils.isNotBlank(categoryTwo) ? 2 : 1;
|
Optional<TbField> fieldOptional = Optional.empty();
|
switch (res) {
|
case 1:
|
fieldOptional = fieldList.stream()
|
.filter(item -> item.getFieldName().equals(fieldStr)
|
&& item.getLevelOneCategory().equals(categoryOne)
|
&& item.getStatus()
|
== ShowStatusEnum.SHOW)
|
.findFirst();
|
if (fieldOptional.isPresent()) {
|
field = fieldOptional.get();
|
field.setFieldName(categoryOne + "-" + field.getFieldName());
|
}
|
break;
|
case 2:
|
fieldOptional = fieldList.stream()
|
.filter(item -> item.getFieldName().equals(fieldStr)
|
&& item.getLevelOneCategory().equals(categoryOne)
|
&& item.getStatus()
|
== ShowStatusEnum.SHOW)
|
.filter(item -> item.getLevelTwoCategory().equals(categoryTwo))
|
.findFirst();
|
if (fieldOptional.isPresent()) {
|
field = fieldOptional.get();
|
field.setFieldName(
|
categoryOne + "-" + categoryTwo + "-" + field.getFieldName());
|
}
|
break;
|
case 3:
|
fieldOptional = fieldList.stream()
|
.filter(item -> item.getFieldName().equals(fieldStr)
|
&& item.getLevelOneCategory().equals(categoryOne)
|
&& item.getStatus()
|
== ShowStatusEnum.SHOW)
|
.filter(item -> item.getLevelTwoCategory().equals(categoryTwo))
|
.filter(item -> item.getLevelThreeCategory()
|
.equals(categoryThree))
|
.findFirst();
|
if (fieldOptional.isPresent()) {
|
field = fieldOptional.get();
|
field.setFieldName(
|
categoryOne + "-" + categoryTwo + "-" + categoryThree + "-"
|
+ field.getFieldName());
|
}
|
break;
|
}
|
}
|
return field;
|
}
|
}
|