package com.hz.pm.api.scheduler.task;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.hz.pm.api.common.helper.RegionCacheHelper;
import com.hz.pm.api.common.model.constant.BizConst;
import com.hz.pm.api.common.model.constant.RegionConst;
import com.hz.pm.api.common.util.BizUtils;
import com.hz.pm.api.dashboard.constant.DashboardConstant;
import com.hz.pm.api.dashboard.model.entity.CockpitStats;
import com.hz.pm.api.dashboard.model.po.SecrecyPasswordGradePO;
import com.hz.pm.api.dashboard.service.ICockpitStatsService;
import com.hz.pm.api.expert.entity.ExpertIntentionWorkRegion;
import com.hz.pm.api.expert.entity.ExpertUserFullInfo;
import com.hz.pm.api.expert.service.IExpertIntentionWorkRegionService;
import com.hz.pm.api.expert.service.IExpertUserFullInfoService;
import com.hz.pm.api.gov.enumeration.GovProjectStatusEnum;
import com.hz.pm.api.gov.model.entity.*;
import com.hz.pm.api.gov.service.*;
import com.hz.pm.api.meta.model.entity.ExpertTag;
import com.hz.pm.api.meta.service.IExpertTagService;
import com.hz.pm.api.performance.model.entity.PerformanceAppraisalProject;
import com.hz.pm.api.performance.service.IPerformanceAppraisalProjectService;
import com.hz.pm.api.projectlib.model.entity.Project;
import com.hz.pm.api.projectlib.model.entity.ProjectInst;
import com.hz.pm.api.projectlib.model.enumeration.InstTypeEnum;
import com.hz.pm.api.projectlib.model.enumeration.ProjectStatusEnum;
import com.hz.pm.api.projectlib.service.IProjectInstService;
import com.hz.pm.api.projectlib.service.IProjectService;
import com.hz.pm.api.sys.model.dto.RegionDTO;
import com.hz.pm.api.sys.model.entity.WflowEarlyWarningRecords;
import com.hz.pm.api.sys.service.IEarlyWarningRecordsService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.HistoryService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author ZPF
 * @Class CockpitStatsStatisticsTask
 * 驾驶舱 统计 每日任务
 * @since 2023/08/31 18:16
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class CockpitStatsStatisticsTask {

    @Value("${hostname}")
    public String HOST;

    @Value("${spring.profiles.active}")
    public String active;

    private final ICockpitStatsService cockpitStatsService;
    private final RegionCacheHelper regionCacheHelper;
    private final IProjectService projectService;
    private final IProjectInstService projectInstService;
    private final IExpertUserFullInfoService expertUserFullInfoService;
    private final IPerformanceAppraisalProjectService performanceAppraisalProjectService;
    private final IGovBizProjectBaseinfoService baseinfoService;
    private final IGovBizProjectApplyService applyService;
    private final HistoryService historyService;
    private final IGovBizProjectApproveService approveService;
    private final IGovBizProjectProcureService procureService;
    private final IGovBizProjectCimplementService cimplementService;
    private final IEarlyWarningRecordsService earlyWarningRecordsService;
    private final IExpertIntentionWorkRegionService expertIntentionWorkRegionService;
    private final IExpertTagService expertTagService;

    private List<Integer> years = Lists.newArrayList(2021, 2022, 2023, 2024, 2025);


    /**
     * 定义统计 驾驶舱数据 每天3点开始执行一次
     */
    @Scheduled(cron = "0 0 3 * * ?")
    public void doTask() throws UnknownHostException {
        if (!HOST.equals(InetAddress.getLocalHost().getHostName())) {
            log.info("定时器没开启或者host不对! {}:{}",
                    HOST, InetAddress.getLocalHost().getHostName());
            return;
        }
        if (BizConst.PRE.equals(active)) {
            log.info("预发环境不用同步!");
            return;
        }

        log.info("驾驶舱数据统计任务开始=====");

        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        List<CockpitStats> res = Lists.newArrayList();
        //1.根据2个维度来统计 区域和分年
        //1.总的
        res.add(statisticsData(DashboardConstant.CockpitStats.TOTAL,
                DashboardConstant.CockpitStats.TOTAL, DashboardConstant.CockpitStats.NONE_YEAR));
        for (Integer year : years) {
            res.add(statisticsData(DashboardConstant.CockpitStats.TOTAL,
                    DashboardConstant.CockpitStats.TOTAL, year));
        }

        List<RegionDTO> regions = regionCacheHelper.listChildren(RegionConst.RC_HZ, RegionConst.RL_CITY);
        regions = regions.stream().filter(r -> r.getRegionLevel() != RegionConst.RL_CITY).collect(Collectors.toList());
        for (RegionDTO regionDto : regions) {
            res.add(statisticsData(regionDto.getRegionCode(), regionDto.getRegionName(),
                    DashboardConstant.CockpitStats.NONE_YEAR));
            for (Integer year : years) {
                res.add(statisticsData(regionDto.getRegionCode(), regionDto.getRegionName(), year));
            }
        }

        //如果结果不为空 就删除之前的 插入最新的数据
        if (CollUtil.isNotEmpty(res)) {
            //计算增长率
            computeRates(res);
            List<CockpitStats> list = cockpitStatsService.list();
            List<Long> ids = list.stream().map(CockpitStats::getId).collect(Collectors.toList());
            cockpitStatsService.removeByIds(ids);
            cockpitStatsService.saveBatch(res);
        }

        stopWatch.stop();
        log.info("驾驶舱数据统计任务结束====={}s", stopWatch.getTotalTimeSeconds());
    }

    private void computeRates(List<CockpitStats> res) {
        Map<String, CockpitStats> map = res.stream().collect(Collectors.toMap(r -> r.getRegionCode() + r.getYear(), r -> r));
        for (CockpitStats cockpitStats : res) {
            if (Objects.isNull(cockpitStats.getYear())) {
                continue;
            }
            //算增长率
            //去年的数据 用于算 增长比例
            if (cockpitStats.getYear().equals(DashboardConstant.CockpitStats.NONE_YEAR)) {
                int thisYear = LocalDateTime.now().getYear();
                CockpitStats thisYearData = map.get(cockpitStats.getRegionCode() + thisYear);
                CockpitStats lastYearData = map.get(cockpitStats.getRegionCode() + (thisYear - 1));
                buildMonitorRise(cockpitStats, thisYearData, lastYearData);
            } else {
                CockpitStats lastYearData = map.get(cockpitStats.getRegionCode() + (cockpitStats.getYear() - 1));
                buildMonitorRise(cockpitStats, cockpitStats, lastYearData);
            }
        }

    }

    /**
     * 统计的具体逻辑
     *
     * @param regionCode
     * @param regionName
     * @param year
     * @return
     */
    private CockpitStats statisticsData(String regionCode, String regionName, Integer year) {
        CockpitStats cockpitStats = new CockpitStats();
        cockpitStats.setRegionCode(regionCode);
        cockpitStats.setRegionName(regionName);
        cockpitStats.setYear(year);

        //申报项目
        boolean condition = Objects.nonNull(year) && !year.equals(DashboardConstant.CockpitStats.NONE_YEAR);
        boolean condition1 = Objects.isNull(year) || year.equals(DashboardConstant.CockpitStats.NONE_YEAR);
        List<Project> projects = projectService.list(Wrappers.lambdaQuery(Project.class)
                .eq(Project::getNewest, Boolean.TRUE)
                .eq(StringUtils.isNotBlank(regionCode) && !DashboardConstant.CockpitStats.TOTAL.equals(regionCode),
                        Project::getAreaCode, regionCode)
                .eq(condition, Project::getProjectYear, year)
                .in(condition1, Project::getProjectYear, years));

        //项目归集
        List<GovBizProjectApply> applieYears = applyService.list(Wrappers.lambdaQuery(GovBizProjectApply.class)
                .eq(condition,
                        GovBizProjectApply::getBaseProjSetYear, year)
                .in(condition1,
                        GovBizProjectApply::getBaseProjSetYear, years));
        List<String> yearProjIds = applieYears.stream().map(GovBizProjectApply::getBaseProjId)
                .collect(Collectors.toList());

        List<GovBizProjectBaseinfo> baseInfos = Lists.newArrayList();
        if (CollUtil.isNotEmpty(yearProjIds)) {
            baseInfos = baseinfoService.list(Wrappers.lambdaQuery(GovBizProjectBaseinfo.class)
                    .eq(GovBizProjectBaseinfo::getDeleted, Boolean.FALSE)
                    .in(GovBizProjectBaseinfo::getBaseProjId, yearProjIds));
        }

        List<GovBizProjectApprove> approves = Lists.newArrayList();
        List<GovBizProjectApply> applies = Lists.newArrayList();
        List<GovBizProjectProcure> procures = Lists.newArrayList();
        List<GovBizProjectCimplement> cimplements = Lists.newArrayList();
        if (CollUtil.isNotEmpty(baseInfos)) {
            List<String> baseProjIds = baseInfos.stream().map(GovBizProjectBaseinfo::getBaseProjId).collect(Collectors.toList());
            approves = approveService.list(Wrappers.lambdaQuery(GovBizProjectApprove.class)
                    .in(GovBizProjectApprove::getBaseProjId, baseProjIds));

            applies = applyService.list(Wrappers.lambdaQuery(GovBizProjectApply.class)
                    .in(GovBizProjectApply::getBaseProjId, baseProjIds));

            procures = procureService.list(Wrappers.lambdaQuery(GovBizProjectProcure.class)
                    .in(GovBizProjectProcure::getBaseProjId, baseProjIds));

            cimplements = cimplementService.list(Wrappers.lambdaQuery(GovBizProjectCimplement.class)
                    .in(GovBizProjectCimplement::getBaseProjId, baseProjIds));
        }

        //1.项目监测
        //1.1 超期在建项目
        Integer overdueConstructionProjectsNum = (int) projects.stream().filter(p -> {
            if (Objects.nonNull(p.getPlanAcceptanceTime()) &&
                    p.getPlanAcceptanceTime().compareTo(LocalDateTime.now()) < 0 &&
                    Objects.nonNull(p.getStatus()) && p.getStatus().compareTo(ProjectStatusEnum.ACCEPTED.getCode()) < 0) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();
        cockpitStats.setMonitorOverdueConstructionProjectsNum(overdueConstructionProjectsNum);
        //1.2 环节滞后项目
        cockpitStats.setMonitorLaggingProjectsNum(computeLagging(projects));

        //1.3预审驳回项目
        Integer preFailed = (int) projects.stream().filter(p -> {
            if (Objects.nonNull(p.getStatus()) &&
                    p.getStatus().equals(ProjectStatusEnum.PREQUALIFICATION_FAILED.getCode())) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();
        cockpitStats.setMonitorRejectedPreReviewProjectsNum(preFailed);

        //1.4 建设方案评审失败
        Integer constructionFailed = (int) projects.stream().filter(p -> {
            if (Objects.nonNull(p.getStatus()) && p.getStatus().equals(ProjectStatusEnum.SCHEME_REVIEW_FAILED.getCode())) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();
        cockpitStats.setMonitorRejectedApproveProjectsNum(constructionFailed);
        //1.5 验收不达标
        cockpitStats.setMonitorAcceptConditionsNotStandardsNum(0);

        //1.6 总申报金额
        double totalDeclaredAmount = projects.stream().mapToDouble(p -> Objects.nonNull(p.getDeclareAmount()) ? p.getDeclareAmount().doubleValue() : 0.0).sum();
        cockpitStats.setMonitorDeclaredAmount(BigDecimal.valueOf(totalDeclaredAmount));
        //1.7 总安全投入
        double totalSafetyAmount = projects.stream().mapToDouble(p -> {
            if (Objects.nonNull(p.getSafetyInputDescribe())) {
                final Double[] total = {0.0};
                try {
                    JSONArray array = JSON.parseArray(p.getSafetyInputDescribe());
                    array.forEach(j -> {
                        JSONObject json = JSON.parseObject(JSON.toJSONString(j));
                        Double safetyInputAmount = json.getDouble(DashboardConstant.Protrait.FEILD_SAFETYMONEY);
                        total[0] += safetyInputAmount;
                    });
                } catch (Exception e) {

                }
                return total[0];
            }
            return 0.0;
        }).sum();
        cockpitStats.setMonitorSafetyInputAmount(BigDecimal.valueOf(totalSafetyAmount));

        //1.8等保密评
        SecrecyPasswordGradePO secrecyPasswordGradePo = cockpitStatsService.getSecrecyPasswordGrade(regionCode, year);

        Integer guijiSecerecyGrade1 = 0;
        Integer guijiSecerecyGrade2 = 0;
        Integer guijiSecerecyGrade3 = 0;
        Integer guijiSecerecyGrade4 = 0;
        Integer guijiSecerecyGrade5 = 0;
        //项目归集 评审信息
        for (GovBizProjectApprove approve : approves) {
            String equalProtectionLevel = approve.getEqualProtectionLevel();
            if (StringUtils.isNotBlank(equalProtectionLevel)) {
                switch (equalProtectionLevel) {
                    case "01":
                        guijiSecerecyGrade1++;
                        break;
                    case "02":
                        guijiSecerecyGrade2++;
                        break;
                    case "03":
                        guijiSecerecyGrade3++;
                        break;
                    case "04":
                        guijiSecerecyGrade4++;
                        break;
                    case "05":
                        guijiSecerecyGrade5++;
                        break;
                    default:
                        break;
                }
            }
        }

        Integer passwordGradeNumGov = 0;
        for (GovBizProjectCimplement cimplement : cimplements) {
            if (StringUtils.isNotBlank(cimplement.getBaseInforLevelFile())) {
                passwordGradeNumGov++;
            }
        }

        if (Objects.nonNull(secrecyPasswordGradePo)) {
            cockpitStats.setMonitorSecrecyGrade1Num(secrecyPasswordGradePo.getMonitorSecrecyGrade1Num() + guijiSecerecyGrade1);
            cockpitStats.setMonitorSecrecyGrade2Num(secrecyPasswordGradePo.getMonitorSecrecyGrade2Num() + guijiSecerecyGrade2);
            cockpitStats.setMonitorSecrecyGrade3Num(secrecyPasswordGradePo.getMonitorSecrecyGrade3Num() + guijiSecerecyGrade3);
            cockpitStats.setMonitorSecrecyGrade4Num(secrecyPasswordGradePo.getMonitorSecrecyGrade4Num() + guijiSecerecyGrade4);
            cockpitStats.setMonitorSecrecyGrade5Num(secrecyPasswordGradePo.getMonitorSecrecyGrade5Num() + guijiSecerecyGrade5);
            cockpitStats.setMonitorPasswordGrade1Num(secrecyPasswordGradePo.getMonitorPasswordGrade1Num() + passwordGradeNumGov);
            cockpitStats.setMonitorPasswordGrade2Num(secrecyPasswordGradePo.getMonitorPasswordGrade2Num());
            cockpitStats.setMonitorPasswordGrade3Num(secrecyPasswordGradePo.getMonitorPasswordGrade3Num());
            cockpitStats.setMonitorPasswordGrade4Num(secrecyPasswordGradePo.getMonitorPasswordGrade4Num());
            cockpitStats.setMonitorPasswordGrade5Num(secrecyPasswordGradePo.getMonitorPasswordGrade5Num());
        } else {
            cockpitStats.setMonitorSecrecyGrade1Num(guijiSecerecyGrade1);
            cockpitStats.setMonitorSecrecyGrade2Num(guijiSecerecyGrade2);
            cockpitStats.setMonitorSecrecyGrade3Num(guijiSecerecyGrade3);
            cockpitStats.setMonitorSecrecyGrade4Num(guijiSecerecyGrade4);
            cockpitStats.setMonitorSecrecyGrade5Num(guijiSecerecyGrade5);
            cockpitStats.setMonitorPasswordGrade1Num(passwordGradeNumGov);
        }

        //2.专家统计
        List<String> lsRegionCodes = RegionConst.LS_ARR;
        List<ExpertIntentionWorkRegion> intentions = expertIntentionWorkRegionService.list(Wrappers.lambdaQuery(ExpertIntentionWorkRegion.class)
                .eq(StringUtils.isNotBlank(regionCode) && !DashboardConstant.CockpitStats.TOTAL.equals(regionCode),
                        ExpertIntentionWorkRegion::getRegionCode, regionCode)
                .in(StringUtils.isBlank(regionCode) || DashboardConstant.CockpitStats.TOTAL.equals(regionCode),
                        ExpertIntentionWorkRegion::getRegionCode, lsRegionCodes));

        List<ExpertUserFullInfo> experts = Lists.newArrayList();
        if (CollUtil.isNotEmpty(intentions)) {
            List<Long> userIds = intentions.stream().map(ExpertIntentionWorkRegion::getUserId)
                    .collect(Collectors.toList());
            experts = expertUserFullInfoService.list(Wrappers.lambdaQuery(ExpertUserFullInfo.class)
                    .in(ExpertUserFullInfo::getUserId, userIds));
        }

        List<ExpertTag> goodAt = expertTagService.list(Wrappers.lambdaQuery(ExpertTag.class));
        Map<Long, List<ExpertTag>> tagMap = goodAt.stream()
                .collect(Collectors.groupingBy(ExpertTag::getUserId));

        String networkCode = DashboardConstant.Expert.NETWORK_CODE;
        String xinchuangCode = DashboardConstant.Expert.XINCHUANG_CODE;
        String fanganCode = DashboardConstant.Expert.FANGAN_CODE;
        String jishuCode = DashboardConstant.Expert.JISHU_CODE;
        String dangzhengCode = DashboardConstant.Expert.DANGZHENG_CODE;
        String ruanyingCode = DashboardConstant.Expert.RUANYING_CODE;
        String caiwuCode = DashboardConstant.Expert.CAIWU_CODE;
        List<String> specialTags = Lists.newArrayList(networkCode, xinchuangCode, fanganCode, jishuCode,
                dangzhengCode, ruanyingCode, caiwuCode);

        cockpitStats.setExpertTotalNum(experts.size());
        Integer financialNum = 0;
        Integer networkSecurityNum = 0;
        Integer xinchuangNum = 0;
        Integer planRationalityNum = 0;
        Integer promotionInfoTechnologyNum = 0;
        Integer partyGovInfoNum = 0;
        Integer softHardPricingNum = 0;
        Integer technicalFeasibilityAssessmentNum = 0;
        Integer specialExpertNum = 0;
        for (ExpertUserFullInfo e : experts) {
            if (tagMap.containsKey(e.getUserId())) {
                List<ExpertTag> expertTags = tagMap.get(e.getUserId());
                boolean isContain = Boolean.FALSE;
                for (ExpertTag expertTag : expertTags) {
                    if (expertTag.getTagCode().equals(networkCode)) {
                        networkSecurityNum++;
                    }
                    if (expertTag.getTagCode().equals(caiwuCode)) {
                        financialNum++;
                    }
                    if (expertTag.getTagCode().equals(xinchuangCode)) {
                        xinchuangNum++;
                    }
                    if (expertTag.getTagCode().equals(fanganCode)) {
                        planRationalityNum++;
                    }
                    if (expertTag.getTagCode().equals(jishuCode)) {
                        technicalFeasibilityAssessmentNum++;
                    }
                    if (expertTag.getTagCode().equals(dangzhengCode)) {
                        partyGovInfoNum++;
                    }
                    if (expertTag.getTagCode().equals(ruanyingCode)) {
                        softHardPricingNum++;
                    }
                    if (specialTags.contains(expertTag.getTagCode())) {
                        isContain = Boolean.TRUE;
                    }
                }
                if (isContain) {
                    specialExpertNum++;
                }
            }
        }
        //财务专家
        cockpitStats.setExpertFinancialNum(financialNum);
        //网络安全
        cockpitStats.setExpertNetworkSecurityNum(networkSecurityNum);
        cockpitStats.setExpertXinchuangNum(xinchuangNum);
        cockpitStats.setExpertPlanRationalityNum(planRationalityNum);
        cockpitStats.setExpertPromotionInfoTechnologyNum(promotionInfoTechnologyNum);
        cockpitStats.setExpertPartyGovInfoNum(partyGovInfoNum);
        cockpitStats.setExpertSoftHardPricingNum(softHardPricingNum);
        cockpitStats.setExpertTechnicalFeasibilityAssessmentNum(technicalFeasibilityAssessmentNum);
        cockpitStats.setSpecialExpertNum(specialExpertNum);

        //3.顶部数据
        //3.1 计划项目数(申报项目:完成年度计划的项目总数
        // 项目归集:评审中、待立项、已立项、已采购、已初验、已终验项目总和)
        Integer planProjectNum = (int) projects.stream().filter(p -> {
            if (Objects.nonNull(p.getStatus()) &&
                    p.getStatus().compareTo(ProjectStatusEnum.PENDING_PREQUALIFICATION.getCode()) >= 0) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();
        Integer planProjectNumGov = (int) baseInfos.stream().filter(p -> {
            if (Objects.nonNull(p.getBaseProjSetProg()) &&
                    //排除 已驳回 已终止
                    (!Lists.newArrayList(GovProjectStatusEnum.REJECTED.getCode(),
                            GovProjectStatusEnum.TERMINATED.getCode()).contains(p.getBaseProjSetProg()))) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();
        cockpitStats.setTopPlanProjectsNum(planProjectNum + planProjectNumGov);

        //3.2 批复项目数(申报项目:完成立项批复流程项目总数 项目归集:已立项、已采购、已初验、已终验项目总和)
        Integer approvalNumDeclared = (int) projects.stream().filter(p -> {
            if (Objects.nonNull(p.getApprovalAmount())) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();
        Integer approvalNumGov = (int) baseInfos.stream().filter(p -> {
            if (Objects.nonNull(p.getBaseProjSetProg()) && Lists.newArrayList(GovProjectStatusEnum.APPROVED.getCode(),
                    GovProjectStatusEnum.PURCHASED.getCode(), GovProjectStatusEnum.HAS_PRE_INS.getCode(),
                    GovProjectStatusEnum.HAS_FINAL_INS.getCode()).contains(p.getBaseProjSetProg())) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();

        BigDecimal approvalAmount = projects.stream().filter(p -> {
            if (Objects.nonNull(p.getApprovalAmount())) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).map(Project::getApprovalAmount).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);

        BigDecimal approvalAmountGov = approves.stream()
                .map(GovBizProjectApprove::getBaseInitialReviewTotalMoney)
                .filter(Objects::nonNull)
                .reduce(BigDecimal::add)
                .orElse(BigDecimal.ZERO);

        cockpitStats.setTopApprovalProjectsNum(approvalNumDeclared + approvalNumGov);
        cockpitStats.setTopApprovalProjectsAmount(approvalAmount.add(approvalAmountGov));
        //3.3 平均建设周期
        OptionalDouble od = Stream.concat(projects.stream().map(Project::getBuildCycle),
                applies.stream().map(GovBizProjectApply::getBaseProjDuration)).mapToInt(c -> {
            try {
                return Integer.parseInt(c);
            } catch (Exception e) {
                return 0;
            }
        }).average();
        double average = od.isPresent() ? od.getAsDouble() : 0.0;
        cockpitStats.setTopAverageConstructionPeriod((int) average);
        //3.4 在建项目数 采购备案后的项目
        Integer constructionNum = (int) projects.stream().filter(p -> {
            if (Objects.nonNull(p.getStatus()) &&
                    p.getStatus().compareTo(ProjectStatusEnum.TO_BE_PURCHASED.getCode()) >= 0
                    && p.getStatus().compareTo(ProjectStatusEnum.ACCEPTED.getCode()) < 0) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();
        Integer constructionNumGov = (int) baseInfos.stream().filter(b -> {
            if (Objects.nonNull(b.getBaseProjSetProg()) &&
                    Lists.newArrayList(GovProjectStatusEnum.PURCHASED.getCode(), GovProjectStatusEnum.HAS_PRE_INS.getCode()).contains(b.getBaseProjSetProg())) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();
        cockpitStats.setTopOngoingProjectsNum(constructionNum + constructionNumGov);

        //4.地图 只要放总数 取的时候 会有逻辑(也要取项目归集)
        cockpitStats.setProjectsTotal(projects.size() + baseInfos.size());

        //5.下面项目状态数
        //5.1 计划(申报项目:项目预审完成到年度计划未完成 项目归集:评审中)
        Integer inPlanNum = (int) projects.stream().filter(p -> {
            if (Objects.nonNull(p.getStatus()) &&
                    p.getStatus().compareTo(ProjectStatusEnum.PREQUALIFICATION_FAILED.getCode()) > 0 &&
                    p.getStatus().compareTo(ProjectStatusEnum.IN_THE_ANNUAL_PLAN.getCode()) <= 0) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();
        Integer inPlanNumGov = (int) baseInfos.stream().filter(p -> {
            if (Objects.nonNull(p.getBaseProjSetProg()) &&
                    p.getBaseProjSetProg().equals(GovProjectStatusEnum.APPROVAL.getCode())) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();
        cockpitStats.setProjectsTotalPlan(inPlanNum + inPlanNumGov);

        //5.2 处于申报(申报项目:年度计划完成到建设方案审批第一个节点审批未通过前 项目归集:待立项)
        Integer inApplyNum = (int) projects.stream().filter(p -> {
            if (Objects.nonNull(p.getStatus()) &&
                    (ProjectStatusEnum.PLAN_TO_BE_DECLARED.getCode().equals(p.getStatus()) ||
                            (ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode().equals(p.getStatus()) &&
                                    searchSchemaReviewFlow(p.getProjectCode())))) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();
        Integer inApplyNumGov = (int) baseInfos.stream().filter(p -> {
            if (Objects.nonNull(p.getBaseProjSetProg()) &&
                    p.getBaseProjSetProg().equals(GovProjectStatusEnum.PENDING.getCode())) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();
        cockpitStats.setProjectsTotalApply(inApplyNum + inApplyNumGov);

        //5.3 处于审批 (申报项目:建设方案审批第一个节点审批通过到立项批复未完成 项目归集:已立项)
        Integer inApproveNum = (int) projects.stream().filter(p -> {
            if (Objects.nonNull(p.getStatus()) &&
                    (ProjectStatusEnum.TO_BE_APPROVED.getCode().equals(p.getStatus()) ||
                            p.getStatus().compareTo(ProjectStatusEnum.APPROVED_AFTER_CHOICE.getCode()) > 0 ||
                            (ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode().equals(p.getStatus()) &&
                                    searchSchemaReviewedFlow(p.getProjectCode())))) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();
        Integer inApproveNumGov = (int) baseInfos.stream().filter(p -> {
            if (Objects.nonNull(p.getBaseProjSetProg()) &&
                    p.getBaseProjSetProg().equals(GovProjectStatusEnum.APPROVED.getCode())) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();
        cockpitStats.setProjectsTotalApprove(inApproveNum + inApproveNumGov);

        //5.4 建设 (申报项目:立项批复完成到项目初验未完成 项目归集:已采购)
        Integer inConstructionNum = (int) projects.stream().filter(p -> {
            if (Objects.nonNull(p.getStatus()) &&
                    (p.getStatus().compareTo(ProjectStatusEnum.APPROVED_AFTER_CHOICE.getCode()) > 0 &&
                            p.getStatus().compareTo(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode()) < 0) ||
                    //如果在建设中 那么初验材料为空代表 初验未完成
                    (p.getStatus().equals(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode()) &&
                            StringUtils.isBlank(p.getPreliminaryInspectionMaterials()))) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();
        Integer inConstructionNumGov = (int) baseInfos.stream().filter(p -> {
            if (Objects.nonNull(p.getBaseProjSetProg()) &&
                    p.getBaseProjSetProg().equals(GovProjectStatusEnum.PURCHASED.getCode())) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();
        cockpitStats.setProjectsTotalConstruction(inConstructionNum + inConstructionNumGov);

        //5.5 验收 (申报项目:项目初验完成到项目终验未完成 项目归集:已初验)
        List<Project> inAcceptProjects = projects.stream().filter(p -> {
            if (Objects.nonNull(p.getStatus()) &&
                    p.getStatus().compareTo(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode()) > 0 &&
                    p.getStatus().compareTo(ProjectStatusEnum.ACCEPTED.getCode()) < 0 ||
                    //如果在建设中 那么初验材料不为空代表 初验完成
                    (p.getStatus().equals(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode()) &&
                            StringUtils.isNotBlank(p.getPreliminaryInspectionMaterials()))) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).collect(Collectors.toList());
        List<GovBizProjectBaseinfo> inAcceptProjectsGov = baseInfos.stream().filter(b -> {
            if (Objects.nonNull(b.getBaseProjSetProg()) &&
                    b.getBaseProjSetProg().equals(GovProjectStatusEnum.HAS_PRE_INS.getCode())) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).collect(Collectors.toList());
        cockpitStats.setProjectsTotalAccept(inAcceptProjects.size() + inAcceptProjectsGov.size());

        //5.6 运维(申报项目:项目验收完成后且项目未注销 项目归集:已终验)
        List<Project> inOperationProjects = projects.stream().filter(p -> {
            if (Objects.nonNull(p.getStatus()) &&
                    p.getStatus().equals(ProjectStatusEnum.ACCEPTED.getCode())) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).collect(Collectors.toList());
        int inOperationProjectsGov = (int) baseInfos.stream().filter(b -> {
            if (Objects.nonNull(b.getBaseProjSetProg()) &&
                    b.getBaseProjSetProg().equals(GovProjectStatusEnum.HAS_FINAL_INS.getCode())) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).count();
        cockpitStats.setProjectsTotalOperation(inOperationProjects.size() + inOperationProjectsGov);

        //5.7 绩效(申报项目:项目验收完成后且未完成绩效自评 项目归集:无)
        List<String> inAcceptCodes = inOperationProjects.stream().map(Project::getProjectCode).collect(Collectors.toList());
        List<PerformanceAppraisalProject> performances = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
                .in(CollUtil.isNotEmpty(inAcceptCodes), PerformanceAppraisalProject::getProjectCode, inAcceptCodes)
                .in(CollUtil.isEmpty(inAcceptCodes), PerformanceAppraisalProject::getProjectCode, Lists.newArrayList("NONE"))
                .eq(PerformanceAppraisalProject::getIsReAppraisal, Boolean.TRUE)
                .isNull(PerformanceAppraisalProject::getReAppraisalTotalScore)
        );
        cockpitStats.setProjectsTotalPerformance(performances.size());
        cockpitStats.setProjectsTotalLogOff(0);

        //6.项目效益
        cockpitStats.setExcellentBestAppNum(0);
        cockpitStats.setExcellentMajorAppNum(0);
        cockpitStats.setExcellentCrossLevelSharingNum(0);
        cockpitStats.setExcellentMajorAppNum(0);

        //7.2驳回节约资金
        List<Project> rejectPreProjects = projects.stream().filter(p -> {
            if (Objects.nonNull(p.getStatus()) &&
                    p.getStatus().equals(ProjectStatusEnum.PREQUALIFICATION_FAILED.getCode())) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).collect(Collectors.toList());
        BigDecimal rejectPreSum = rejectPreProjects.stream().map(p -> {
            if (Objects.nonNull(p.getDeclareAmount())) {
                return p.getDeclareAmount();
            }
            return BigDecimal.ZERO;
        }).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
        cockpitStats.setRejectSavingsFunds(rejectPreSum);

        //7.3 柱状图
        //7.3.1 申报状态的3个资金
//        projects.stream()
        //首先完成年度计划 并且未注销的项目
        List<Project> normalProjects = projects.stream().filter(p -> {
            if (Objects.nonNull(p.getStatus()) &&
                    p.getStatus().compareTo(ProjectStatusEnum.BE_SUSPENDED.getCode()) > 0) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).collect(Collectors.toList());

        //申报的申报金额(申报项目:初步方案申报金额 项目归集:项目总投资)
        final BigDecimal[] declaredAmountApprove = {BigDecimal.ZERO};
        normalProjects.stream().map(p -> ObjectUtil.defaultIfNull(p.getDeclareAmount(), BigDecimal.ZERO))
                .reduce(BigDecimal::add).ifPresent(b -> declaredAmountApprove[0] = b);
        final BigDecimal[] declaredAmountApproveGov = {BigDecimal.ZERO};
        applies.stream().map(g -> ObjectUtil.defaultIfNull(g.getBaseProjTotalAmount(), BigDecimal.ZERO))
                .reduce(BigDecimal::add).ifPresent(b -> declaredAmountApproveGov[0] = b);
        BigDecimal declaredAmountApproveTotal = declaredAmountApprove[0].add(declaredAmountApproveGov[0]);
        cockpitStats.setDeclaredAmountApprove(declaredAmountApproveTotal);

        //申报的批复金额(申报项目:建设方案申报金额 项目归集:建议总投资)
        final BigDecimal[] approvalAmountApprove = {BigDecimal.ZERO};
        normalProjects.stream().map(p -> ObjectUtil.defaultIfNull(p.getApprovalAmount(), BigDecimal.ZERO))
                .reduce(BigDecimal::add).ifPresent(b -> approvalAmountApprove[0] = b);
        final BigDecimal[] approvalAmountApproveGov = {BigDecimal.ZERO};
        approves.stream().map(p -> ObjectUtil.defaultIfNull(p.getBaseExpertTotalMoney(), BigDecimal.ZERO))
                .reduce(BigDecimal::add).ifPresent(b -> approvalAmountApproveGov[0] = b);
        BigDecimal approvalAmountApproveTotal = approvalAmountApprove[0].add(approvalAmountApproveGov[0]);
        cockpitStats.setApprovalAmountApprove(approvalAmountApproveTotal);
        //申报的差额
        BigDecimal subtractApprove = declaredAmountApproveTotal.subtract(approvalAmountApproveTotal);
        cockpitStats.setDifferenceApprove(subtractApprove);

        //批复的申报金额(申报项目:建设方案申报金额 项目归集:建议总投资)
        cockpitStats.setDeclaredAmountApproval(approvalAmountApproveTotal);

        //批复的批复金额(申报项目:归集信息建议批复总投资 项目归集:建议批复总投资)
        final BigDecimal[] approvalAmountApproval = {BigDecimal.ZERO};
        normalProjects.stream().map(p -> ObjectUtil.defaultIfNull(p.getProposeTotalInvest(), BigDecimal.ZERO))
                .reduce(BigDecimal::add).ifPresent(b -> approvalAmountApproval[0] = b);
        final BigDecimal[] approvalAmountApprovalGov = {BigDecimal.ZERO};
        approves.stream().map(p -> ObjectUtil.defaultIfNull(p.getBaseInitialReviewTotalMoney(), BigDecimal.ZERO))
                .reduce(BigDecimal::add).ifPresent(b -> approvalAmountApprovalGov[0] = b);
        BigDecimal approvalAmountApprovalTotal = approvalAmountApproval[0].add(approvalAmountApprovalGov[0]);
        cockpitStats.setApprovalAmountApproval(approvalAmountApprovalTotal);

        //批复的差额
        BigDecimal subtractApproval = approvalAmountApproveTotal.subtract(approvalAmountApprovalTotal);
        cockpitStats.setDifferenceApproval(subtractApproval);

        //合同的申报金额(申报项目:归集信息建议批复总投资 项目归集:建议批复总投资)
        cockpitStats.setDeclaredAmountContract(approvalAmountApprovalTotal);

        //合同的批复金额(申报项目:成交金额 项目归集:成交金额)
        final BigDecimal[] approvalAmountContract = {BigDecimal.ZERO};
        normalProjects.stream().map(p -> Objects.nonNull(p.getTransactionAmount()) ? p.getTransactionAmount() : BigDecimal.ZERO)
                .reduce(BigDecimal::add).ifPresent(b -> approvalAmountContract[0] = b);
        final BigDecimal[] approvalAmountContractGov = {BigDecimal.ZERO};
        procures.stream().map(p -> Objects.nonNull(p.getBaseProjPurchaseAmount()) ?
                        p.getBaseProjPurchaseAmount() : BigDecimal.ZERO).reduce(BigDecimal::add)
                .ifPresent(b -> approvalAmountContractGov[0] = b);
        BigDecimal approvalAmountContractTotal = approvalAmountContract[0].add(approvalAmountContractGov[0]);
        cockpitStats.setApprovalAmountContract(approvalAmountContractTotal);

        //合同的差额
        BigDecimal subtractContract = approvalAmountApprovalTotal.subtract(approvalAmountContractTotal);
        cockpitStats.setDifferenceContract(subtractContract);

        //7 核减资金
        cockpitStats.setReduceFundsTotal(subtractApprove.add(subtractApproval).add(subtractContract));

        //8 产出数据
        cockpitStats.setProduceAppNum(0);
        cockpitStats.setProduceDataNum(0);
        cockpitStats.setProduceComponentNum(0);
        cockpitStats.setProduceBrainElementsNum(0);

        //9.绩效
        List<String> projectCodes = projects.stream().map(Project::getProjectCode).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(projectCodes)) {
            List<PerformanceAppraisalProject> performanceAll = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class)
                    .in(PerformanceAppraisalProject::getProjectCode, projectCodes));
            List<PerformanceAppraisalProject> verified = performanceAll.stream().filter(p -> {
                        if (Objects.nonNull(p.getVerifyTotalScore())) {
                            return Boolean.TRUE;
                        }
                        return Boolean.FALSE;
                    }).sorted(Comparator.comparing(PerformanceAppraisalProject::getVerifyTotalScore).reversed())
                    .collect(Collectors.toList());

            List<PerformanceAppraisalProject> start5 = performanceAll.stream().filter(p -> {
                        if (Objects.nonNull(p.getVerifyTotalScore())
                                && p.getVerifyTotalScore().compareTo(BigDecimal.valueOf(80)) > 0) {
                            return Boolean.TRUE;
                        }
                        return Boolean.FALSE;
                    }).sorted(Comparator.comparing(PerformanceAppraisalProject::getVerifyTotalScore).reversed())
                    .collect(Collectors.toList());
            List<PerformanceAppraisalProject> start4 = performanceAll.stream().filter(p -> {
                        if (Objects.nonNull(p.getVerifyTotalScore())
                                && p.getVerifyTotalScore().compareTo(BigDecimal.valueOf(60)) >= 0
                                && p.getVerifyTotalScore().compareTo(BigDecimal.valueOf(80)) < 0) {
                            return Boolean.TRUE;
                        }
                        return Boolean.FALSE;
                    }).sorted(Comparator.comparing(PerformanceAppraisalProject::getVerifyTotalScore).reversed())
                    .collect(Collectors.toList());
            List<PerformanceAppraisalProject> start3 = performanceAll.stream().filter(p -> {
                        if (Objects.nonNull(p.getVerifyTotalScore())
                                && p.getVerifyTotalScore().compareTo(BigDecimal.valueOf(40)) >= 0
                                && p.getVerifyTotalScore().compareTo(BigDecimal.valueOf(60)) < 0) {
                            return Boolean.TRUE;
                        }
                        return Boolean.FALSE;
                    }).sorted(Comparator.comparing(PerformanceAppraisalProject::getVerifyTotalScore).reversed())
                    .collect(Collectors.toList());
            List<PerformanceAppraisalProject> start2 = performanceAll.stream().filter(p -> {
                        if (Objects.nonNull(p.getVerifyTotalScore())
                                && p.getVerifyTotalScore().compareTo(BigDecimal.valueOf(20)) >= 0
                                && p.getVerifyTotalScore().compareTo(BigDecimal.valueOf(40)) < 0) {
                            return Boolean.TRUE;
                        }
                        return Boolean.FALSE;
                    }).sorted(Comparator.comparing(PerformanceAppraisalProject::getVerifyTotalScore).reversed())
                    .collect(Collectors.toList());
            List<PerformanceAppraisalProject> start1 = performanceAll.stream().filter(p -> {
                        if (Objects.nonNull(p.getVerifyTotalScore())
                                && p.getVerifyTotalScore().compareTo(BigDecimal.ZERO) >= 0
                                && p.getVerifyTotalScore().compareTo(BigDecimal.valueOf(20)) < 0) {
                            return Boolean.TRUE;
                        }
                        return Boolean.FALSE;
                    }).sorted(Comparator.comparing(PerformanceAppraisalProject::getVerifyTotalScore).reversed())
                    .collect(Collectors.toList());
            cockpitStats.setPerformanceTotal(performanceAll.size());
            cockpitStats.setPerformanceReviewedTotal(verified.size());
            cockpitStats.setPerformanceTobeReviewTotal(performanceAll.size() - verified.size());

            cockpitStats.setPerformanceTop1Score(BigDecimal.valueOf(start1.size()));
            cockpitStats.setPerformanceTop2Score(BigDecimal.valueOf(start2.size()));
            cockpitStats.setPerformanceTop3Score(BigDecimal.valueOf(start3.size()));
            cockpitStats.setPerformanceTop4Score(BigDecimal.valueOf(start4.size()));
            cockpitStats.setPerformanceTop5Score(BigDecimal.valueOf(start5.size()));
        }

        return cockpitStats;
    }

    /**
     * 建设方案申报了 但未开始审核的项目
     *
     * @param projectCode
     * @return
     */
    private boolean searchSchemaReviewFlow(String projectCode) {
        Project project = projectService.getProjectByCode(projectCode);
        if (Objects.isNull(project)) {
            return Boolean.FALSE;
        }
        List<Long> allVersionProjectId = projectService.getAllVersionProjectId(project);
        ProjectInst pi = projectInstService.getOne(Wrappers.lambdaQuery(ProjectInst.class)
                .in(ProjectInst::getProjectId, allVersionProjectId)
                .eq(ProjectInst::getInstType, InstTypeEnum.CONSTRUCTION_PLAN_REVIEW.getCode())
                .last(BizConst.LIMIT_1));
        if (Objects.isNull(pi)) {
            return Boolean.FALSE;
        }
        String instCode = pi.getInstCode();
        List<HistoricActivityInstance> finished = historyService.createHistoricActivityInstanceQuery()
                .finished()
                .processInstanceId(instCode)
                .orderByHistoricActivityInstanceEndTime()
                .asc()
                .list();
        List<HistoricActivityInstance> unfinished = historyService.createHistoricActivityInstanceQuery()
                .unfinished()
                .processInstanceId(instCode)
                .orderByHistoricActivityInstanceStartTime()
                .asc()
                .list();
        //已经完成的没有 未完成的有 则可计算
        if (CollUtil.isNotEmpty(unfinished) && CollUtil.isEmpty(finished)) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    //已经开始审批
    private boolean searchSchemaReviewedFlow(String projectCode) {
        Project project = projectService.getProjectByCode(projectCode);
        if (Objects.isNull(project)) {
            return Boolean.FALSE;
        }
        List<Long> allVersionProjectId = projectService.getAllVersionProjectId(project);
        ProjectInst pi = projectInstService.getOne(Wrappers.lambdaQuery(ProjectInst.class)
                .in(ProjectInst::getProjectId, allVersionProjectId)
                .eq(ProjectInst::getInstType, InstTypeEnum.CONSTRUCTION_PLAN_REVIEW.getCode())
                .last(BizConst.LIMIT_1));
        if (Objects.isNull(pi)) {
            return Boolean.FALSE;
        }
        String instCode = pi.getInstCode();
        List<HistoricActivityInstance> finished = historyService.createHistoricActivityInstanceQuery()
                .finished()
                .processInstanceId(instCode)
                .orderByHistoricActivityInstanceEndTime()
                .asc()
                .list();
        //已经完成的 则可计算
        if (CollUtil.isNotEmpty(finished)) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    /**
     * 计算环节滞后项目
     *
     * @param projects
     * @return
     */
    private Integer computeLagging(List<Project> projects) {
        List<String> projectCodes = projects.stream().map(Project::getProjectCode).collect(Collectors.toList());
        Map<String, Project> map = projects.stream().collect(Collectors.toMap(Project::getProjectCode, p -> p));
        List<WflowEarlyWarningRecords> records = Lists.newArrayList();
        if (CollUtil.isNotEmpty(projectCodes)) {
            records = earlyWarningRecordsService.list(Wrappers.lambdaQuery(WflowEarlyWarningRecords.class)
                    .in(WflowEarlyWarningRecords::getProjectCode, projectCodes));
        }
        return records.stream().mapToInt(r -> {
            if (!map.containsKey(r.getProjectCode())) {
                return 0;
            }
            Project project = map.get(r.getProjectCode());
            //如果状态 相等 说明预警了 但是没处理 +1
            if (Objects.nonNull(project.getStatus()) && Objects.nonNull(r.getProjectStatus()) &&
                    project.getStatus().equals(r.getProjectStatus())) {
                return 1;
            }
            return 0;
        }).sum();
    }

    private void buildMonitorRise(CockpitStats cockpitStats, CockpitStats thisYearData, CockpitStats lastYearData) {
        if (Objects.isNull(thisYearData) || Objects.isNull(lastYearData)) {
            return;
        }
        cockpitStats.setMonitorOverdueConstructionProjectsRise(BizUtils.computeRise(thisYearData.getMonitorOverdueConstructionProjectsNum(),
                lastYearData.getMonitorOverdueConstructionProjectsNum()));
        cockpitStats.setMonitorLaggingProjectsRise(BizUtils.computeRise(thisYearData.getMonitorLaggingProjectsNum(),
                lastYearData.getMonitorLaggingProjectsNum()));
        cockpitStats.setMonitorRejectedApproveProjectsRise(BizUtils.computeRise(thisYearData.getMonitorRejectedApproveProjectsNum(),
                lastYearData.getMonitorRejectedApproveProjectsNum()));
        cockpitStats.setMonitorRejectedPreReviewProjectsRise(BizUtils.computeRise(thisYearData.getMonitorRejectedPreReviewProjectsNum(),
                lastYearData.getMonitorRejectedPreReviewProjectsNum()));
        cockpitStats.setMonitorAcceptConditionsNotStandardsRise(BizUtils.computeRise(thisYearData.getMonitorAcceptConditionsNotStandardsNum(),
                lastYearData.getMonitorAcceptConditionsNotStandardsNum()));
    }
}
