package com.finance.system.service.impl;
|
|
import cn.hutool.core.date.DateUtil;
|
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.core.domain.entity.SysUser;
|
import com.finance.common.enums.BasicDataFieldEnum;
|
import com.finance.common.enums.CalculateTypeEnum;
|
import com.finance.common.enums.IndicatorItemEnum;
|
import com.finance.common.enums.QuestionTypeEnum;
|
import com.finance.common.enums.ShowStatusEnum;
|
import com.finance.common.enums.UserTypeEnum;
|
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.DateUtils;
|
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.TbQuestion;
|
import com.finance.system.domain.TbScore;
|
import com.finance.system.dto.CalculateItemDTO;
|
import com.finance.system.mapper.TbBasicDataMapper;
|
import com.finance.system.mapper.TbQuestionMapper;
|
import com.finance.system.service.AsyncService;
|
import com.finance.system.service.ISysUserService;
|
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.Date;
|
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;
|
private final TbQuestionMapper tbQuestionMapper;
|
private final ISysUserService sysUserService;
|
|
@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) {
|
if (tbBasicData.getDeptAreaCode().equals("000000")) {
|
return;
|
}
|
SysUser sysUser = sysUserService.lambdaQuery()
|
.eq(SysUser::getAreaCode, tbBasicData.getDeptAreaCode())
|
.eq(SysUser::getUserType,
|
UserTypeEnum.DEPARTMENT).oneOpt().get();
|
List<BasicDataConfigVO> fixedRulesConfigList = tbBasicDataConfigService.getFixedRulesConfigList();
|
// 查询四川省的基础数据
|
TbBasicData provinceBasicData = tbBasicDataMapper.selectOne(
|
Wrappers.lambdaQuery(TbBasicData.class)
|
.eq(TbBasicData::getDeptAreaCode, "000000")
|
.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<TbQuestion> list = tbQuestionMapper.selectList(
|
Wrappers.lambdaQuery(TbQuestion.class)
|
.eq(TbQuestion::getQuarter, tbBasicData.getQuarter()));
|
String deptAreaCode = tbBasicData.getDeptAreaCode();
|
List<TbScore> scoreList = tbScoreService.lambdaQuery()
|
.eq(TbScore::getBasicDataId, tbBasicData.getId()).list();
|
for (BasicDataConfigVO vo : fixedRulesConfigList) {
|
double score = 0D;
|
BigDecimal deptDividendValue;
|
BigDecimal deptDivisorValue;
|
BigDecimal provinceDividendValue;
|
BigDecimal provinceDivisorValue;
|
List<TbQuestion> questionList;
|
// 季度末时间
|
Date quarterDate = DateUtils.getQuarterDateEnd(tbBasicData.getQuarter());
|
BigDecimal month = BigDecimal.valueOf(
|
Double.parseDouble(DateUtil.format(quarterDate, "MM")));
|
boolean res1 = false;
|
boolean res2 = false;
|
switch (Objects.requireNonNull(IndicatorItemEnum.getEnumByCode(vo.getId()))) {
|
case INDICATOR_ITEM1:
|
// 1:财政经济形势-收入占GDP比重-地方一般公共预算收入占GDP的比重;
|
// 获取所需字段
|
deptDividendValue = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD2);
|
deptDivisorValue = BigDecimal.valueOf(
|
Double.parseDouble(tbBasicData.getCurrentGdp()));
|
provinceDividendValue = getProvinceBigDecimal(provinceFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD2);
|
provinceDivisorValue = BigDecimal.valueOf(
|
Double.parseDouble(provinceBasicData.getCurrentGdp()));
|
res1 = validateDivisorValue(deptDivisorValue);
|
res2 = validateDivisorValue(provinceDivisorValue);
|
if (!res1 && !res2) {
|
score = getScore(deptDividendValue, deptDivisorValue,
|
provinceDividendValue, provinceDivisorValue, vo);
|
} else {
|
score = 0D;
|
}
|
|
break;
|
case INDICATOR_ITEM2:
|
// 2:财政经济形势-收入执行率-地方一般公共预算收入执行进度(地方一般公共预算收入/年初预算或调整预算);
|
deptDividendValue = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD2);
|
deptDivisorValue = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD1);
|
res1 = validateDivisorValue(deptDivisorValue);
|
if (!res1) {
|
score = getScore(deptDividendValue, deptDivisorValue, month,
|
BigDecimal.valueOf(12D),
|
vo);
|
} else {
|
score = 0D;
|
}
|
break;
|
case INDICATOR_ITEM3:
|
// 3:财政经济形势-收入执行率-政府性基金预算收入执行进度(政府性基金预算收入/年初预算或调整预算)
|
deptDividendValue = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD18);
|
deptDivisorValue = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD17);
|
res1 = validateDivisorValue(deptDivisorValue);
|
if (!res1) {
|
score = getScore(deptDividendValue, deptDivisorValue, month,
|
BigDecimal.valueOf(12D),
|
vo);
|
} else {
|
score = 0D;
|
}
|
break;
|
case INDICATOR_ITEM4:
|
// 4:财政经济形势-收入质量-税收收入占地方一般公共预算收入比重
|
// 获取所需字段
|
deptDividendValue = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD3);
|
deptDivisorValue = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD2);
|
provinceDividendValue = getProvinceBigDecimal(provinceFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD3);
|
provinceDivisorValue = getProvinceBigDecimal(provinceFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD2);
|
res1 = validateDivisorValue(deptDivisorValue);
|
res2 = validateDivisorValue(provinceDivisorValue);
|
score = 0D;
|
if (!res1 && !res2) {
|
score = getScore(deptDividendValue, deptDivisorValue,
|
provinceDividendValue, provinceDivisorValue, vo);
|
}
|
|
break;
|
case INDICATOR_ITEM5:
|
// 5: 财政经济形势-重大财税政策落实情况-减税降费落实情况
|
questionList = getQuestList(list, deptAreaCode,
|
QuestionTypeEnum.ENUM0);
|
score = CollUtils.isNotEmpty(questionList) ? -5D : 0D;
|
break;
|
case INDICATOR_ITEM6:
|
// 6:财政经济形势-重大财税政策落实情况-其他重大政策落实情况
|
questionList = getQuestList(list, deptAreaCode,
|
QuestionTypeEnum.ENUM1);
|
score = CollUtils.isNotEmpty(questionList) ? questionList.size() * -3D : 0D;
|
break;
|
case INDICATOR_ITEM7:
|
// 7:预算管理方面-转移支付-中央转移支付占地方可用财力比重
|
deptDividendValue = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD7);
|
deptDivisorValue = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD13);
|
provinceDividendValue = getProvinceBigDecimal(provinceFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD7);
|
provinceDivisorValue = getProvinceBigDecimal(provinceFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD13);
|
res1 = validateDivisorValue(deptDivisorValue);
|
res2 = validateDivisorValue(provinceDivisorValue);
|
score = 0D;
|
if (!res1 && !res2) {
|
score = getScore2(deptDividendValue, deptDivisorValue,
|
provinceDividendValue, provinceDivisorValue, vo);
|
}
|
break;
|
case INDICATOR_ITEM8:
|
// 8:预算管理方面-“三保”保障情况-“三保”年初预算保障情况
|
BigDecimal aw = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD47);
|
BigDecimal ap = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD40);
|
BigDecimal az = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD50);
|
BigDecimal aq = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD41);
|
BigDecimal bc = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD53);
|
BigDecimal ar = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD42);
|
boolean res = aw.compareTo(ap) < 0 || (az.compareTo(aq) < 0 || (bc.compareTo(ar)
|
< 0));
|
score = res ? 0 : vo.getMaxScore();
|
break;
|
case INDICATOR_ITEM9:
|
BigDecimal au = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD45);
|
BigDecimal r = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD13);
|
res1 = validateDivisorValue(r);
|
score = 0D;
|
if (!res1) {
|
BigDecimal divided = au.divide(r, 2, RoundingMode.HALF_UP);
|
if (divided.compareTo(BigDecimal.valueOf(0.6D)) > 0) {
|
BigDecimal add = BigDecimal.valueOf(0.6D).subtract(divided)
|
.multiply(BigDecimal.valueOf(100D))
|
.divide(BigDecimal.valueOf(4D), 2, RoundingMode.HALF_UP)
|
.add(BigDecimal.valueOf(8));
|
score = add.compareTo(BigDecimal.ZERO) >= 0 ? add.doubleValue() : 0D;
|
} else {
|
score = vo.getMaxScore();
|
}
|
}
|
|
break;
|
case INDICATOR_ITEM10:
|
// 10:预算管理方面-“三保”保障情况-“三保”支出保障情况
|
questionList = getQuestList(list, deptAreaCode, QuestionTypeEnum.ENUM2);
|
score = CollUtils.isNotEmpty(questionList) ? 0D : vo.getMaxScore();
|
break;
|
case INDICATOR_ITEM11:
|
// 11:预算管理方面-强化预算约束-存量资金盘活
|
questionList = getQuestList(list, deptAreaCode,
|
QuestionTypeEnum.ENUM3);
|
score = CollUtils.isNotEmpty(questionList) ? -3D : 0D;
|
break;
|
case INDICATOR_ITEM12:
|
// 12:预算管理方面-强化预算约束-不得无预算、超预算拨款
|
questionList = getQuestList(list, deptAreaCode,
|
QuestionTypeEnum.ENUM4);
|
score = CollUtils.isNotEmpty(questionList) ? -3D : 0D;
|
break;
|
case INDICATOR_ITEM13:
|
// 13:预算执行方面-库款管理-库款保障水平
|
BigDecimal currentData = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD35);
|
BigDecimal part1;
|
BigDecimal part2 = BigDecimal.ZERO;
|
if (currentData.compareTo(BigDecimal.valueOf(0.8D)) < 0) {
|
BigDecimal add = currentData.subtract(BigDecimal.valueOf(0.8D))
|
.divide(BigDecimal.valueOf(0.1D), 2, RoundingMode.HALF_UP)
|
.multiply(BigDecimal.valueOf(0.6D))
|
.add(BigDecimal.valueOf(3D));
|
part1 = add.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : add;
|
} else {
|
part1 = BigDecimal.valueOf(3D);
|
}
|
// BigDecimal first = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
// BasicDataFieldEnum.BASIC_DATA_FIELD36);
|
// BigDecimal second = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
// BasicDataFieldEnum.BASIC_DATA_FIELD37);
|
// BigDecimal third = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
// BasicDataFieldEnum.BASIC_DATA_FIELD38);
|
String year = tbBasicData.getQuarter().substring(0, 4);
|
List<BigDecimal> kuKuanList = tbBasicDataMapper.getKuKuanBaoZhangShuiPingByAreaCode(
|
sysUser.getAreaCode(),
|
year).stream()
|
.map(BigDecimal::new)
|
.collect(Collectors.toList());
|
|
part2 = kuKuanList.stream()
|
.anyMatch(item -> item.compareTo(BigDecimal.valueOf(0.3D)) <= 0)
|
? BigDecimal.ZERO
|
: BigDecimal.valueOf(3D);
|
|
score = part1.add(part2).doubleValue();
|
break;
|
case INDICATOR_ITEM14:
|
// 14:预算执行方面-预算执行情况-一般公共预算支出执行率
|
deptDividendValue = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD15);
|
deptDivisorValue = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD14);
|
String substring = tbBasicData.getQuarter().substring(4);
|
if (substring.equals("四季度")) {
|
// 使用全年评价
|
BigDecimal divide = deptDividendValue.divide(deptDivisorValue, 2,
|
RoundingMode.HALF_UP);
|
if (divide.compareTo(BigDecimal.valueOf(0.98D)) < 0) {
|
score = divide.subtract(BigDecimal.valueOf(0.98D))
|
.multiply(BigDecimal.valueOf(100D))
|
.divide(BigDecimal.valueOf(3D), 2, RoundingMode.HALF_UP)
|
.add(BigDecimal.valueOf(vo.getMaxScore())).doubleValue();
|
} else {
|
score = vo.getMaxScore();
|
}
|
}
|
score = getScoreByMonth(deptDividendValue, deptDivisorValue, month, vo);
|
break;
|
case INDICATOR_ITEM15:
|
// 15:预算执行方面-预算执行情况-政府性基金预算支出执行率
|
deptDividendValue = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD23);
|
deptDivisorValue = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD22);
|
res1 = validateDivisorValue(deptDivisorValue);
|
score = 0D;
|
if (!res1) {
|
score = getScoreByMonth(deptDividendValue, deptDivisorValue, month, vo);
|
}
|
break;
|
case INDICATOR_ITEM16:
|
// 16:预算执行方面-中央直达资金-中央直达资金支付进度
|
deptDividendValue = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD11);
|
BigDecimal divided1 = month.divide(BigDecimal.valueOf(12D), 2,
|
RoundingMode.HALF_UP);
|
if (deptDividendValue.compareTo(divided1) < 0) {
|
BigDecimal add = deptDividendValue.subtract(divided1)
|
.multiply(BigDecimal.valueOf(100D))
|
.divide(BigDecimal.valueOf(5D), 2,
|
RoundingMode.HALF_UP)
|
.add(BigDecimal.valueOf(vo.getMaxScore()));
|
score = add.compareTo(BigDecimal.ZERO) < 0 ? 0D : add.doubleValue();
|
} else {
|
score = vo.getMaxScore();
|
}
|
break;
|
case INDICATOR_ITEM17:
|
// 17:预算执行方面-中央直达资金-直达资金规范使用
|
questionList = getQuestList(list, deptAreaCode,
|
QuestionTypeEnum.ENUM5);
|
score = CollUtils.isNotEmpty(questionList) ? 0D : vo.getMaxScore();
|
break;
|
case INDICATOR_ITEM18:
|
// 18:风险防控方面-暂付款管理-违规新增暂付款
|
deptDividendValue = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD57);
|
score = deptDividendValue.compareTo(BigDecimal.ZERO) > 0 ? 0D
|
: vo.getMaxScore();
|
break;
|
case INDICATOR_ITEM19:
|
// 19:风险防控方面-暂付款管理-暂付款累计余额
|
BigDecimal bk = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD61);
|
BigDecimal t = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD15);
|
BigDecimal ab = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD23);
|
BigDecimal add = t.add(ab.divide(month.multiply(
|
BigDecimal.valueOf(12D).multiply(BigDecimal.valueOf(0.05D))), 2,
|
RoundingMode.HALF_UP));
|
score = bk.compareTo(add) > 0 ? 0D : vo.getMaxScore();
|
break;
|
case INDICATOR_ITEM20:
|
// 20:风险防控方面-暂付款管理-暂付款消化
|
deptDividendValue = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD59);
|
deptDivisorValue = getBigDecimal(sysUser.getAreaName(), deptFieldsMap,
|
BasicDataFieldEnum.BASIC_DATA_FIELD58);
|
res1 = validateDivisorValue(deptDivisorValue);
|
score = 0D;
|
if (!res1) {
|
BigDecimal d1 = deptDividendValue.divide(deptDivisorValue, 2,
|
RoundingMode.HALF_UP);
|
BigDecimal d2 = month.divide(BigDecimal.valueOf(12D), 2,
|
RoundingMode.HALF_UP);
|
score = d1.compareTo(d2) < 0 ? d1.divide(d2, 2, RoundingMode.HALF_UP)
|
.multiply(BigDecimal.valueOf(vo.getMaxScore())).doubleValue()
|
: vo.getMaxScore();
|
} else {
|
score = vo.getMaxScore();
|
}
|
break;
|
case INDICATOR_ITEM21:
|
// 21:风险防控方面-债务管理-法定债务率
|
score = getTextFieldScore(deptFieldsMap, BasicDataFieldEnum.BASIC_DATA_FIELD74,
|
vo);
|
break;
|
case INDICATOR_ITEM22:
|
// 22:风险防控方面-债务管理-隐性债务率
|
score = getTextFieldScore(deptFieldsMap, BasicDataFieldEnum.BASIC_DATA_FIELD76,
|
vo);
|
break;
|
case INDICATOR_ITEM23:
|
// 23:风险防控方面-债务管理-隐性债务化解
|
questionList = getQuestList(list, deptAreaCode,
|
QuestionTypeEnum.ENUM6);
|
score = CollUtils.isEmpty(questionList) ? vo.getMaxScore() : -3D;
|
break;
|
case INDICATOR_ITEM24:
|
// 24:风险防控方面-债务管理-日常监督发现问题
|
questionList = getQuestList(list, deptAreaCode,
|
QuestionTypeEnum.ENUM7);
|
if (CollUtils.isNotEmpty(questionList)) {
|
score = -18D + questionList.size() * -1D;
|
}
|
break;
|
case INDICATOR_ITEM25:
|
// 25:风险防控方面-日常监督发现问题
|
questionList = getQuestList(list, deptAreaCode,
|
QuestionTypeEnum.ENUM8);
|
if (CollUtils.isNotEmpty(questionList)) {
|
score = questionList.size() * -1D;
|
}
|
break;
|
default:
|
// Handle default case if needed
|
break;
|
}
|
Optional<TbScore> scoreOpt = scoreList.stream()
|
.filter(s -> s.getBasicDataConfigId().equals(vo.getId()))
|
.findFirst();
|
if (scoreOpt.isPresent()) {
|
TbScore tbScore = scoreOpt.get();
|
tbScore.setScore(score);
|
} else {
|
TbScore tbScore = new TbScore();
|
tbScore.setScore(score);
|
tbScore.setBasicDataId(tbBasicData.getId());
|
tbScore.setBasicDataConfigId(vo.getId());
|
scoreList.add(tbScore);
|
}
|
}
|
if (CollUtils.isNotEmpty(scoreList)) {
|
tbScoreService.saveOrUpdateBatch(scoreList);
|
}
|
}
|
|
private static boolean validateDivisorValue(BigDecimal deptDivisorValue) {
|
if (deptDivisorValue.compareTo(BigDecimal.ZERO) == 0) {
|
return true;
|
}
|
return false;
|
}
|
|
private static List<TbQuestion> getQuestList(List<TbQuestion> list, String deptAreaCode,
|
QuestionTypeEnum type) {
|
return list.stream()
|
.filter(q -> q.getDeptAreaCode().equals(deptAreaCode) && q.getType()
|
.equals(type))
|
.collect(Collectors.toList());
|
}
|
|
private BigDecimal getProvinceBigDecimal(Map<Long, TbBasicDataField> provinceFieldsMap,
|
BasicDataFieldEnum key) {
|
TbBasicDataField tbBasicDataField = provinceFieldsMap.get(key.getCode());
|
if (Objects.isNull(tbBasicDataField)) {
|
throw new ServiceException(
|
String.format("四川省的字段【%s】的数据缺失,请修改后再试", key.getDesc()));
|
}
|
return BigDecimal.valueOf(Double.parseDouble(tbBasicDataField.getFieldValue()));
|
}
|
|
private BigDecimal getBigDecimal(String areaName, Map<Long, TbBasicDataField> deptFieldsMap,
|
BasicDataFieldEnum key) {
|
TbBasicDataField tbBasicDataField = deptFieldsMap.get(key.getCode());
|
if (Objects.isNull(tbBasicDataField) || StringUtils.isBlank(
|
tbBasicDataField.getFieldValue())) {
|
throw new ServiceException(
|
String.format(areaName + "-" + "字段【%s】的数据缺失,请修改后再试",
|
key.getDesc()));
|
}
|
|
return BigDecimal.valueOf(
|
Double.parseDouble(tbBasicDataField.getFieldValue().replace(",", "")));
|
}
|
|
/**
|
* 通用计算公式获取得分
|
*
|
* @param deptDividendValue 部门被除数
|
* @param deptDivisorValue 部门除数
|
* @param provinceDividendValue 省份被除数
|
* @param provinceDivisorValue 省份除数
|
* @param vo 基础数据配置
|
* @return 得分
|
*/
|
private Double getScore(BigDecimal deptDividendValue, BigDecimal deptDivisorValue,
|
BigDecimal provinceDividendValue, BigDecimal provinceDivisorValue,
|
BasicDataConfigVO vo) {
|
BigDecimal score = BigDecimal.ZERO;
|
// 开始计算
|
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 Double getScore2(BigDecimal deptDividendValue, BigDecimal deptDivisorValue,
|
BigDecimal provinceDividendValue, BigDecimal provinceDivisorValue,
|
BasicDataConfigVO vo) {
|
BigDecimal score = BigDecimal.ZERO;
|
// 开始计算
|
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 = BigDecimal.valueOf(vo.getMaxScore());
|
} else {
|
score = deptDivided.subtract(provinceDivided)
|
.multiply(BigDecimal.valueOf(100L))
|
.add(BigDecimal.valueOf(vo.getMaxScore()));
|
score = score.compareTo(BigDecimal.ZERO) >= 0 ? score : BigDecimal.ZERO;
|
}
|
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;
|
}
|
|
private Double getScoreByMonth(BigDecimal deptDividendValue, BigDecimal deptDivisorValue,
|
BigDecimal currentMonth, BasicDataConfigVO vo) {
|
double score;
|
BigDecimal divided1 = deptDividendValue.divide(deptDivisorValue, 2,
|
RoundingMode.HALF_UP);
|
BigDecimal divided2 = currentMonth.divide(BigDecimal.valueOf(12D), 2,
|
RoundingMode.HALF_UP);
|
if (divided1.compareTo(
|
currentMonth.divide(BigDecimal.valueOf(12D), 2, RoundingMode.HALF_UP))
|
< 0) {
|
BigDecimal add = divided1.subtract(divided2)
|
.multiply(BigDecimal.valueOf(100D))
|
.divide(BigDecimal.valueOf(5D), 2,
|
RoundingMode.HALF_UP)
|
.add(BigDecimal.valueOf(vo.getMaxScore()));
|
score = add.compareTo(BigDecimal.ZERO) < 0 ? 0D : add.doubleValue();
|
} else {
|
score = vo.getMaxScore();
|
}
|
return score;
|
}
|
|
private Double getTextFieldScore(Map<Long, TbBasicDataField> deptFieldsMap,
|
BasicDataFieldEnum key,
|
BasicDataConfigVO vo) {
|
double score = 0D;
|
TbBasicDataField tbBasicDataField = deptFieldsMap.get(
|
key.getCode());
|
if (Objects.isNull(tbBasicDataField) || StringUtils.isBlank(
|
tbBasicDataField.getFieldValue())) {
|
throw new ServiceException(String.format("字段【%s】的数据缺失,请修改后再试",
|
key.getDesc()));
|
}
|
score = tbBasicDataField.getFieldValue().equals("绿") ? vo.getMaxScore()
|
: tbBasicDataField.getFieldValue().equals("黄") ? 6D
|
: tbBasicDataField.getFieldValue().equals("橙") ? 3D : 0D;
|
return score;
|
}
|
|
@Override
|
public void subtractScoreWithFixedRules(String deptAreaCode) throws Exception {
|
String previousQuarter = DateUtils.getPreviousQuarter();
|
TbBasicData tbBasicData = tbBasicDataMapper.selectOne(
|
Wrappers.lambdaQuery(TbBasicData.class).eq(TbBasicData::getQuarter, previousQuarter)
|
.eq(TbBasicData::getDeptAreaCode, deptAreaCode));
|
if (Objects.isNull(tbBasicData)) {
|
return;
|
}
|
List<TbScore> scoreList = tbScoreService.lambdaQuery()
|
.eq(TbScore::getBasicDataId, tbBasicData.getId()).list();
|
List<BasicDataConfigVO> fixedRulesConfigList = tbBasicDataConfigService.getSubsractRulesConfigList();
|
List<TbQuestion> list = tbQuestionMapper.selectList(
|
Wrappers.lambdaQuery(TbQuestion.class)
|
.eq(TbQuestion::getQuarter, previousQuarter)
|
.eq(TbQuestion::getDeptAreaCode, deptAreaCode));
|
List<TbQuestion> questionList;
|
|
for (BasicDataConfigVO vo : fixedRulesConfigList) {
|
double score = 0D;
|
switch (Objects.requireNonNull(IndicatorItemEnum.getEnumByCode(vo.getId()))) {
|
case INDICATOR_ITEM5:
|
// 5: 财政经济形势-重大财税政策落实情况-减税降费落实情况
|
questionList = getQuestList(list, deptAreaCode,
|
QuestionTypeEnum.ENUM0);
|
score = CollUtils.isNotEmpty(questionList) ? -5D : 0D;
|
break;
|
case INDICATOR_ITEM6:
|
// 6:财政经济形势-重大财税政策落实情况-其他重大政策落实情况
|
questionList = getQuestList(list, deptAreaCode,
|
QuestionTypeEnum.ENUM1);
|
score = CollUtils.isNotEmpty(questionList) ? questionList.size() * -3D : 0D;
|
break;
|
case INDICATOR_ITEM11:
|
// 11:预算管理方面-强化预算约束-存量资金盘活
|
questionList = getQuestList(list, deptAreaCode,
|
QuestionTypeEnum.ENUM3);
|
score = CollUtils.isNotEmpty(questionList) ? -3D : 0D;
|
break;
|
case INDICATOR_ITEM12:
|
// 12:预算管理方面-强化预算约束-不得无预算、超预算拨款
|
questionList = getQuestList(list, deptAreaCode,
|
QuestionTypeEnum.ENUM4);
|
score = CollUtils.isNotEmpty(questionList) ? -3D : 0D;
|
break;
|
case INDICATOR_ITEM23:
|
// 23:风险防控方面-债务管理-隐性债务化解
|
questionList = getQuestList(list, deptAreaCode,
|
QuestionTypeEnum.ENUM6);
|
score = CollUtils.isNotEmpty(questionList) ? vo.getMaxScore() : -3D;
|
break;
|
case INDICATOR_ITEM24:
|
// 24:风险防控方面-债务管理-日常监督发现问题
|
questionList = getQuestList(list, deptAreaCode,
|
QuestionTypeEnum.ENUM7);
|
if (CollUtils.isNotEmpty(questionList)) {
|
score = -18D + questionList.size() * -1D;
|
}
|
case INDICATOR_ITEM25:
|
// 25:风险防控方面-日常监督发现问题
|
questionList = getQuestList(list, deptAreaCode,
|
QuestionTypeEnum.ENUM8);
|
if (CollUtils.isNotEmpty(questionList)) {
|
score = questionList.size() * -1D;
|
}
|
break;
|
|
}
|
Optional<TbScore> scoreOpt = scoreList.stream()
|
.filter(s -> s.getBasicDataConfigId().equals(vo.getId()))
|
.findFirst();
|
if (scoreOpt.isPresent()) {
|
TbScore tbScore = scoreOpt.get();
|
tbScore.setScore(score);
|
} else {
|
TbScore tbScore = new TbScore();
|
tbScore.setScore(score);
|
tbScore.setBasicDataId(tbBasicData.getId());
|
tbScore.setBasicDataConfigId(vo.getId());
|
scoreList.add(tbScore);
|
}
|
}
|
if (CollUtils.isNotEmpty(scoreList)) {
|
tbScoreService.saveOrUpdateBatch(scoreList);
|
}
|
}
|
}
|