mitao
2024-07-09 07c83c163675e24252de05d029cef2eab046e583
完成基础数据导入
16个文件已修改
5个文件已添加
1274 ■■■■ 已修改文件
finance-admin-dept/src/main/java/com/finance/FinanceAdminDeptApplication.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-admin/src/main/java/com/finance/web/controller/api/HistoryDataController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-admin/src/main/java/com/finance/web/controller/api/TbBasicDataCategoryController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-admin/src/main/java/com/finance/web/controller/api/TbBasicDataConfigController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-admin/src/main/java/com/finance/web/controller/api/TbFieldCategoryController.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-admin/src/main/java/com/finance/web/controller/api/TbFieldController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-admin/src/test/java/com/finance/FinanceManageApplicationTest.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-common/src/main/java/com/finance/common/config/AsyncThreadPoolConfig.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-common/src/main/java/com/finance/common/enums/BasicDataFieldEnum.java 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-common/src/main/java/com/finance/common/enums/IndicatorItemEnum.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-system/src/main/java/com/finance/system/domain/TbBasicDataField.java 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-system/src/main/java/com/finance/system/dto/BasicDataFieldDTO.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-system/src/main/java/com/finance/system/listener/BasicDataListener.java 281 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-system/src/main/java/com/finance/system/listener/HistoryDataListener.java 167 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-system/src/main/java/com/finance/system/service/AsyncService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-system/src/main/java/com/finance/system/service/TbBasicDataConfigService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-system/src/main/java/com/finance/system/service/impl/AsyncServiceImpl.java 394 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-system/src/main/java/com/finance/system/service/impl/TbBasicDataConfigServiceImpl.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-system/src/main/java/com/finance/system/service/impl/TbBasicDataServiceImpl.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-system/src/main/java/com/finance/system/service/impl/TbFieldServiceImpl.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-system/src/main/java/com/finance/system/vo/BasicDataConfigVO.java 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
finance-admin-dept/src/main/java/com/finance/FinanceAdminDeptApplication.java
@@ -1,8 +1,11 @@
package com.finance;
import com.finance.system.service.AsyncService;
import java.net.InetAddress;
import java.net.UnknownHostException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -23,6 +26,9 @@
@EnableScheduling//开启定时任务
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class FinanceAdminDeptApplication {
    @Autowired
    private AsyncService asyncService;
    public static void main(String[] args) throws UnknownHostException {
        ConfigurableApplicationContext application = SpringApplication.run(
@@ -55,4 +61,17 @@
        return restTemplate;
    }
    @Bean
    public ApplicationRunner applicationRunner() {
        return applicationArguments -> {
            long startTime = System.currentTimeMillis();
            System.out.println(Thread.currentThread().getName() + ":开始调用异步业务");
            asyncService.asyncTask();
            long endTime = System.currentTimeMillis();
            System.out.println(
                    Thread.currentThread().getName() + ":调用异步业务结束,耗时:" + (endTime
                            - startTime));
        };
    }
}
finance-admin/src/main/java/com/finance/web/controller/api/HistoryDataController.java
@@ -6,7 +6,6 @@
import com.finance.common.basic.PageDTO;
import com.finance.common.core.domain.R;
import com.finance.common.enums.BusinessType;
import com.finance.common.enums.ReportingStatusEnum;
import com.finance.common.exception.ServiceException;
import com.finance.system.domain.TbBasicData;
import com.finance.system.dto.update.BasicDataUpdDTO;
@@ -74,7 +73,7 @@
        Page<TbBasicData> page =
                tbBasicDataService
                        .lambdaQuery()
                        .eq(TbBasicData::getStatus, ReportingStatusEnum.FILLED)
                        // .eq(TbBasicData::getStatus, ReportingStatusEnum.FILLED)
                        .between(flag, TbBasicData::getReportingTime, startTime, endTime)
                        .groupBy(TbBasicData::getQuarter)
                        .orderByDesc(TbBasicData::getReportingTime)
finance-admin/src/main/java/com/finance/web/controller/api/TbBasicDataCategoryController.java
@@ -72,6 +72,9 @@
    @PostMapping("/edit")
    @ApiOperation("编辑")
    public R<Void> add(@RequestBody @Validated BasicDataCategoryUpdateDTO dto) {
        if (dto.getId() <= 17) {
            throw new ServiceException("该基础数据分类不能修改");
        }
        try {
            tbBasicDataCategoryService.update(dto);
        } catch (Exception e) {
@@ -93,6 +96,9 @@
    @DeleteMapping("/delete")
    @ApiOperation("删除")
    public R<Void> delete(@RequestParam(value = "id") Long id) {
        if (id <= 17) {
            throw new ServiceException("该基础数据分类不能删除");
        }
        try {
            tbBasicDataCategoryService.removeById(id);
        } catch (Exception e) {
@@ -137,6 +143,9 @@
    @PostMapping("/show-hide")
    @ApiOperation("隐藏显示操作")
    public R<Void> showHide(@RequestBody ShowHideDTO dto) {
        if (dto.getId() <= 17) {
            throw new ServiceException("该基础数据分类不能隐藏");
        }
        try {
            tbBasicDataCategoryService.showHide(dto);
        } catch (Exception e) {
finance-admin/src/main/java/com/finance/web/controller/api/TbBasicDataConfigController.java
@@ -142,6 +142,9 @@
    @PostMapping("/edit")
    @ApiOperation("编辑")
    public R<Void> edit(@RequestBody @Validated BasicDataConfigUpdateDTO dto) {
        if (dto.getId() <= 24) {
            return R.fail("该基础数据配置不可操作");
        }
        try {
            tbBasicDataConfigService.edit(dto);
        } catch (Exception e) {
@@ -184,6 +187,9 @@
    @DeleteMapping("/delete")
    @ApiOperation("删除")
    public R<Void> delete(Long id) {
        if (id <= 24) {
            return R.fail("该基础数据配置不可操作");
        }
        try {
            tbBasicDataConfigService.delete(id);
        } catch (Exception e) {
@@ -205,6 +211,9 @@
    @PostMapping("show-hide")
    @ApiOperation("隐藏显示操作")
    public R<Void> showHide(@RequestBody ShowHideDTO dto) {
        if (dto.getId() <= 24) {
            return R.fail("该基础数据配置不可操作");
        }
        try {
            tbBasicDataConfigService.showHide(dto);
        } catch (Exception e) {
finance-admin/src/main/java/com/finance/web/controller/api/TbFieldCategoryController.java
@@ -16,7 +16,14 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
@@ -37,6 +44,7 @@
    /**
     * 添加
     *
     * @param dto 字段分类数据传输对象
     * @return R
     */
@@ -57,6 +65,7 @@
    /**
     * 根据id获取字段分类详情
     *
     * @param id 字段分类id
     * @return R
     */
@@ -77,6 +86,7 @@
    /**
     * 分页条件查询
     *
     * @param query 部门条件查询对象
     * @return PageVO<FieldCategoryDetailVO>
     */
@@ -96,12 +106,16 @@
    /**
     * 隐藏显示操作
     *
     * @param dto 显示隐藏操作数据传输对象
     * @return R
     */
    @PostMapping("/show-hide")
    @ApiOperation("隐藏显示操作")
    public R<Void> showHide(@RequestBody ShowHideDTO dto) {
        if (dto.getId() < 50) {
            throw new ServiceException("固定字段分类,不能操作!");
        }
        try {
            tbFieldCategoryService.showHide(dto);
        } catch (Exception e) {
@@ -116,14 +130,19 @@
    /**
     * 删除分类子节点
     *
     * @param id id
     * @return R
     */
    @DeleteMapping("/delete-children")
    @ApiOperation("编辑页面删除子字段分类")
    public R<Object> deleteChildren(@RequestParam(value = "id") Long id){
        if (id < 50) {
            throw new ServiceException("固定字段分类,不能操作!");
        }
        try {
            tbFieldCategoryService.deleteChildren(id);
        } catch (Exception e) {
            if (e instanceof ServiceException) {
                return R.fail(e.getMessage());
@@ -136,12 +155,16 @@
    /**
     * 删除分类
     *
     * @param id id
     * @return R
     */
    @DeleteMapping("/delete")
    @ApiOperation("列表页面删除分类")
    public R<Void> delete(@RequestParam(value = "id") Long id){
        if (id < 50) {
            throw new ServiceException("固定字段分类,不能操作");
        }
        try {
            tbFieldCategoryService.delete(id);
        } catch (Exception e) {
@@ -156,12 +179,16 @@
    /**
     * 编辑分类
     *
     * @param dto 字段分类更新数据传输对象
     * @return R
     */
    @PutMapping("/edit")
    @ApiOperation("编辑")
    public R<Object> edit(@RequestBody FieldCategoryUpdateDTO dto) {
        if (dto.getId() < 50) {
            throw new ServiceException("固定字段分类,不能操作");
        }
        try {
            tbFieldCategoryService.edit(dto);
        } catch (Exception e) {
finance-admin/src/main/java/com/finance/web/controller/api/TbFieldController.java
@@ -90,6 +90,9 @@
    @GetMapping("/influenced-data")
    @ApiOperation("隐藏字段,获取同步隐藏的基础数据")
    public R<String> influencedData(@RequestParam Long id) {
        if (id <= 88) {
            throw new ServiceException("固定字段,不能操作");
        }
        try {
            return R.ok(tbFieldService.influencedData(id));
        } catch (Exception e) {
@@ -110,6 +113,9 @@
    @PostMapping("/show-hide")
    @ApiOperation("隐藏显示操作")
    public R<Void> showHide(@RequestBody ShowHideDTO dto) {
        if (dto.getId() <= 88) {
            throw new ServiceException("固定字段,不能操作");
        }
        try {
            tbFieldService.showHide(dto);
        } catch (Exception e) {
@@ -131,6 +137,9 @@
    @PostMapping("/edit")
    @ApiOperation("编辑字段")
    public R<Void> editField(@RequestBody @Validated FieldUpdateDTO dto) {
        if (dto.getId() <= 88) {
            throw new ServiceException("固定字段,不能操作");
        }
        try {
            tbFieldService.editField(dto);
        } catch (Exception e) {
@@ -193,6 +202,9 @@
    @DeleteMapping("/delete")
    @ApiOperation("删除")
    public R<Void> delete(@RequestParam Long id) {
        if (id <= 88) {
            throw new ServiceException("固定字段,不能操作");
        }
        try {
            tbFieldService.removeById(id);
        } catch (Exception e) {
finance-admin/src/test/java/com/finance/FinanceManageApplicationTest.java
@@ -3,7 +3,17 @@
import static com.finance.web.controller.service.DepartmentRanking.DATA_ONE_SCORE_RANKING_KEY;
import static com.finance.web.controller.service.DepartmentRanking.TOTAL_SCORE_RANKING_KEY;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.finance.common.enums.ShowStatusEnum;
import com.finance.system.domain.TbBasicData;
import com.finance.system.domain.TbBasicDataField;
import com.finance.system.domain.TbField;
import com.finance.system.mapper.TbBasicDataFieldMapper;
import com.finance.system.mapper.TbBasicDataMapper;
import com.finance.system.service.AsyncService;
import com.finance.system.service.TbFieldService;
import com.finance.web.controller.service.DepartmentRanking;
import java.util.List;
import javax.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@@ -17,6 +27,14 @@
    @Resource
    private DepartmentRanking departmentRanking;
    @Resource
    private AsyncService asyncService;
    @Resource
    private TbBasicDataMapper basicDataMapper;
    @Resource
    private TbBasicDataFieldMapper basicDataFieldMapper;
    @Resource
    private TbFieldService tbFieldService;
    @Test
    public void test() {
@@ -58,5 +76,17 @@
            System.out.println("Area2 not found in the ranking.");
        }
    }
    @Test
    public void test2() {
        TbBasicData one = basicDataMapper.selectOne(
                Wrappers.lambdaQuery(TbBasicData.class).eq(TbBasicData::getId, "1"));
        List<TbBasicDataField> list = basicDataFieldMapper.selectList(
                Wrappers.lambdaQuery(TbBasicDataField.class)
                        .eq(TbBasicDataField::getBasicDataId, one.getId()));
        List<TbField> fieldList =
                tbFieldService.lambdaQuery().eq(TbField::getStatus, ShowStatusEnum.SHOW).list();
        asyncService.calculateScoreWithFixedRules(one, list, fieldList);
    }
}
finance-common/src/main/java/com/finance/common/config/AsyncThreadPoolConfig.java
New file
@@ -0,0 +1,32 @@
package com.finance.common.config;
import java.util.concurrent.ThreadPoolExecutor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@EnableAsync
@Configuration
public class AsyncThreadPoolConfig {
    private static final int MAX_POOL_SIZE = 50;
    private static final int CORE_POOL_SIZE = 20;
    private static final int TASK_NUM = 200;
    private static final int ACTIVE_TIME = 60;
    @Bean("asyncTaskExecutor")
    public AsyncTaskExecutor asyncTaskExecutor() {
        ThreadPoolTaskExecutor asyncTaskExecutor = new ThreadPoolTaskExecutor();
        asyncTaskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
        asyncTaskExecutor.setCorePoolSize(CORE_POOL_SIZE);
        asyncTaskExecutor.setQueueCapacity(TASK_NUM);
        asyncTaskExecutor.setKeepAliveSeconds(ACTIVE_TIME);
        asyncTaskExecutor.setThreadNamePrefix("async-task-thread-pool-");
        asyncTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        asyncTaskExecutor.initialize();
        return asyncTaskExecutor;
    }
}
finance-common/src/main/java/com/finance/common/enums/BasicDataFieldEnum.java
New file
@@ -0,0 +1,130 @@
package com.finance.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum BasicDataFieldEnum {
    BASIC_DATA_FIELD1(1L, "(一)一般公共预算-一般公共预算收入-预算数"),
    BASIC_DATA_FIELD2(2L, "(一)一般公共预算-一般公共预算收入-当期执行数-完成数"),
    BASIC_DATA_FIELD3(3L,
            "(一)一般公共预算-一般公共预算收入-当期执行数-其中:税收收入"),
    BASIC_DATA_FIELD4(4L, "(一)一般公共预算-一般公共预算收入-上年同期执行数-完成数"),
    BASIC_DATA_FIELD5(5L, "(一)一般公共预算-一般公共预算收入-上年同期执行数-其中:税收收入"),
    BASIC_DATA_FIELD6(6L, "(一)一般公共预算-上级补助收入-预算数"),
    BASIC_DATA_FIELD7(7L, "(一)一般公共预算-上级补助收入-执行数"),
    BASIC_DATA_FIELD8(8L, "(一)一般公共预算-调入资金-预算数"),
    BASIC_DATA_FIELD9(9L, "(一)一般公共预算-调入资金-预算数"),
    BASIC_DATA_FIELD10(10L, "(一)一般公共预算-动用预算稳定调节基金-预算数"),
    BASIC_DATA_FIELD11(11L, "(一)一般公共预算-动用预算稳定调节基金-执行数"),
    BASIC_DATA_FIELD12(12L,
            "(一)一般公共预算-综合财力 (本级收入+上级补助-上解+下级上解收入-补助下级支出)-预算数"),
    BASIC_DATA_FIELD13(13L,
            "(一)一般公共预算-综合财力 (本级收入+上级补助-上解+下级上解收入-补助下级支出)-执行数"),
    BASIC_DATA_FIELD14(14L, "(一)一般公共预算-一般公共预算支出-预算数"),
    BASIC_DATA_FIELD15(15L, "(一)一般公共预算-一般公共预算支出-当期执行数"),
    BASIC_DATA_FIELD16(16L, "(一)一般公共预算-一般公共预算支出-上年同期执行数"),
    BASIC_DATA_FIELD17(17L, "(二)政府性基金预算-政府性基金预算收入-预算数"),
    BASIC_DATA_FIELD18(18L, "(二)政府性基金预算-政府性基金预算收入-当期执行数"),
    BASIC_DATA_FIELD19(19L, "(二)政府性基金预算-政府性基金预算收入-上年同期执行数"),
    BASIC_DATA_FIELD20(20L,
            "(二)政府性基金预算-可用财力 (本级收入+上级补助-上解+下级上解收入-补助下级支出)-预算数"),
    BASIC_DATA_FIELD21(21L,
            "(二)政府性基金预算-可用财力 (本级收入+上级补助-上解+下级上解收入-补助下级支出)-执行数"),
    BASIC_DATA_FIELD22(22L, "(二)政府性基金预算-政府性基金预算支出-预算数"),
    BASIC_DATA_FIELD23(23L, "(二)政府性基金预算-政府性基金预算支出-当期执行数"),
    BASIC_DATA_FIELD24(24L, "(二)政府性基金预算-政府性基金预算支出-上年同期执行数"),
    BASIC_DATA_FIELD25(25L, "(二)政府性基金预算-调出资金-预算数"),
    BASIC_DATA_FIELD26(26L, "(二)政府性基金预算-调出资金-执行数"),
    BASIC_DATA_FIELD27(27L, "(三)库款保障情况-期初库款余额"),
    BASIC_DATA_FIELD28(28L, "(三)库款保障情况-本期库款流入"),
    BASIC_DATA_FIELD29(29L, "(三)库款保障情况-本期库款流出"),
    BASIC_DATA_FIELD30(30L, "(三)库款保障情况-期末库款余额-余额"),
    BASIC_DATA_FIELD31(31L, "(三)库款保障情况-期末库款余额-其中:-一般账户余额"),
    BASIC_DATA_FIELD32(32L, "(三)库款保障情况-期末库款余额-其中:-工资账户余额"),
    BASIC_DATA_FIELD33(33L, "(三)库款保障情况-期末库款余额-其中:-基本民生账户余额"),
    BASIC_DATA_FIELD34(34L, "(三)库款保障情况-期末库款余额-其中:-直达资金账户余额"),
    BASIC_DATA_FIELD35(35L, "(三)库款保障情况-库款保障水平-当前季度数据"),
    BASIC_DATA_FIELD36(36L, "(三)库款保障情况-库款保障水平-第一月数据"),
    BASIC_DATA_FIELD37(37L, "(三)库款保障情况-库款保障水平-第二月数据"),
    BASIC_DATA_FIELD38(38L, "(三)库款保障情况-库款保障水平-第三月数据"),
    BASIC_DATA_FIELD39(39L,
            "(四)“三保”保障情况-国家标准“三保”支出(按照财预便[2021]164号的范围和标准填列)-合计-需求数"),
    BASIC_DATA_FIELD40(40L,
            "(四)“三保”保障情况-国家标准“三保”支出(按照财预便[2021]164号的范围和标准填列)-保基本民生-需求数"),
    BASIC_DATA_FIELD41(41L,
            "(四)“三保”保障情况-国家标准“三保”支出(按照财预便[2021]164号的范围和标准填列)-保工资-需求数"),
    BASIC_DATA_FIELD42(42L,
            "(四)“三保”保障情况-国家标准“三保”支出(按照财预便[2021]164号的范围和标准填列)-保运转-需求数"),
    BASIC_DATA_FIELD43(43L,
            "(四)“三保”保障情况-地方标准“三保”支出(以地方实际结构填列,含国标)-合计-需求数"),
    BASIC_DATA_FIELD44(44L,
            "(四)“三保”保障情况-地方标准“三保”支出(以地方实际结构填列,含国标)-合计-预算数"),
    BASIC_DATA_FIELD45(45L,
            "(四)“三保”保障情况-地方标准“三保”支出(以地方实际结构填列,含国标)-合计-执行数"),
    BASIC_DATA_FIELD46(46L,
            "(四)“三保”保障情况-地方标准“三保”支出(以地方实际结构填列,含国标)-保基本民生-需求数"),
    BASIC_DATA_FIELD47(47L,
            "(四)“三保”保障情况-地方标准“三保”支出(以地方实际结构填列,含国标)-保基本民生-预算数"),
    BASIC_DATA_FIELD48(48L,
            "(四)“三保”保障情况-地方标准“三保”支出(以地方实际结构填列,含国标)-保基本民生-执行数"),
    BASIC_DATA_FIELD49(49L,
            "(四)“三保”保障情况-地方标准“三保”支出(以地方实际结构填列,含国标)-保工资-需求数"),
    BASIC_DATA_FIELD50(50L,
            "(四)“三保”保障情况-地方标准“三保”支出(以地方实际结构填列,含国标)-保工资-预算数"),
    BASIC_DATA_FIELD51(51L,
            "(四)“三保”保障情况-地方标准“三保”支出(以地方实际结构填列,含国标)-保工资-执行数"),
    BASIC_DATA_FIELD52(52L,
            "(四)“三保”保障情况-地方标准“三保”支出(以地方实际结构填列,含国标)-保运转-需求数"),
    BASIC_DATA_FIELD53(53L,
            "(四)“三保”保障情况-地方标准“三保”支出(以地方实际结构填列,含国标)-保运转-预算数"),
    BASIC_DATA_FIELD54(54L,
            "(四)“三保”保障情况-地方标准“三保”支出(以地方实际结构填列,含国标)-保运转-执行数"),
    BASIC_DATA_FIELD55(55L, "(五)暂付款情况-截至上年底暂付性款项余额-金额"),
    BASIC_DATA_FIELD56(56L, "(五)暂付款情况-截至上年底暂付性款项余额-其中:2018年底前形成的暂付款"),
    BASIC_DATA_FIELD57(57L, "(五)暂付款情况-当年新增暂付性款项金额"),
    BASIC_DATA_FIELD58(58L, "(五)暂付款情况-当年消化情况-当年拟消化金额"),
    BASIC_DATA_FIELD59(59L, "(五)暂付款情况-当年消化情况-金额"),
    BASIC_DATA_FIELD60(60L, "(五)暂付款情况-当年消化情况-其中:已消化2018年底存量暂付款"),
    BASIC_DATA_FIELD61(61L, "(五)暂付款情况-累计暂付性款项余额"),
    BASIC_DATA_FIELD62(62L, "(六)存量资金情况-结转结余-总额"),
    BASIC_DATA_FIELD63(63L, "(六)存量资金情况-结转结余-其中:-一般公共预算结转结余"),
    BASIC_DATA_FIELD64(64L, "(六)存量资金情况-结转结余-其中:-政府性基金预算结转结余"),
    BASIC_DATA_FIELD65(65L, "(六)存量资金情况-结转结余-其中:-转移支付结转结余"),
    BASIC_DATA_FIELD66(66L, "(六)存量资金情况-结转结余-其中:-预算稳定调节基金"),
    BASIC_DATA_FIELD67(67L, "(六)存量资金情况-结转结余-其中:-预算周转金"),
    BASIC_DATA_FIELD68(68L, "(六)存量资金情况-结转结余-其中:-财政专户资金"),
    BASIC_DATA_FIELD69(69L, "(六)存量资金情况-已收回存量资金-总额"),
    BASIC_DATA_FIELD70(70L, "(六)存量资金情况-已收回存量资金-其中:-结余、结转两年以上"),
    BASIC_DATA_FIELD71(71L, "(六)存量资金情况-已收回存量资金-其中:-低效资金"),
    BASIC_DATA_FIELD72(72L, "(六)存量资金情况-已收回存量资金再安排金额"),
    BASIC_DATA_FIELD73(73L, "(七)债务管理情况-法定债务率-债务率"),
    BASIC_DATA_FIELD74(74L, "(七)债务管理情况-法定债务率-风险等级"),
    BASIC_DATA_FIELD75(75L, "(七)债务管理情况-YZ率-债务率"),
    BASIC_DATA_FIELD76(76L, "(七)债务管理情况-YZ率-风险等级"),
    BASIC_DATA_FIELD77(77L, "(七)债务管理情况-当年需还本金额-一般债-需求数"),
    BASIC_DATA_FIELD78(78L, "(七)债务管理情况-当年需还本金额-一般债-预算数"),
    BASIC_DATA_FIELD79(79L, "(七)债务管理情况-当年需还本金额-专项债-需求数"),
    BASIC_DATA_FIELD80(80L, "(七)债务管理情况-当年需还本金额-专项债-预算数"),
    BASIC_DATA_FIELD81(81L, "(七)债务管理情况-当年需付息金额-一般债-需求数"),
    BASIC_DATA_FIELD82(82L, "(七)债务管理情况-当年需付息金额-一般债-预算数"),
    BASIC_DATA_FIELD83(83L, "(七)债务管理情况-当年需付息金额-专项债-需求数"),
    BASIC_DATA_FIELD84(84L, "(七)债务管理情况-当年需付息金额-专项债-预算数"),
    BASIC_DATA_FIELD85(85L, "(七)债务管理情况', '当年已付息金额-一般债"),
    BASIC_DATA_FIELD86(86L, "(七)债务管理情况', '当年已付息金额-专项债"),
    BASIC_DATA_FIELD87(87L, "(七)债务管理情况', '当年已付息金额-一般债"),
    BASIC_DATA_FIELD88(88L, "(七)债务管理情况', '当年已付息金额-专项债");
    private final Long code;
    private final String desc;
    public static BasicDataFieldEnum getEnumByCode(long code) {
        for (BasicDataFieldEnum e : BasicDataFieldEnum.values()) {
            if (e.code.equals(code)) {
                return e;
            }
        }
        return null;
    }
}
finance-common/src/main/java/com/finance/common/enums/IndicatorItemEnum.java
New file
@@ -0,0 +1,47 @@
package com.finance.common.enums;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum IndicatorItemEnum {
    INDICATOR_ITEM1(1, "财政经济形势-收入占GDP比重-地方一般公共预算收入占GDP的比重"),
    INDICATOR_ITEM2(2,
            "财政经济形势-收入执行率-地方一般公共预算收入执行进度(地方一般公共预算收入/年初预算或调整预算)"),
    INDICATOR_ITEM3(3,
            "财政经济形势-收入执行率-政府性基金预算收入执行进度(政府性基金预算收入/年初预算或调整预算)"),
    INDICATOR_ITEM4(4, "财政经济形势-收入质量-税收收入占地方一般公共预算收入比重"),
    INDICATOR_ITEM5(5, "财政经济形势-重大财税政策落实情况-减税降费落实情况"),
    INDICATOR_ITEM6(6, "财政经济形势-重大财税政策落实情况-其他重大政策落实情况"),
    INDICATOR_ITEM7(7, "预算管理方面-转移支付-中央转移支付占地方可用财力比重"),
    INDICATOR_ITEM8(8, "预算管理方面-“三保”保障情况-“三保”年初预算保障情况"),
    INDICATOR_ITEM9(9, "预算管理方面-“三保”保障情况-“三保”需求占可用财力的比重"),
    INDICATOR_ITEM10(10, "预算管理方面-“三保”保障情况-“三保”支出保障情况"),
    INDICATOR_ITEM11(11, "预算管理方面-强化预算约束-存量资金盘活"),
    INDICATOR_ITEM12(12, "预算管理方面-强化预算约束-不得无预算、超预算拨款"),
    INDICATOR_ITEM13(13, "预算执行方面-库款管理-库款保障水平"),
    INDICATOR_ITEM14(14, "预算执行方面-预算执行情况-一般公共预算支出执行率"),
    INDICATOR_ITEM15(15, "预算执行方面-预算执行情况-政府性基金预算支出执行率"),
    INDICATOR_ITEM16(16, "预算执行方面-中央直达资金-中央直达资金支付进度"),
    INDICATOR_ITEM17(17, "预算执行方面-中央直达资金-直达资金规范使用"),
    INDICATOR_ITEM18(18, "风险防控方面-暂付款管理-违规新增暂付款"),
    INDICATOR_ITEM19(19, "风险防控方面-暂付款管理-暂付款累计余额"),
    INDICATOR_ITEM20(20, "风险防控方面-暂付款管理-暂付款消化"),
    INDICATOR_ITEM21(21, "风险防控方面-债务管理-法定债务率"),
    INDICATOR_ITEM22(22, "风险防控方面-债务管理-隐性债务率"),
    INDICATOR_ITEM23(23, "风险防控方面-债务管理-日常监督发现问题"),
    INDICATOR_ITEM24(24, "风险防控方面-日常监督发现问题");
    private final Integer code;
    private final String desc;
    public static IndicatorItemEnum getEnumByCode(Integer code) {
        for (IndicatorItemEnum e : IndicatorItemEnum.values()) {
            if (e.code.equals(code)) {
                return e;
            }
        }
        return null;
    }
}
finance-system/src/main/java/com/finance/system/domain/TbBasicDataField.java
@@ -1,13 +1,16 @@
package com.finance.system.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * <p>
@@ -45,6 +48,18 @@
    @TableField("field_value")
    private String fieldValue;
    @ApiModelProperty(value = "第一月数据")
    @TableField("first_month_value")
    private String firstMonthValue;
    @ApiModelProperty(value = "第二月数据")
    @TableField("second_month_value")
    private String secondMonthValue;
    @ApiModelProperty(value = "第三月数据")
    @TableField("third_month_value")
    private String thirdMonthValue;
    @ApiModelProperty(value = "创建人")
    @TableField(value = "create_by", fill = FieldFill.INSERT)
    private String createBy;
finance-system/src/main/java/com/finance/system/dto/BasicDataFieldDTO.java
@@ -17,4 +17,13 @@
    @ApiModelProperty(value = "字段值")
    private String fieldValue;
    @ApiModelProperty(value = "第一月数据")
    private String firstMonthValue;
    @ApiModelProperty(value = "第二月数据")
    private String secondMonthValue;
    @ApiModelProperty(value = "第三月数据")
    private String thirdMonthValue;
}
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) {
finance-system/src/main/java/com/finance/system/listener/HistoryDataListener.java
@@ -8,7 +8,6 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.finance.common.core.domain.entity.SysUser;
import com.finance.common.enums.CalculateTypeEnum;
import com.finance.common.enums.DataScreenConfigEnum;
@@ -22,6 +21,7 @@
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;
@@ -30,6 +30,7 @@
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.ISysUserService;
import com.finance.system.service.TbBasicDataConfigDetailService;
import com.finance.system.service.TbBasicDataConfigService;
@@ -40,15 +41,17 @@
import com.finance.system.service.TbFieldService;
import com.finance.system.service.TbScoreService;
import com.finance.system.vo.DataScreenConfigVO;
import com.google.common.collect.Lists;
import java.time.LocalDate;
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;
@Slf4j
public class HistoryDataListener extends AnalysisEventListener<Map<Integer, String>> {
@@ -67,6 +70,7 @@
    public String quarter;
    public TbDataScreenScoreService tbDataScreenScoreService;
    public TbDataScreenConfigService tbDataScreenConfigService;
    public AsyncService asyncService;
    private List<Map<Integer, String>> cachedDataList = ListUtils.newArrayListWithExpectedSize(
            BATCH_COUNT);
@@ -77,7 +81,7 @@
            TbBasicDataConfigDetailService tbBasicDataConfigDetailService,
            TbScoreService tbScoreService, ISysUserService sysUserService, String quarter,
            TbDataScreenScoreService tbDataScreenScoreService,
            TbDataScreenConfigService tbDataScreenConfigService) {
            TbDataScreenConfigService tbDataScreenConfigService, AsyncService asyncService) {
        this.tbBasicDataService = tbBasicDataService;
        this.tbFieldService = tbFieldService;
        this.tbBasicDataFieldService = tbBasicDataFieldService;
@@ -88,6 +92,7 @@
        this.quarter = quarter;
        this.tbDataScreenConfigService = tbDataScreenConfigService;
        this.tbDataScreenScoreService = tbDataScreenScoreService;
        this.asyncService = asyncService;
    }
    @Override
@@ -128,6 +133,14 @@
        List<TbField> fieldList =
                tbFieldService.lambdaQuery().eq(TbField::getStatus, ShowStatusEnum.SHOW).list();
        Map<Integer, String> headMap = getHeadMap();
        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);
        List<Map<Integer, String>> dataMapList = getMapList();
        if (headMap == null || dataMapList == null) {
            throw new ServiceException("导入失败,请下载最新的导入模板");
@@ -135,31 +148,33 @@
        log.info("{}条数据,开始存储数据库!", dataMapList.size());
        log.info("表头:{}", JSON.toJSONString(headMap));
        log.info("填写的数据:{}", JSON.toJSONString(dataMapList));
        for (Map<Integer, String> dataMap : dataMapList) {
            Optional<SysUser> sysUser = sysUserService.lambdaQuery()
                    .eq(SysUser::getUserType, UserTypeEnum.DEPARTMENT)
                    .eq(SysUser::getAreaName, dataMap.get(0)).oneOpt();
            if (!sysUser.isPresent()) {
                throw new ServiceException("该地区不存在,请修改后重新导入!");
            }
            String areaCode = sysUser.get().getAreaCode();
            int remarkIndex = headMap.size() - 1;
            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));
           /*  boolean flag = new ArrayList<>(dynamicFields).containsAll(collect);
            if (dynamicFields.size() != collect.size() || !flag) {
                throw new ServiceException("导入失败,请下载最新的导入模板");
            }*/
            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("导入失败,请下载最新的导入模板");
            }
        List<SysUser> departmentList = sysUserService.lambdaQuery()
                .eq(SysUser::getUserType, UserTypeEnum.DEPARTMENT).list();
        List<TbBasicData> basicDataList = tbBasicDataService.lambdaQuery().
                eq(TbBasicData::getQuarter, quarter).list();
        for (Map<Integer, String> dataMap : dataMapList) {
            Optional<SysUser> sysUser = departmentList.stream()
                    .filter(dept -> dept.getAreaName().equals(dataMap.get(0))).findFirst();
            if (!sysUser.isPresent()) {
                throw new ServiceException("该地区不存在,请修改后重新导入!");
            }
            String areaCode = sysUser.get().getAreaCode();
            LocalDate now = LocalDate.now();
            TbBasicData tbBasicData;
            Optional<TbBasicData> tbBasicDataOpt = tbBasicDataService.lambdaQuery().
                    eq(TbBasicData::getQuarter, quarter)
                    .eq(TbBasicData::getDeptAreaCode, areaCode).oneOpt();
            Optional<TbBasicData> tbBasicDataOpt = basicDataList.stream()
                    .filter(basicData -> basicData.getDeptAreaCode().equals(areaCode)).findFirst();
            tbBasicData = tbBasicDataOpt.orElseGet(TbBasicData::new);
            tbBasicData.setQuarter(quarter);
            tbBasicData.setTransferPaymentScale(dataMap.get(2));
@@ -168,6 +183,10 @@
            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()));
@@ -187,7 +206,7 @@
            currentGdp.setFieldValue(tbBasicData.getCurrentGdp());
            fields.add(currentGdp);
            //遍历动态字段map
            for (Map.Entry<Integer, String> integerStringEntry : dynamicFieldsMap.entrySet()) {
            /*for (Map.Entry<Integer, String> integerStringEntry : dynamicFieldsMap.entrySet()) {
                Optional<TbField> tbField = tbFieldService.lambdaQuery()
                        .eq(TbField::getFieldName, integerStringEntry.getValue())
                        .eq(TbField::getStatus, ShowStatusEnum.SHOW).oneOpt();
@@ -201,17 +220,101 @@
                    tbBasicDataField.setFieldValue(value);
                    fields.add(tbBasicDataField);
                }
            }*/
            // 遍历动态字段map
            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);
                }
            }
            tbBasicDataFieldService.saveBatch(fields);
            tbBasicData.setStatus(ReportingStatusEnum.FILLED);
            tbBasicDataService.updateById(tbBasicData);
            CompletableFuture.runAsync(() -> {
                calculateScore(tbBasicData, fields);
                calculateScreenScore(tbBasicData, fields);
            });
            // CompletableFuture.runAsync(() -> {
            //     calculateScore(tbBasicData, fields);
            //     calculateScreenScore(tbBasicData, fields);
            // });
            asyncService.calculateScoreWithFixedRules(tbBasicData, fields, fieldList);
        }
        log.info(String.format("%s导入基础数据成功!", JSON.toJSONString(dataMapList)));
    }
    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;
    }
    /**
     * 需要导入的数据
@@ -227,6 +330,16 @@
        return null;
    }
    @NotNull
    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(Entry::getKey, Entry::getValue));
        return dynamicFieldsMap;
    }
    /**
     * 表头
     *
finance-system/src/main/java/com/finance/system/service/AsyncService.java
New file
@@ -0,0 +1,20 @@
package com.finance.system.service;
import com.finance.system.domain.TbBasicData;
import com.finance.system.domain.TbBasicDataField;
import com.finance.system.domain.TbField;
import java.util.List;
/**
 * @author mitao
 * @date 2024/7/5
 */
public interface AsyncService {
    void calculateScore(TbBasicData tbBasicData, List<TbBasicDataField> fields);
    void asyncTask();
    void calculateScoreWithFixedRules(TbBasicData tbBasicData, List<TbBasicDataField> fields,
            List<TbField> fieldList);
}
finance-system/src/main/java/com/finance/system/service/TbBasicDataConfigService.java
@@ -12,6 +12,7 @@
import com.finance.system.vo.BasicDataConfigDetailVO;
import com.finance.system.vo.BasicDataConfigVO;
import com.finance.system.vo.ScoreCalculateVO;
import java.util.List;
/**
 * <p>
@@ -40,4 +41,6 @@
    Page<BasicDataConfigVO> queryPage(Page<BasicDataConfigVO> objectPage,
            BasicDataConfigQuery query);
    List<BasicDataConfigVO> getFixedRulesConfigList();
}
finance-system/src/main/java/com/finance/system/service/impl/AsyncServiceImpl.java
New file
@@ -0,0 +1,394 @@
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;
    }
}
finance-system/src/main/java/com/finance/system/service/impl/TbBasicDataConfigServiceImpl.java
@@ -15,6 +15,7 @@
import com.finance.common.utils.Checker;
import com.finance.common.utils.CollUtils;
import com.finance.common.utils.StringUtils;
import com.finance.system.domain.TbBasicDataCategory;
import com.finance.system.domain.TbBasicDataConfig;
import com.finance.system.domain.TbBasicDataConfigDetail;
import com.finance.system.domain.TbField;
@@ -36,7 +37,9 @@
import com.finance.system.vo.ScoreCalculateVO;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -259,4 +262,30 @@
            BasicDataConfigQuery query) {
        return baseMapper.queryPage(page, query);
    }
    @Override
    public List<BasicDataConfigVO> getFixedRulesConfigList() {
        List<TbBasicDataConfig> configList = this.lambdaQuery()
                .le(TbBasicDataConfig::getId, 24).list();
        Map<Long, TbBasicDataCategory> configCategoryMap = tbBasicDataCategoryService.list()
                .stream()
                .collect(Collectors.toMap(TbBasicDataCategory::getId,
                        Function.identity()));
        List<BasicDataConfigVO> configVOList = BeanUtils.copyList(configList,
                BasicDataConfigVO.class);
        configVOList = configVOList.stream().map(c -> {
            TbBasicDataCategory tbBasicDataCategory2 = configCategoryMap.get(
                    c.getBasicDataCategoryId());
            if (Objects.nonNull(tbBasicDataCategory2)) {
                c.setBasicDataCategory(tbBasicDataCategory2.getBasicDataCategoryName());
                TbBasicDataCategory tbBasicDataCategory1 = configCategoryMap.get(
                        tbBasicDataCategory2.getParentId());
                if (Objects.nonNull(tbBasicDataCategory1)) {
                    c.setBasicDataCategoryOne(tbBasicDataCategory1.getBasicDataCategoryName());
                }
            }
            return c;
        }).collect(Collectors.toList());
        return configVOList;
    }
}
finance-system/src/main/java/com/finance/system/service/impl/TbBasicDataServiceImpl.java
@@ -48,6 +48,7 @@
import com.finance.system.query.CurrentFieldsQuery;
import com.finance.system.query.ScoreCalculateQuery;
import com.finance.system.query.ScoreQuery;
import com.finance.system.service.AsyncService;
import com.finance.system.service.ISysUserService;
import com.finance.system.service.TbBasicDataConfigDetailService;
import com.finance.system.service.TbBasicDataConfigService;
@@ -114,7 +115,7 @@
    private final TbOperLogService tbOperLogService;
    private final TbDataScreenScoreService tbDataScreenScoreService;
    private final TbDataScreenConfigService tbDataScreenConfigService;
    private final AsyncService asyncService;
    public static void setFieldValues(
            List<FieldsTreeVO> fields, Map<Long, TbBasicDataField> fieldMap) {
@@ -474,6 +475,7 @@
        }*/
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String areaCode = loginUser.getUser().getAreaCode();
        String nowQuarter = DateUtils.getNowQuarter();
        EasyExcel.read(
                        file.getInputStream(),
                        new BasicDataListener(
@@ -483,7 +485,9 @@
                                tbBasicDataFieldService,
                                tbBasicDataConfigService,
                                tbBasicDataConfigDetailService,
                                tbScoreService, tbDataScreenScoreService, tbDataScreenConfigService))
                                tbScoreService, tbDataScreenScoreService, nowQuarter,
                                tbDataScreenConfigService,
                                asyncService))
                .sheet()
                .headRowNumber(0)
                .doRead();
@@ -900,8 +904,9 @@
                                tbBasicDataConfigService,
                                tbBasicDataConfigDetailService,
                                tbScoreService, sysUserService, quarter, tbDataScreenScoreService,
                                tbDataScreenConfigService))
                                tbDataScreenConfigService, asyncService))
                .sheet()
                .headRowNumber(0)
                .doRead();
    }
finance-system/src/main/java/com/finance/system/service/impl/TbFieldServiceImpl.java
@@ -322,7 +322,6 @@
                        .collect(Collectors.toList());
        Map<Integer, String[]> selectedMap = new HashMap<>();
        if (CollUtils.isNotEmpty(collect)) {
            selectedMap = new HashMap<>();
            for (TbField tbField : collect) {
                int outerListIndex = getOuterListIndex(head, tbField.getFieldName());
                String[] selectStr = tbField.getTextContent().split(",");
finance-system/src/main/java/com/finance/system/vo/BasicDataConfigVO.java
@@ -4,9 +4,8 @@
import com.finance.common.enums.ShowStatusEnum;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import lombok.Data;
/**
 * @author mitao
@@ -21,10 +20,16 @@
    @ApiModelProperty(value = "基础数据配置id")
    private Long id;
    @ApiModelProperty(value = "类型名称")
    @ApiModelProperty(value = "类型名称(三级指标)")
    private String typeName;
    @ApiModelProperty(value = "基础数据所属分类")
    @ApiModelProperty(value = "基础数据分类id")
    private Long basicDataCategoryId;
    @ApiModelProperty(value = "基础数据所属分类(一级指标)")
    private String basicDataCategoryOne;
    @ApiModelProperty(value = "基础数据所属分类(二级指标)")
    private String basicDataCategory;
    @ApiModelProperty(value = "计算类型(数字计算 文本统计 百分比统计)")
@@ -32,4 +37,7 @@
    @ApiModelProperty(value = "隐藏状态")
    private ShowStatusEnum status;
    @ApiModelProperty(value = "最大分值")
    private Double maxScore;
}