mitao
2024-07-09 07c83c163675e24252de05d029cef2eab046e583
finance-system/src/main/java/com/finance/system/listener/BasicDataListener.java
@@ -4,11 +4,7 @@
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.util.ListUtils;
import com.alibaba.fastjson2.JSON;
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.CalculateTypeEnum;
import com.finance.common.enums.DataScreenConfigEnum;
import com.finance.common.enums.FieldInputTypeEnum;
import com.finance.common.enums.FieldTypeEnum;
@@ -17,16 +13,14 @@
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.TbDataScreenScore;
import com.finance.system.domain.TbField;
import com.finance.system.domain.TbScore;
import com.finance.system.dto.CalculateItemDTO;
import com.finance.system.service.AsyncService;
import com.finance.system.service.TbBasicDataConfigDetailService;
import com.finance.system.service.TbBasicDataConfigService;
import com.finance.system.service.TbBasicDataFieldService;
@@ -41,9 +35,9 @@
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.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
@@ -65,7 +59,9 @@
    public TbBasicDataConfigDetailService tbBasicDataConfigDetailService;
    public TbScoreService tbScoreService;
    public TbDataScreenScoreService tbDataScreenScoreService;
    public String quarter;
    public TbDataScreenConfigService tbDataScreenConfigService;
    public AsyncService asyncService;
    public BasicDataListener(TbBasicDataService tbBasicDataService,
            TbFieldService tbFieldService,
@@ -73,7 +69,8 @@
            TbBasicDataConfigService tbBasicDataConfigService,
            TbBasicDataConfigDetailService tbBasicDataConfigDetailService,
            TbScoreService tbScoreService, TbDataScreenScoreService tbDataScreenScoreService,
            TbDataScreenConfigService tbDataScreenConfigService) {
            String quarter,
            TbDataScreenConfigService tbDataScreenConfigService, AsyncService asyncService) {
        this.tbBasicDataService = tbBasicDataService;
        this.tbFieldService = tbFieldService;
        this.areaCode = areaCode;
@@ -82,7 +79,9 @@
        this.tbBasicDataConfigDetailService = tbBasicDataConfigDetailService;
        this.tbScoreService = tbScoreService;
        this.tbDataScreenConfigService = tbDataScreenConfigService;
        this.quarter = quarter;
        this.tbDataScreenScoreService = tbDataScreenScoreService;
        this.asyncService = asyncService;
    }
    @Override
@@ -158,46 +157,45 @@
        // 查询需要填写的动态字段
        List<TbField> fieldList =
                tbFieldService.lambdaQuery().eq(TbField::getStatus, ShowStatusEnum.SHOW).list();
        Map<Integer, String> categoryOneMap = cachedDataList.get(0);
        Map<Integer, String> categoryTwoMap = cachedDataList.get(1);
        Map<Integer, String> categoryThreeMap = cachedDataList.get(2);
        Map<Integer, String> headMap = cachedDataList.get(3);
        int remarkIndex = headMap.size() - 1;
        Map<Integer, String> dynamicFieldsMap = getDynamicHeadMap(headMap, remarkIndex);
        Map<Integer, String> dynamicCategoryOneMap = getDynamicHeadMap(cachedDataList.get(0),
                remarkIndex);
        Map<Integer, String> dynamicCategoryTwoMap = getDynamicHeadMap(cachedDataList.get(1),
                remarkIndex);
        Map<Integer, String> dynamicCategoryThreeMap = getDynamicHeadMap(cachedDataList.get(2),
                remarkIndex);
        Map<Integer, String> dataMap = cachedDataList.get(5);
        log.info("{}条数据,开始存储数据库!", cachedDataList.size());
        log.info("表头:{}", JSON.toJSONString(headMap));
        log.info("填写的数据:{}", JSON.toJSONString(dataMap));
        log.info("所有数据:{}", JSON.toJSONString(cachedDataList));
        int remarkIndex = headMap.size() - 1;
        Map<Integer, String> dynamicFieldsMap = getIntegerStringMap(headMap, remarkIndex);
        Map<Integer, String> dynamicCategoryOneMap = getIntegerStringMap(categoryOneMap,
                remarkIndex);
        Map<Integer, String> dynamicCategoryTwoMap = getIntegerStringMap(categoryTwoMap,
                remarkIndex);
        Map<Integer, String> dynamicCategoryThreeMap = getIntegerStringMap(categoryThreeMap,
                remarkIndex);
        List<String> dynamicFields = new ArrayList<>(dynamicFieldsMap.values());
        List<String> collect = fieldList.stream().map(TbField::getFieldName)
                .collect(Collectors.toList());
        boolean flag = new ArrayList<>(dynamicFields).containsAll(collect);
        if (dynamicFields.size() != collect.size() || !flag) {
        if (dynamicFields.size() != fieldList.size() || !flag) {
            throw new ServiceException("导入失败,请下载最新的导入模板");
        }
        LocalDate now = LocalDate.now();
        TbBasicData tbBasicData;
        String quarter = dataMap.get(1);
        Optional<TbBasicData> tbBasicDataOpt = tbBasicDataService.lambdaQuery().
                eq(TbBasicData::getQuarter, quarter)
                .eq(TbBasicData::getDeptAreaCode, areaCode).oneOpt();
        tbBasicData = tbBasicDataOpt.orElseGet(TbBasicData::new);
        tbBasicData.setQuarter(DateUtils.getNowQuarter());
        tbBasicData.setQuarter(quarter);
        tbBasicData.setTransferPaymentScale(dataMap.get(2));
        tbBasicData.setCurrentGdp(dataMap.get(3));
        tbBasicData.setDeptAreaCode(areaCode);
        tbBasicData.setRemark(dataMap.get(remarkIndex));
        tbBasicData.setStatus(ReportingStatusEnum.MISSING_DATA);
        tbBasicData.setReportingTime(DateUtils.getQuarterDate(quarter));
        long count = dataMap.entrySet().stream()
                .filter(entry -> StringUtils.isBlank(entry.getValue())).count();
        tbBasicData.setStatus(
                count > 0 ? ReportingStatusEnum.MISSING_DATA : ReportingStatusEnum.FILLED);
        tbBasicDataService.saveOrUpdate(tbBasicData);
        tbBasicDataFieldService.remove(Wrappers.<TbBasicDataField>lambdaQuery()
                .eq(TbBasicDataField::getBasicDataId, tbBasicData.getId()));
@@ -217,11 +215,36 @@
        currentGdp.setFieldValue(tbBasicData.getCurrentGdp());
        fields.add(currentGdp);
        //遍历动态字段map
        for (Map.Entry<Integer, String> integerStringEntry : dynamicFieldsMap.entrySet()) {
        for (Entry<Integer, String> entry : dynamicFieldsMap.entrySet()) {
            Integer key = entry.getKey();
            String fieldStr = entry.getValue();
            String categoryOne = dynamicCategoryOneMap.get(key);
            String categoryTwo = dynamicCategoryTwoMap.get(key);
            String categoryThree = dynamicCategoryThreeMap.get(key);
            TbField field = getFieldByFieldName(fieldList, categoryOne, categoryTwo,
                    categoryThree, fieldStr);
            if (Objects.nonNull(field)) {
                String value = dataMap.get(key);
                TbBasicDataField tbBasicDataField = new TbBasicDataField();
                tbBasicDataField.setBasicDataId(tbBasicData.getId());
                tbBasicDataField.setFieldId(field.getId());
                tbBasicDataField.setFieldName(field.getFieldName());
                tbBasicDataField.setFieldValue(value);
                fields.add(tbBasicDataField);
            }
        }
        /*for (Entry<Integer, String> integerStringEntry : dynamicFieldsMap.entrySet()) {
            String categoryOne = dynamicCategoryOneMap.get(integerStringEntry.getKey());
            String categoryTwo = dynamicCategoryTwoMap.get(integerStringEntry.getKey());
            String categoryThree = dynamicCategoryThreeMap.get(integerStringEntry.getKey());
            String fieldStr = integerStringEntry.getValue();
            if (fieldStr.equals("库款保障水平-第一月") || fieldStr.equals("库款保障水平-第二月")
                    || fieldStr.equals("库款保障水平-第三月")) {
                continue;
            }
            boolean res = !fieldStr.equals(categoryTwo);
            List<TbField> tbField = tbFieldService.lambdaQuery()
                    .eq(TbField::getFieldName, fieldStr)
@@ -231,131 +254,123 @@
                    .eq(!fieldStr.equals(categoryThree) && res, TbField::getLevelThreeCategory,
                            categoryThree)
                    .list();
            if (CollUtils.isNotEmpty(tbField)) {
                TbField field = tbField.get(0);
                String value = validateFields(integerStringEntry, dataMap, field);
            TbField field = getFieldByFieldName(fieldList, categoryOne,
                    categoryTwo, categoryThree, fieldStr);
            // String value = validateFields(integerStringEntry, dataMap, field);
            if (Objects.nonNull(field)) {
                String value = dataMap.get(integerStringEntry.getKey());
                TbBasicDataField tbBasicDataField = new TbBasicDataField();
                tbBasicDataField.setBasicDataId(tbBasicData.getId());
                tbBasicDataField.setFieldId(field.getId());
                tbBasicDataField.setFieldName(field.getFieldName());
                tbBasicDataField.setFieldValue(value);
                if (fieldStr.equals("库款保障水平")) {
                    String firstMonthValue = dataMap.get(integerStringEntry.getKey() + 1);
                    String secondMonthValue = dataMap.get(integerStringEntry.getKey() + 2);
                    String thirdMonthValue = dataMap.get(integerStringEntry.getKey() + 3);
                    tbBasicDataField.setFirstMonthValue(firstMonthValue);
                    tbBasicDataField.setSecondMonthValue(secondMonthValue);
                    tbBasicDataField.setThirdMonthValue(thirdMonthValue);
                }
                fields.add(tbBasicDataField);
            }
        }
        }*/
        tbBasicDataFieldService.saveBatch(fields);
        tbBasicData.setStatus(ReportingStatusEnum.FILLED);
        tbBasicDataService.updateById(tbBasicData);
        log.info(String.format("%s导入基础数据成功!", dataMap.get(0)));
        CompletableFuture.runAsync(() -> {
            calculateScore(tbBasicData, fields);
            calculateScreenScore(tbBasicData, fields);
        });
        // asyncService.calculateScore(tbBasicData, fields);
        asyncService.asyncTask();
    }
    /**
     * 需要导入的数据
     *
     * @return List<Map < Integer, String>>
     */
    private List<Map<Integer, String>> getMapList() {
        for (int i = 0; i < cachedDataList.size(); i++) {
            if (cachedDataList.get(i).get(0).equals("栏号")) {
                return cachedDataList.subList(i + 1, cachedDataList.size());
            }
        }
        return null;
    }
    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 =
                    !fieldStr.equals(categoryTwo) ? (!fieldStr.equals(categoryThree) ? 3 : 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;
    }
    @NotNull
    private static Map<Integer, String> getIntegerStringMap(Map<Integer, String> headMap,
    private static Map<Integer, String> getDynamicHeadMap(Map<Integer, String> headMap,
            int remarkIndex) {
        Map<Integer, String> dynamicFieldsMap = headMap.entrySet().stream()
                .filter(entry -> !(Lists.newArrayList(0, 1, 2, 3).contains(entry.getKey())
                        || entry.getKey() == remarkIndex))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
        return dynamicFieldsMap;
    }
    private 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 (Map.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);
    }
    private void calculateScreenScore(TbBasicData tbBasicData,
            List<TbBasicDataField> tbBasicDataFields) {