package org.springblade.modules.project.service.impl;

import cn.hutool.core.map.MapWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bstek.ureport.font.yahei.YaheiFontRegister;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.*;
import org.bouncycastle.asn1.isismtt.x509.ProfessionInfo;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.FileUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.ObjectUtil;
import org.springblade.modules.project.mapper.ProjectInfoMapper;
import org.springblade.modules.project.pojo.dto.*;
import org.springblade.modules.project.pojo.entity.*;
import org.springblade.modules.project.pojo.excel.ProjectImportExcel;
import org.springblade.modules.project.pojo.vo.*;
import org.springblade.modules.project.service.*;
import org.springblade.modules.project.utils.ObjectUtils;
import org.springblade.modules.project.utils.SnowFlakeUtil;
import org.springblade.modules.system.service.IDictBizService;
import org.springframework.beans.BeanUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.nio.file.Paths;
import java.text.DateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.apache.poi.ss.usermodel.TableStyleType.headerRow;

/**
 * @Param
 * @Author wangwl
 * @Date 2024/4/8 12:01
 **/
@Service
@AllArgsConstructor
public class ProjectInfoServiceImpl extends BaseServiceImpl<ProjectInfoMapper, ProjectInfo> implements IProjectInfoService {

    private final IProjectInvestPlanService investPlanService;

    private final IProjectPlanProgressService planProgressService;

    private final IProjectWarningService warningService;

    private final IRepealRecordService repealRecordService;

    private final IDictBizService dictBizService;

    private final BladeRedis bladeRedis;

    @Override
    @Transactional
    public Long add(ProjectInfoDTO dto) {
        //校验是否已经存在相同的项目名称
        List<ProjectInfo> infos = this.list(new LambdaQueryWrapper<ProjectInfo>()
                .eq(ProjectInfo::getName, dto.getName()));
        if (infos.size() > 0){
            throw new ServiceException("新增失败：项目名称已经存在");
        }
        //保存项目信息
        ProjectInfo info = new ProjectInfo();
        BeanUtils.copyProperties(dto,info);
        info.setId(SnowFlakeUtil.getId());
        this.save(info);
        //保存计划信息
        List<ProjectInvestPlan> list = dto.getList();
        if (list == null || list.size() == 0){
            return info.getId();
        }
        BigDecimal projectAll = BigDecimal.ZERO;
        for (ProjectInvestPlan plan : list) {
            Integer year = plan.getPlanYear();
            if (year == null){
                throw new ServiceException("请选择年");
            }
            plan.setPlanYear(null);
            if (ObjectUtils.isAllFieldsNull(plan)){
                plan.setIsPlan(0);
            }else {
                plan.setIsPlan(1);
            }
            plan.setPlanYear(year);
            plan.setProjectId(info.getId());
            //校验全年计划投资
            BigDecimal all = BigDecimal.ZERO;
            if (plan.getOneInvest() != null){
                all = all.add(plan.getOneInvest());
            }
            if (plan.getTwoInvest() != null){
                all = all.add(plan.getTwoInvest());
            }
            if (plan.getThreeInvest() != null){
                all = all.add(plan.getThreeInvest());
            }
            if (plan.getFourInvest() != null){
                all = all.add(plan.getFourInvest());
            }
            if ((plan.getYearlyInvest() == null && !all.equals(BigDecimal.ZERO)) || (plan.getYearlyInvest() != null && all.compareTo(plan.getYearlyInvest()) != 0)){
                throw new ServiceException(dto.getName() +"的"+plan.getPlanYear()+"年全年计划投资与每季度总和不对");
            }
            projectAll = projectAll.add(all);
        }
        if (info.getAllInvestMoney() != null && info.getAllInvestMoney().compareTo(projectAll) == -1){
            throw new ServiceException(dto.getName() +"的"+"所有年计划投资之和不能大于总投资，请修改后重新保存");
        }
        investPlanService.saveBatch(list);
        return info.getId();
    }

    @Override
    public PageVO<ProjectInfoVO> page2(ProjectInfoPageDTO dto) {
        PageVO<ProjectInfoVO> page = new PageVO();
        page.setCurrent(dto.getCurrent());
        page.setSize(dto.getSize());
        PageVO<ProjectInfoVO> iPage = baseMapper.page(page, dto);
        //获取所有建设规模
        Long buildTotal = baseMapper.getBuildTotal(dto);
        iPage.setBuildTotal(buildTotal);
        List<ProjectInfoVO> records = iPage.getRecords();
        if (records != null && records.size() != 0){
            for (ProjectInfoVO vo : records) {
                Integer total = vo.getHasPlanYearTotal();
                if (total == 0){
                    continue;
                }
                BigDecimal totalMonth = new BigDecimal(total).multiply(new BigDecimal("12"));
                BigDecimal totalField = new BigDecimal(total).multiply(new BigDecimal("0.48"));
                //项目进展比例
                if (vo.getProgress() != null){
                    vo.setProgressRatio(vo.getProgress().divide(totalMonth,2, RoundingMode.UP));
                }
                //完成情况填写比例
                if (vo.getFinishedFill() != null && !vo.getFinishedFill().equals(BigDecimal.ZERO)){
                    vo.setFinishedFillRatio(vo.getFinishedFill().divide(totalField,2, RoundingMode.UP));
                }
            }
        }
        return iPage;
    }

    @Override
    public ProjectInfoDetailVO detail(Long id) {
        //获取项目详情
        ProjectInfoDetailVO vo = baseMapper.detail(id);
        //获取计划详情
        List<ProjectInvestPlan> planList = investPlanService.list(new LambdaQueryWrapper<ProjectInvestPlan>()
                .eq(ProjectInvestPlan::getProjectId, id)
                .orderByAsc(ProjectInvestPlan::getPlanYear));
        vo.setList(planList);
        return vo;
    }

    @Override
    @Transactional
    public void update2(ProjectInfoDetailVO dto) {
        ProjectInfo oldInfo = this.getById(dto.getId());
        if (oldInfo.getStartYear() != null){
            if (!oldInfo.getStartYear().equals(dto.getStartYear()) || !oldInfo.getEndYear().equals(dto.getEndYear())){
                throw new ServiceException("不能修改年份");
            }
        }
        //修改项目信息
        ProjectInfo info = new ProjectInfo();
        BeanUtils.copyProperties(dto,info);
        this.updateById(info);
        //修改计划信息,先校验年份是否改变
        List<ProjectInvestPlan> list = dto.getList();
        if (list == null || list.size() == 0){
            return;
        }
        for (ProjectInvestPlan plan : list) {
            //校验全年计划投资
            BigDecimal all = BigDecimal.ZERO;
            if (plan.getOneInvest() != null){
                all = all.add(plan.getOneInvest());
            }
            if (plan.getTwoInvest() != null){
                all = all.add(plan.getTwoInvest());
            }
            if (plan.getThreeInvest() != null){
                all = all.add(plan.getThreeInvest());
            }
            if (plan.getFourInvest() != null){
                all = all.add(plan.getFourInvest());
            }
                if ((plan.getYearlyInvest() == null && all.compareTo(BigDecimal.ZERO) != 0) || (plan.getYearlyInvest() != null && all.compareTo(plan.getYearlyInvest()) != 0)){
                throw new ServiceException(dto.getName() +"的"+plan.getPlanYear()+"年全年计划投资与每季度总和不对");
            }
            if (plan.getYearlyInvest() != null || StringUtils.isNotBlank(plan.getYearlyTarget()) || StringUtils.isNotBlank(plan.getOnePlan())
                || StringUtils.isNotBlank(plan.getTwoPlan()) || StringUtils.isNotBlank(plan.getThreePlan()) || StringUtils.isNotBlank(plan.getFourPlan())){
                plan.setIsPlan(1);
            }else {
                plan.setIsPlan(0);
            }

            //如果已经有完成情况，则更新每个月投资情况
            if (plan.getIsFillPlan() == 1){
                BigDecimal invest = BigDecimal.ZERO;
                BigDecimal investFinish = BigDecimal.ZERO;
                //校验一季度已有投资，则不能删除或改为0
                if (plan.getOneInvest() != null){
                    invest = invest.add(plan.getOneInvest());
                }
                if (plan.getOneInvestFinish() != null){
                    investFinish = investFinish.add(plan.getOneInvestFinish());
                }
                if (plan.getOneInvestFinish() != null && (plan.getOneInvest() == null || plan.getOneInvest().equals(BigDecimal.ZERO))){
                    throw new ServiceException(dto.getName() +"的"+plan.getPlanYear()+"年一季度已有投资金额，不能修改为0");
                }
                if (plan.getIsOneInvestFinish() == 1){
                    plan.setOneInvestRatio(plan.getOneInvestFinish().divide(plan.getOneInvestFinish(),4, RoundingMode.DOWN).multiply(new BigDecimal(100)).setScale(2));
                }

                //校验二季度已有投资，则不能删除或改为0
                if (plan.getTwoInvest() != null){
                    invest = invest.add(plan.getTwoInvest());
                }
                if (plan.getTwoInvestFinish() != null){
                    investFinish = investFinish.add(plan.getTwoInvestFinish());
                }
                if (plan.getTwoInvestFinish() != null && (plan.getTwoInvest() == null || plan.getTwoInvest().equals(BigDecimal.ZERO))){
                    throw new ServiceException(dto.getName() +"的"+plan.getPlanYear()+"年二季度已有投资金额，不能修改为0");
                }
                if (plan.getIsTwoInvestFinish() == 1){
                    plan.setTwoInvestRatio(plan.getTwoInvestFinish().divide(plan.getTwoInvestFinish(),4, RoundingMode.DOWN).multiply(new BigDecimal(100)).setScale(2));
                    plan.setTwoAggregateRatio(investFinish.divide(invest,4, RoundingMode.DOWN).multiply(new BigDecimal(100)).setScale(2));
                }

                //校验三季度已有投资，则不能删除或改为0
                if (plan.getThreeInvestFinish() != null && (plan.getThreeInvest() == null || plan.getThreeInvest().equals(BigDecimal.ZERO))){
                    throw new ServiceException(dto.getName() +"的"+plan.getPlanYear()+"年三季度已有投资金额，不能修改为0");
                }
                if (plan.getIsThreeInvestFinish() == 1){
                    plan.setThreeInvestRatio(plan.getThreeInvestFinish().divide(plan.getThreeInvestFinish(),4, RoundingMode.DOWN).multiply(new BigDecimal(100)).setScale(2));
                    plan.setThreeAggregateRatio(investFinish.divide(invest,4, RoundingMode.DOWN).multiply(new BigDecimal(100)).setScale(2));
                }

                //校验四季度已有投资，则不能删除或改为0
                if (plan.getFourInvestFinish() != null && (plan.getFourInvest() == null || plan.getFourInvest().equals(BigDecimal.ZERO))){
                    throw new ServiceException(dto.getName() +"的"+plan.getPlanYear()+"年四季度已有投资金额，不能修改为0");
                }
                if (plan.getIsFourInvestFinish() == 1){
                    plan.setFourInvestRatio(plan.getFourInvestFinish().divide(plan.getFourInvestFinish(),4, RoundingMode.DOWN).multiply(new BigDecimal(100)).setScale(2));
                    plan.setFourAggregateRatio(investFinish.divide(invest,4, RoundingMode.DOWN).multiply(new BigDecimal(100)).setScale(2));
                }
            }
        }
        investPlanService.saveOrUpdateBatch(list);

    }

    @Override
    public ProjectAndPlanDetailVO detail2(Long id) {
        //项目详情
        ProjectAndPlanDetailVO vo = baseMapper.detail2(id);
        if (vo.getBuildScaleUnit() == 1){
            vo.setBuildScaleName(vo.getBuildScale()+"(公里)");
        }else {
            vo.setBuildScaleName(vo.getBuildScale());
        }
        //获取所有-有计划的年
        List<ProjectInvestPlanVO> planList = baseMapper.getAllPlanByProjectId(id);
        if (planList.size() == 0){
            return vo;
        }
        //获取所有填写的完成情况
        List<ProjectPlanProgressVO> list = baseMapper.getAllProgressByProjectId(id);

        Boolean isPlanDetail = false;
        Map<Long, List<ProjectPlanProgressVO>> listMap = new HashMap<>();
        if (list.size() != 0){
            isPlanDetail = true;
            listMap = list.stream().collect(Collectors.groupingBy(ProjectPlanProgressVO::getInvestPlanId));
        }
        String[] monthNames = {"","1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"};
        //循环年，设置完成情况
        for (ProjectInvestPlanVO planVO : planList) {
            //校验是否允许填写，未设置计划和超过今年的不允许填写
            if (planVO.getIsPlan() == 0 || planVO.getPlanYear() > LocalDate.now().getYear()){
                planVO.setIsCanFill(0);
            }else {
                planVO.setIsCanFill(1);
            }
            //如果没有填写过完成情况，则创建构建完成情况信息
            List<ProjectPlanProgressVO> progresses = new ArrayList<>();
            BigDecimal monthFinished = BigDecimal.ZERO;
            if (planVO.getIsFillPlan() == 0){

                for (int i = 1; i <= 12; i++) {
                    ProjectPlanProgressVO progress = new ProjectPlanProgressVO();
                    progress.setProjectId(id);
                    progress.setInvestPlanId(planVO.getId());
                    progress.setPlanYear(planVO.getPlanYear());
                    progress.setPlanMonth(i);
                    progress.setPlanMonthName(monthNames[i]);
                    progress.setYearlyTarget(planVO.getYearlyTarget());
                    if (i <= 3){
                        progress.setPlanQuarter(1);
                        progress.setPlanQuarterName("一季度");
                        progress.setPlanInvestMoney(planVO.getOneInvest());
                        progress.setWorkPlan(planVO.getOnePlan());
                    }else if (i <= 6){
                        progress.setPlanQuarter(2);
                        progress.setPlanQuarterName("二季度");
                        progress.setPlanInvestMoney(planVO.getTwoInvest());
                        progress.setWorkPlan(planVO.getTwoPlan());
                    }else if (i <= 9){
                        progress.setPlanQuarter(3);
                        progress.setPlanQuarterName("三季度");
                        progress.setPlanInvestMoney(planVO.getThreeInvest());
                        progress.setWorkPlan(planVO.getThreePlan());
                    }else {
                        progress.setPlanQuarter(4);
                        progress.setPlanQuarterName("四季度");
                        progress.setPlanInvestMoney(planVO.getFourInvest());
                        progress.setWorkPlan(planVO.getFourPlan());
                    }
                    progresses.add(progress);
                }
            }else {
                List<ProjectPlanProgressVO> vos = listMap.get(planVO.getId());
                if (!isPlanDetail || vos == null || vos.size() == 0){
                    throw new ServiceException("数据错误，请联系管理员");
                }
                for (ProjectPlanProgressVO progress : vos) {
                    Integer i = progress.getPlanMonth();
                    progress.setPlanMonthName(monthNames[i]);
                    progress.setYearlyTarget(planVO.getYearlyTarget());
                    if (i <= 3){
                        progress.setPlanQuarterName("一季度");
                        if (planVO.getOneInvest() != null) {
                            progress.setPlanInvestMoney(planVO.getOneInvest());
                            progress.setInvestUnfinishedMoney(planVO.getOneInvest().subtract(planVO.getOneInvestFinish()));
                        }
                        progress.setWorkPlan(planVO.getOnePlan());
                    }else if (i <= 6){
                        progress.setPlanQuarterName("二季度");
                        if (planVO.getTwoInvest() != null) {
                            progress.setPlanInvestMoney(planVO.getTwoInvest());
                            progress.setInvestUnfinishedMoney(planVO.getTwoInvest().subtract(planVO.getTwoInvestFinish()));
                        }
                        progress.setWorkPlan(planVO.getTwoPlan());
                    }else if (i <= 9){
                        progress.setPlanQuarterName("三季度");
                        if (planVO.getThreeInvest() != null) {
                            progress.setPlanInvestMoney(planVO.getThreeInvest());
                            progress.setInvestUnfinishedMoney(planVO.getThreeInvest().subtract(planVO.getThreeInvestFinish()));
                        }
                        progress.setWorkPlan(planVO.getThreePlan());
                    }else {
                        progress.setPlanQuarterName("四季度");
                        if (planVO.getFourInvest() != null) {
                            progress.setPlanInvestMoney(planVO.getFourInvest());
                            progress.setInvestUnfinishedMoney(planVO.getFourInvest().subtract(planVO.getFourInvestFinish()));
                        }
                        progress.setWorkPlan(planVO.getFourPlan());
                    }
                }
                progresses = vos;
            }
            planVO.setList(progresses);
        }
        vo.setList(planList);
        return vo;
    }

    @Override
    @Transactional
    public void updateFinished(ProjectAndPlanDetailVO dto) {
        //获取年数组，如果数组为null则跳过保存
        List<ProjectInvestPlanVO> years = dto.getList();
        if (years == null || years.size() == 0){
            return;
        }
        //删除所有年的详情
        baseMapper.deleteProgressByProjectId(dto.getId());
        List<ProjectInvestPlan> updateYearPlan = new ArrayList<>();
        //开工累计完成投资
        BigDecimal projectInvestFinished = BigDecimal.ZERO;
        for (ProjectInvestPlanVO year : years) {
            //如果此年不能填写，则直接跳过
            if (year.getIsCanFill() == 0){
                continue;
            }
            //统计当前整年数据
            ProjectInvestPlan yearPlan = new ProjectInvestPlan();
            //设置底部4条数据
            yearPlan.setId(year.getId());
            yearPlan.setQuestionable(year.getQuestionable());
            yearPlan.setWorkAdvise(year.getWorkAdvise());
            yearPlan.setWriteUnit(year.getWriteUnit());
            yearPlan.setLinkman(year.getLinkman());
            //当年累计完成投资
            BigDecimal allInvestFinished = BigDecimal.ZERO;
            //季度已投资
            BigDecimal investFinished = BigDecimal.ZERO;
            //前面所有季度计划投资
            BigDecimal planInvest = BigDecimal.ZERO;
            //当季投资填写次数
            Integer quarterFillTotal = 0;
            //季度进度总和
            BigDecimal planFinished = BigDecimal.ZERO;
            //当季进度填写次数
            Integer quarterPlanTotal = 0;

            List<ProjectPlanProgressVO> monthList = year.getList();
            for (ProjectPlanProgress progress : monthList) {
                progress.setInvestMoneyAll(null);
                //设置当前行已经填写字段
                Integer fillField = 0;
                Integer i = progress.getPlanMonth();
                if (i <= 3){
                    if (year.getOneInvest() != null && year.getOneInvest().compareTo(BigDecimal.ZERO) != 0 && progress.getInvestMoney() != null) {
                        fillField ++;
                        quarterFillTotal++;
                        investFinished = investFinished.add(progress.getInvestMoney());
                        allInvestFinished = allInvestFinished.add(progress.getInvestMoney());
                        progress.setInvestMoneyAll(allInvestFinished);
                    }
                   if (StringUtils.isNotBlank(year.getOnePlan())){
                        if (StringUtils.isNotBlank(progress.getWorkProgress())){
                            fillField++;
                        }
                       if (StringUtils.isNotBlank(progress.getWorkProgressAll())){
                           fillField++;
                       }
                       if (progress.getPlanRatio() != null){
                           fillField++;
                           quarterPlanTotal++;
                           planFinished = planFinished.add(progress.getPlanRatio());
                       }

                   }
                    if (i == 3){
                        if (year.getOneInvest() != null){
                            planInvest = planInvest.add(year.getOneInvest());
                        }
                        //设置一季度已投资
                        yearPlan.setOneInvestFinish(investFinished);
                        if (quarterFillTotal > 0)yearPlan.setIsFillPlan(1);
                        if (quarterFillTotal == 3){
                            //一季度全部投资都填完，设置投资比例
                            yearPlan.setIsOneInvestFinish(1);
                            yearPlan.setOneInvestRatio(investFinished.divide(year.getOneInvest(),4, RoundingMode.UP).multiply(new BigDecimal(100)).setScale(2));
                        }else {
                            yearPlan.setIsOneInvestFinish(0);
                        }
                        if (quarterPlanTotal == 3){
                            yearPlan.setIsOnePlanFinish(1) ;
                            yearPlan.setOnePlanRatio(planFinished.divide(new BigDecimal(3),2,RoundingMode.UP));
                        }else {
                            yearPlan.setIsOnePlanFinish(0);
                        }
                        //重置季度填写统计
                        quarterFillTotal = 0;
                        quarterPlanTotal = 0;
                        //重置季度已投资
                        investFinished = BigDecimal.ZERO;
                        planFinished = BigDecimal.ZERO;
                    }
                }else if (i <= 6){
                    if (year.getTwoInvest() != null && year.getTwoInvest().compareTo(BigDecimal.ZERO) != 0 && progress.getInvestMoney() != null) {
                        fillField += 1;
                        quarterFillTotal++;
                        investFinished = investFinished.add(progress.getInvestMoney());
                        allInvestFinished = allInvestFinished.add(progress.getInvestMoney());
                        progress.setInvestMoneyAll(allInvestFinished);
                    }
                    if (StringUtils.isNotBlank(year.getTwoPlan())){
                        if (StringUtils.isNotBlank(progress.getWorkProgress())){
                            fillField++;
                        }
                        if (StringUtils.isNotBlank(progress.getWorkProgressAll())){
                            fillField++;
                        }
                        if (progress.getPlanRatio() != null){
                            fillField++;
                            quarterPlanTotal++;
                            planFinished = planFinished.add(progress.getPlanRatio());
                        }

                    }
                    if (i == 6){
                        if (year.getTwoInvest() != null){
                            planInvest = planInvest.add(year.getTwoInvest());
                        }
                        //设置季度已投资
                        yearPlan.setTwoInvestFinish(investFinished);
                        if (quarterFillTotal > 0)yearPlan.setIsFillPlan(1);
                        if (quarterFillTotal == 3){
                            //季度全部投资都填完，设置投资比例
                            yearPlan.setIsTwoInvestFinish(1);
                            yearPlan.setTwoInvestRatio(investFinished.divide(year.getTwoInvest(),4, RoundingMode.UP).multiply(new BigDecimal(100)).setScale(2));
                            //设置累计投资比例，前面所有季度之和
                            if (planInvest.compareTo(BigDecimal.ZERO) != 0){
                                yearPlan.setTwoAggregateRatio(allInvestFinished.divide(planInvest,4, RoundingMode.UP).multiply(new BigDecimal(100)).setScale(2));
                            }
                        }else {
                            yearPlan.setIsTwoInvestFinish(0);
                        }
                        if (quarterPlanTotal == 3){
                            yearPlan.setIsTwoPlanFinish(1); ;
                            yearPlan.setTwoPlanRatio(planFinished.divide(new BigDecimal(3),2,RoundingMode.UP));
                        }else {
                            yearPlan.setIsTwoPlanFinish(0);
                        }
                        //重置季度填写统计
                        quarterFillTotal = 0;
                        quarterPlanTotal = 0;
                        //重置季度已投资
                        investFinished = BigDecimal.ZERO;
                        planFinished = BigDecimal.ZERO;
                    }
                }else if (i <= 9){
                    if (year.getThreeInvest() != null && year.getThreeInvest().compareTo(BigDecimal.ZERO) != 0 && progress.getInvestMoney() != null) {
                        fillField += 1;
                        quarterFillTotal++;
                        investFinished = investFinished.add(progress.getInvestMoney());
                        allInvestFinished = allInvestFinished.add(progress.getInvestMoney());
                        progress.setInvestMoneyAll(allInvestFinished);
                    }
                    if (StringUtils.isNotBlank(year.getThreePlan())){
                        if (StringUtils.isNotBlank(progress.getWorkProgress())){
                            fillField++;
                        }
                        if (StringUtils.isNotBlank(progress.getWorkProgressAll())){
                            fillField++;
                        }
                        if (progress.getPlanRatio() != null){
                            fillField++;
                            quarterPlanTotal++;
                            planFinished = planFinished.add(progress.getPlanRatio());
                        }

                    }
                    if (i == 9){
                        if (year.getThreeInvest() != null){
                            planInvest = planInvest.add(year.getThreeInvest());
                        }
                        //设置季度已投资
                        yearPlan.setThreeInvestFinish(investFinished);
                        if (quarterFillTotal > 0)yearPlan.setIsFillPlan(1);
                        if (quarterFillTotal == 3){
                            //季度全部投资都填完，设置投资比例
                            yearPlan.setIsThreeInvestFinish(1);
                            yearPlan.setThreeInvestRatio(investFinished.divide(year.getThreeInvest(),4, RoundingMode.UP).multiply(new BigDecimal(100)).setScale(2));
                            //设置累计投资比例，前面所有季度之和
                            if (planInvest.compareTo(BigDecimal.ZERO) != 0){
                                yearPlan.setThreeAggregateRatio(allInvestFinished.divide(planInvest,4, RoundingMode.UP).multiply(new BigDecimal(100)).setScale(2));
                            }
                        }else {
                            yearPlan.setIsThreeInvestFinish(0);
                        }
                        if (quarterPlanTotal == 3){
                            yearPlan.setIsThreePlanFinish(1); ;
                            yearPlan.setThreePlanRatio(planFinished.divide(new BigDecimal(3),2,RoundingMode.UP));
                        }else {
                            yearPlan.setIsThreePlanFinish(0);
                        }
                        //重置季度填写统计
                        quarterFillTotal = 0;
                        quarterPlanTotal = 0;
                        //重置季度已投资
                        investFinished = BigDecimal.ZERO;
                        planFinished = BigDecimal.ZERO;
                    }
                }else {
                    if (year.getFourInvest() != null && year.getFourInvest().compareTo(BigDecimal.ZERO) != 0 && progress.getInvestMoney() != null) {
                        fillField += 1;
                        quarterFillTotal++;
                        investFinished = investFinished.add(progress.getInvestMoney());
                        allInvestFinished = allInvestFinished.add(progress.getInvestMoney());
                        progress.setInvestMoneyAll(allInvestFinished);
                    }
                    if (StringUtils.isNotBlank(year.getFourPlan())){
                        if (StringUtils.isNotBlank(progress.getWorkProgress())){
                            fillField++;
                        }
                        if (StringUtils.isNotBlank(progress.getWorkProgressAll())){
                            fillField++;
                        }
                        if (progress.getPlanRatio() != null){
                            fillField++;
                            quarterPlanTotal++;
                            planFinished = planFinished.add(progress.getPlanRatio());
                        }

                    }
                    if (i == 12){
                        if (year.getFourInvest() != null){
                            planInvest = planInvest.add(year.getFourInvest());
                        }
                        //设置季度已投资
                        yearPlan.setFourInvestFinish(investFinished);
                        if (quarterFillTotal > 0)yearPlan.setIsFillPlan(1);
                        if (quarterFillTotal == 3){
                            //季度全部投资都填完，设置投资比例
                            yearPlan.setIsFourInvestFinish(1);
                            yearPlan.setFourInvestRatio(investFinished.divide(year.getFourInvest(),4, RoundingMode.UP).multiply(new BigDecimal(100)).setScale(2));
                            //设置累计投资比例，前面所有季度之和
                            if (planInvest.compareTo(BigDecimal.ZERO) != 0){
                                yearPlan.setFourAggregateRatio(allInvestFinished.divide(planInvest,4, RoundingMode.UP).multiply(new BigDecimal(100)).setScale(2));
                            }
                        }else {
                            yearPlan.setIsFourInvestFinish(0);
                        }
                        if (quarterPlanTotal == 3){
                            yearPlan.setIsFourPlanFinish(1); ;
                            yearPlan.setFourPlanRatio(planFinished.divide(new BigDecimal(3),2,RoundingMode.UP));
                        }else {
                            yearPlan.setIsFourPlanFinish(0);
                        }
                        //重置季度填写统计
                        quarterFillTotal = 0;
                        quarterPlanTotal = 0;
                        //重置季度已投资
                        investFinished = BigDecimal.ZERO;
                        planFinished = BigDecimal.ZERO;
                    }
                }
                progress.setFillField(fillField);
                if (fillField > 0){
                    yearPlan.setIsFillPlan(1);
                }
            }
            //直接保存月计划集合
            List<ProjectPlanProgress> progresses = new ArrayList<>();
            for (ProjectPlanProgressVO vo : monthList) {
                ProjectPlanProgress progress = new ProjectPlanProgress();
                BeanUtils.copyProperties(vo,progress);
                progresses.add(progress);
            }
            planProgressService.saveBatch(progresses);
            //添加要修改年计划
            projectInvestFinished = projectInvestFinished.add(allInvestFinished);
            yearPlan.setYearFinishInvest(allInvestFinished);
            yearPlan.setStartFinishInvest(projectInvestFinished);
            if (year.getYearlyInvest() != null) {
                yearPlan.setYearUnfinishedInvest(year.getYearlyInvest().subtract(allInvestFinished));
            }
            updateYearPlan.add(yearPlan);
        }
        //修改年计划
        investPlanService.updateBatchById(updateYearPlan);
    }

    @Override
    @Transactional
    public void delete(ProjectInfoPageDTO dto) {
        String ids = dto.getIds();
        if (StringUtils.isBlank(ids)){
            throw new ServiceException("请选择");
        }
        List<Long> longs = Func.toLongList(ids);
        for (Long id : longs) {
            this.removeById(id);
            investPlanService.remove(new LambdaQueryWrapper<ProjectInvestPlan>()
                    .eq(ProjectInvestPlan::getProjectId,id));
            planProgressService.remove(new LambdaQueryWrapper<ProjectPlanProgress>()
                    .eq(ProjectPlanProgress::getProjectId,id));
        }
    }

    @Override
    public DataProjectStatVO dataProjectStat(DataStatDTO dto) {
        Integer year = dto.getYear();
        if (year == null){
            throw new ServiceException("请选择年");
        }
        DataProjectStatVO vo = new DataProjectStatVO();
        vo.setProjectTotal(0);
        vo.setCurrentMoney(BigDecimal.ZERO);
        vo.setInvestRatio(BigDecimal.ZERO);
        vo.setPlanAllMoney(BigDecimal.ZERO);
        vo.setTotal1(0);
        vo.setTotal2(0);
        vo.setTotal3(0);
        List<DataProjectStatVO2> vo2s = baseMapper.dataProjectStat(dto);
        if (vo2s.size() == 0){
            return vo;
        }
        List<ProjectInvestPlan> planList = investPlanService.list(new LambdaQueryWrapper<ProjectInvestPlan>()
                .eq(ProjectInvestPlan::getPlanYear, year)
                .in(ProjectInvestPlan::getProjectId, vo2s.stream().map(l -> l.getId()).collect(Collectors.toList())));
        if (vo2s.size() != planList.size()){
            throw new ServiceException("项目数据错误，请联系管理员");
        }
        Map<Long, ProjectInvestPlan> planMap = planList.stream().collect(Collectors.toMap(l -> l.getProjectId(), l -> l));
        int[] quarters = {0,1,1,1,2,2,2,3,3,3,4,4,4};
        Integer month = dto.getMonth();
        for (DataProjectStatVO2 vo2 : vo2s) {
            //获取当年计划
            ProjectInvestPlan plan = planMap.get(vo2.getId());
            //判断是否选择过月，选择过月则计划总投资为季度-实际完成投资为当月
            if (month != null && month != -1) {
                if (quarters[month] == 1) {
                    vo2.setPlanAllMoney(plan.getOneInvest() == null ? BigDecimal.ZERO : plan.getOneInvest());
                    vo2.setCurrentMoney(plan.getOneInvestFinish() == null ? BigDecimal.ZERO : plan.getOneInvestFinish());
                } else if (quarters[month] == 2) {
                    vo2.setPlanAllMoney(plan.getTwoInvest() == null ? BigDecimal.ZERO : plan.getTwoInvest());
                    vo2.setCurrentMoney(plan.getTwoInvestFinish() == null ? BigDecimal.ZERO : plan.getTwoInvestFinish());
                } else if (quarters[month] == 3) {
                    vo2.setPlanAllMoney(plan.getThreeInvest() == null ? BigDecimal.ZERO : plan.getThreeInvest());
                    vo2.setCurrentMoney(plan.getThreeInvestFinish() == null ? BigDecimal.ZERO : plan.getThreeInvestFinish());
                } else {
                    vo2.setPlanAllMoney(plan.getFourInvest() == null ? BigDecimal.ZERO : plan.getFourInvest());
                    vo2.setCurrentMoney(plan.getFourInvestFinish() == null ? BigDecimal.ZERO : plan.getFourInvestFinish());
                }
            } else {
                //没有选择过月计划总投资为年-实际完成投资为当年，
                vo2.setPlanAllMoney(plan.getYearlyInvest() == null ? BigDecimal.ZERO : plan.getYearlyInvest());
                vo2.setCurrentMoney(plan.getYearFinishInvest() == null ? BigDecimal.ZERO : plan.getYearFinishInvest());
            }
            //判断项目进程类型
            if ((plan.getIsOneInvestFinish() == 1 && plan.getOneInvest().compareTo(plan.getOneInvestFinish()) > 0) ||
                    (plan.getIsTwoInvestFinish() == 1 && plan.getTwoInvest().compareTo(plan.getTwoInvestFinish()) > 0) ||
                    (plan.getIsThreeInvestFinish() == 1 && plan.getThreeInvest().compareTo(plan.getThreeInvestFinish()) > 0) ||
                    (plan.getIsFourInvestFinish() == 1 && plan.getFourInvest().compareTo(plan.getFourInvestFinish()) > 0) ||
                    (plan.getIsOnePlanFinish() == 1 && plan.getOnePlanRatio().compareTo(new BigDecimal(100)) < 0) ||
                    (plan.getIsTwoPlanFinish() == 1 && plan.getTwoPlanRatio().compareTo(new BigDecimal(100)) < 0) ||
                    (plan.getIsThreePlanFinish() == 1 && plan.getThreePlanRatio().compareTo(new BigDecimal(100)) < 0) ||
                    (plan.getIsFourPlanFinish() == 1 && plan.getFourPlanRatio().compareTo(new BigDecimal(100)) < 0)){
                vo2.setScheduleType(3);
            }else if ((plan.getIsOneInvestFinish() == 1 && plan.getOneInvest().compareTo(plan.getOneInvestFinish()) < 0) ||
                    (plan.getIsTwoInvestFinish() == 1 && plan.getTwoInvest().compareTo(plan.getTwoInvestFinish()) < 0) ||
                    (plan.getIsThreeInvestFinish() == 1 && plan.getThreeInvest().compareTo(plan.getThreeInvestFinish()) < 0) ||
                    (plan.getIsFourInvestFinish() == 1 && plan.getFourInvest().compareTo(plan.getFourInvestFinish()) < 0) ||
                    (plan.getIsOnePlanFinish() == 1 && plan.getOnePlanRatio().compareTo(new BigDecimal(100)) > 0) ||
                    (plan.getIsTwoPlanFinish() == 1 && plan.getTwoPlanRatio().compareTo(new BigDecimal(100)) > 0) ||
                    (plan.getIsThreePlanFinish() == 1 && plan.getThreePlanRatio().compareTo(new BigDecimal(100)) > 0) ||
                    (plan.getIsFourPlanFinish() == 1 && plan.getFourPlanRatio().compareTo(new BigDecimal(100)) > 0)){
                vo2.setScheduleType(2);
            }else  {
                vo2.setScheduleType(1);
            }

        }
        //判断是否选择过项目进度类型，选择过，那么重新把集合赋值为筛选后的
        Integer scheduleType = dto.getProjectScheduleType();
        if (scheduleType != null && scheduleType != -1){
            vo2s = vo2s.stream().filter(l->scheduleType.equals(l.getScheduleType())).collect(Collectors.toList());
        }
        vo.setProjectTotal(vo2s.size());
        vo.setPlanAllMoney(vo2s.stream().map(l->l.getPlanAllMoney()).reduce(BigDecimal.ZERO,BigDecimal::add));
        vo.setCurrentMoney(vo2s.stream().map(l->l.getCurrentMoney()).reduce(BigDecimal.ZERO,BigDecimal::add));
        if (vo.getPlanAllMoney().compareTo(BigDecimal.ZERO) == 0){
            vo.setInvestRatio(vo.getCurrentMoney());
        }else {
            vo.setInvestRatio(vo.getCurrentMoney().multiply(new BigDecimal(100)).divide(vo.getPlanAllMoney(),2,RoundingMode.UP));
        }
        vo.setTotal1((int) vo2s.stream().filter(l->l.getScheduleType() == 1).count());
        vo.setTotal2((int) vo2s.stream().filter(l->l.getScheduleType() == 2).count());
        vo.setTotal3((int) vo2s.stream().filter(l->l.getScheduleType() == 3).count());
        return vo;
    }

    @Override
    public DataInvestStatVO dataInvestStat(DataStatDTO dto) {
        Integer year = dto.getYear();
        if (year == null){
            throw new ServiceException("请选择年");
        }
        DataInvestStatVO vo = new DataInvestStatVO();
        vo.setOneFinished(BigDecimal.ZERO);
        vo.setOneUnFinished(BigDecimal.ZERO);
        vo.setTwoFinished(BigDecimal.ZERO);
        vo.setTwoUnFinished(BigDecimal.ZERO);
        vo.setThreeFinished(BigDecimal.ZERO);
        vo.setThreeUnFinished(BigDecimal.ZERO);
        vo.setFourFinished(BigDecimal.ZERO);
        vo.setFourUnFinished(BigDecimal.ZERO);
        List<DataInvestStatVO2> vo2s = baseMapper.dataInvestStat(dto);
        if (vo2s.size() == 0){
            return vo;
        }
        List<ProjectInvestPlan> planList = investPlanService.list(new LambdaQueryWrapper<ProjectInvestPlan>()
                .eq(ProjectInvestPlan::getPlanYear, year)
                .in(ProjectInvestPlan::getProjectId, vo2s.stream().map(l -> l.getId()).collect(Collectors.toList())));
        if (vo2s.size() != planList.size()){
            throw new ServiceException("项目数据错误，请联系管理员");
        }
        Map<Long, ProjectInvestPlan> planMap = planList.stream().collect(Collectors.toMap(l -> l.getProjectId(), l -> l));
        int[] quarters = {0,1,1,1,2,2,2,3,3,3,4,4,4};
        Integer month = dto.getMonth();
        for (DataInvestStatVO2 vo2 : vo2s) {
            //获取当年计划
            ProjectInvestPlan plan = planMap.get(vo2.getId());
            //判断是否选择过月，选择过月则计划总投资为季度-实际完成投资为当月
            if (month != null && month != -1){
                if (quarters[month] == 1){
                    vo2.setPlanAllMoney(plan.getOneInvest() == null?BigDecimal.ZERO:plan.getOneInvest());
                    vo2.setCurrentMoney(plan.getOneInvestFinish() == null?BigDecimal.ZERO:plan.getOneInvestFinish());
                    vo2.setUnFinishedMoney(vo2.getPlanAllMoney().subtract(vo2.getCurrentMoney()));
                }else if (quarters[month] == 2){
                    vo2.setPlanAllMoney(plan.getTwoInvest() == null?BigDecimal.ZERO:plan.getTwoInvest());
                    vo2.setCurrentMoney(plan.getTwoInvestFinish() == null?BigDecimal.ZERO:plan.getTwoInvestFinish());
                    vo2.setUnFinishedMoney(vo2.getPlanAllMoney().subtract(vo2.getCurrentMoney()));
                }else  if (quarters[month] == 3){
                    vo2.setPlanAllMoney(plan.getThreeInvest() == null?BigDecimal.ZERO:plan.getThreeInvest());
                    vo2.setCurrentMoney(plan.getThreeInvestFinish() == null?BigDecimal.ZERO:plan.getThreeInvestFinish());
                    vo2.setUnFinishedMoney(vo2.getPlanAllMoney().subtract(vo2.getCurrentMoney()));
                }else {
                    vo2.setPlanAllMoney(plan.getFourInvest() == null?BigDecimal.ZERO:plan.getFourInvest());
                    vo2.setCurrentMoney(plan.getFourInvestFinish() == null?BigDecimal.ZERO:plan.getFourInvestFinish());
                    vo2.setUnFinishedMoney(vo2.getPlanAllMoney().subtract(vo2.getCurrentMoney()));
                }
            }else {
                //没有选择过月计划总投资为年-实际完成投资为当年，
                vo2.setPlanAllMoney(plan.getYearlyInvest() == null?BigDecimal.ZERO:plan.getYearlyInvest());
                vo2.setCurrentMoney(plan.getYearFinishInvest() == null?BigDecimal.ZERO:plan.getYearFinishInvest());
                vo2.setUnFinishedMoney(vo2.getPlanAllMoney().subtract(vo2.getCurrentMoney()));
            }
            //设置每个季度数据
            vo2.setOneFinished(plan.getOneInvestFinish() == null?BigDecimal.ZERO:plan.getOneInvestFinish());
            vo2.setOneUnFinished(plan.getOneInvest() == null?BigDecimal.ZERO:plan.getOneInvest().subtract(vo2.getOneFinished()));
            vo2.setTwoFinished(plan.getTwoInvestFinish() == null?BigDecimal.ZERO:plan.getTwoInvestFinish());
            vo2.setTwoUnFinished(plan.getTwoInvest() == null?BigDecimal.ZERO:plan.getTwoInvest().subtract(vo2.getTwoFinished()));
            vo2.setThreeFinished(plan.getThreeInvestFinish() == null?BigDecimal.ZERO:plan.getThreeInvestFinish());
            vo2.setThreeUnFinished(plan.getThreeInvest() == null?BigDecimal.ZERO:plan.getThreeInvest().subtract(vo2.getThreeFinished()));
            vo2.setFourFinished(plan.getFourInvestFinish() == null?BigDecimal.ZERO:plan.getFourInvestFinish());
            vo2.setFourUnFinished(plan.getFourInvest() == null?BigDecimal.ZERO:plan.getFourInvest().subtract(vo2.getFourFinished()));
            //判断项目进程类型
            if (plan.getOneInvest() == null || plan.getTwoInvest() == null || plan.getThreeInvest() == null || plan.getFourInvest() == null ||
                    plan.getIsOneInvestFinish() == 0 || plan.getIsTwoInvestFinish() == 0 || plan.getIsThreeInvestFinish() == 0 || plan.getIsFourInvestFinish() == 0 ||
                    plan.getIsOnePlanFinish() == 0 || plan.getIsTwoPlanFinish() == 0 || plan.getIsThreePlanFinish() == 0 || plan.getIsFourPlanFinish() == 0) {
                vo2.setScheduleType(3);
            } else {
                if (plan.getOneInvest().compareTo(plan.getOneInvestFinish()) <= 0 &&
                        plan.getTwoInvest().compareTo(plan.getTwoInvestFinish()) <= 0 &&
                        plan.getThreeInvest().compareTo(plan.getThreeInvestFinish()) <= 0 &&
                        plan.getFourInvest().compareTo(plan.getFourInvestFinish()) <= 0 &&
                        plan.getOnePlanRatio().compareTo(new BigDecimal(100)) >= 0 &&
                        plan.getTwoPlanRatio().compareTo(new BigDecimal(100)) >= 0 &&
                        plan.getThreePlanRatio().compareTo(new BigDecimal(100)) >= 0 &&
                        plan.getFourPlanRatio().compareTo(new BigDecimal(100)) >= 0) {
                    vo2.setScheduleType(2);
                } else if ((plan.getOneInvest().compareTo(plan.getOneInvestFinish()) == 0 &&
                        plan.getTwoInvest().compareTo(plan.getTwoInvestFinish()) == 0 &&
                        plan.getThreeInvest().compareTo(plan.getThreeInvestFinish()) == 0 &&
                        plan.getFourInvest().compareTo(plan.getFourInvestFinish()) == 0 &&
                        plan.getOnePlanRatio().compareTo(new BigDecimal(100)) == 0 &&
                        plan.getTwoPlanRatio().compareTo(new BigDecimal(100)) == 0 &&
                        plan.getThreePlanRatio().compareTo(new BigDecimal(100)) == 0 &&
                        plan.getFourPlanRatio().compareTo(new BigDecimal(100)) == 0)) {
                    vo2.setScheduleType(1);
                } else {
                    vo2.setScheduleType(3);
                }
            }
        }
        //判断是否选择过项目进度类型，选择过，那么重新把集合赋值为筛选后的
        Integer scheduleType = dto.getProjectScheduleType();
        if (scheduleType != null && scheduleType != -1){
            vo2s = vo2s.stream().filter(l->scheduleType.equals(l.getScheduleType())).collect(Collectors.toList());
        }
        //统计季度
        vo.setOneFinished(vo2s.stream().map(l->l.getOneFinished()).reduce(BigDecimal.ZERO,BigDecimal::add));
        vo.setOneUnFinished(vo2s.stream().map(l->l.getOneUnFinished()).reduce(BigDecimal.ZERO,BigDecimal::add));
        vo.setTwoFinished(vo2s.stream().map(l->l.getTwoFinished()).reduce(BigDecimal.ZERO,BigDecimal::add));
        vo.setTwoUnFinished(vo2s.stream().map(l->l.getTwoUnFinished()).reduce(BigDecimal.ZERO,BigDecimal::add));
        vo.setThreeFinished(vo2s.stream().map(l->l.getThreeFinished()).reduce(BigDecimal.ZERO,BigDecimal::add));
        vo.setThreeUnFinished(vo2s.stream().map(l->l.getThreeUnFinished()).reduce(BigDecimal.ZERO,BigDecimal::add));
        vo.setFourFinished(vo2s.stream().map(l->l.getFourFinished()).reduce(BigDecimal.ZERO,BigDecimal::add));
        vo.setFourUnFinished(vo2s.stream().map(l->l.getFourUnFinished()).reduce(BigDecimal.ZERO,BigDecimal::add));
        //统计项目阶段
        List<DataInvestStatVO.InvestInfo> list = new ArrayList<>();
        Map<Integer, List<DataInvestStatVO2>> map = vo2s.stream().collect(Collectors.groupingBy(DataInvestStatVO2::getProjectStage));
        Set<Integer> stages = map.keySet();
        ArrayList<Integer> stages2 = new ArrayList<>(stages);
        Collections.sort(stages2);
        for (Integer stage : stages2) {
            //按照项目类型分组
            Map<Integer, List<DataInvestStatVO2>> listMap = map.get(stage).stream().collect(Collectors.groupingBy(DataInvestStatVO2::getProjectType));
            Set<Integer> types = listMap.keySet();
            ArrayList<Integer> types2 = new ArrayList<>(types);
            Collections.sort(types2);
            for (Integer type : types2) {
                List<DataInvestStatVO2> vo2List = listMap.get(type);
                DataInvestStatVO.InvestInfo info = new DataInvestStatVO.InvestInfo();
                info.setProjectStageName(vo2List.get(0).getProjectStageName());
                info.setProjectTypeName(vo2List.get(0).getProjectTypeName());
                info.setPlanAllMoney(vo2List.stream().map(l->l.getPlanAllMoney()).reduce(BigDecimal.ZERO,BigDecimal::add));
                info.setCurrentMoney(vo2List.stream().map(l->l.getCurrentMoney()).reduce(BigDecimal.ZERO,BigDecimal::add));
                info.setUnFinishedMoney(vo2List.stream().map(l->l.getUnFinishedMoney()).reduce(BigDecimal.ZERO,BigDecimal::add));
                //走势图
                Map<String,List<BigDecimal>> stringListMap = new HashMap<>();
                List<BigDecimal> planInvest = new ArrayList<>();
                List<BigDecimal> finishedInvest = new ArrayList<>();
                List<BigDecimal> unFinishedInvest = new ArrayList<>();
                BigDecimal one = BigDecimal.ZERO;
                BigDecimal two = BigDecimal.ZERO;
                BigDecimal three = BigDecimal.ZERO;
                BigDecimal four = BigDecimal.ZERO;
                BigDecimal one2 = BigDecimal.ZERO;
                BigDecimal two2 = BigDecimal.ZERO;
                BigDecimal three2 = BigDecimal.ZERO;
                BigDecimal four2 = BigDecimal.ZERO;
                BigDecimal one3 = BigDecimal.ZERO;
                BigDecimal two3 = BigDecimal.ZERO;
                BigDecimal three3 = BigDecimal.ZERO;
                BigDecimal four3 = BigDecimal.ZERO;
                for (DataInvestStatVO2 vo2 : vo2List) {
                    ProjectInvestPlan plan = planMap.get(vo2.getId());
                    if (plan.getOneInvest() != null){
                        one = one.add(plan.getOneInvest());
                    }
                    if (plan.getTwoInvest() != null){
                        two = two.add(plan.getTwoInvest());
                    }
                    if (plan.getThreeInvest() != null){
                        three = three.add(plan.getThreeInvest());
                    }
                    if (plan.getFourInvest() != null){
                        four = four.add(plan.getFourInvest());
                    }
                    one2 = one2.add(vo2.getOneFinished());
                    one3 = one3.add(vo2.getOneUnFinished());

                    two2 = two2.add(vo2.getTwoFinished());
                    two3 = two3.add(vo2.getTwoUnFinished());

                    three2 = three2.add(vo2.getThreeFinished());
                    three3 = three3.add(vo2.getThreeUnFinished());

                    four2 = four2.add(vo2.getFourFinished());
                    four3 = four3.add(vo2.getFourUnFinished());
                }
                planInvest.add(one);
                planInvest.add(two);
                planInvest.add(three);
                planInvest.add(four);
                finishedInvest.add(one2);
                finishedInvest.add(two2);
                finishedInvest.add(three2);
                finishedInvest.add(four2);
                unFinishedInvest.add(one3);
                unFinishedInvest.add(two3);
                unFinishedInvest.add(three3);
                unFinishedInvest.add(four3);
                //a计划b实际c未完成
                stringListMap.put("a",planInvest);
                stringListMap.put("b",finishedInvest);
                stringListMap.put("c",unFinishedInvest);
                info.setMap(stringListMap);
                list.add(info);
            }
        }
        vo.setList(list);
        return vo;
    }

    @Override
    public DataScheduleStatVO dataScheduleStat(DataStatDTO dto) {
        Integer year = dto.getYear();
        if (year == null){
            throw new ServiceException("请选择年");
        }
        DataScheduleStatVO vo = new DataScheduleStatVO();
        vo.setOneFinished(0);
        vo.setOneUnFinished(0);
        vo.setTwoFinished(0);
        vo.setTwoUnFinished(0);
        vo.setThreeFinished(0);
        vo.setThreeUnFinished(0);
        vo.setFourFinished(0);
        vo.setFourUnFinished(0);
        List<DataScheduleStatVO2> vo2s = baseMapper.dataScheduleStat(dto);
        if (vo2s.size() == 0){
            return vo;
        }
        List<ProjectInvestPlan> planList = investPlanService.list(new LambdaQueryWrapper<ProjectInvestPlan>()
                .eq(ProjectInvestPlan::getPlanYear, year)
                .in(ProjectInvestPlan::getProjectId, vo2s.stream().map(l -> l.getId()).collect(Collectors.toList())));
        if (vo2s.size() != planList.size()){
            throw new ServiceException("项目数据错误，请联系管理员");
        }
        Map<Long, ProjectInvestPlan> planMap = planList.stream().collect(Collectors.toMap(l -> l.getProjectId(), l -> l));
        int[] quarters = {0,1,1,1,2,2,2,3,3,3,4,4,4};
        Integer month = dto.getMonth();
        for (DataScheduleStatVO2 vo2 : vo2s) {
            //获取当年计划
            ProjectInvestPlan plan = planMap.get(vo2.getId());
            if (plan.getIsOnePlanFinish() == 0 || plan.getOnePlanRatio().compareTo(new BigDecimal(100)) < 0){
                vo2.setIsOneFinished(0);
            }else {
                vo2.setIsOneFinished(1);
            }
            if (plan.getIsTwoPlanFinish() == 0 || plan.getTwoPlanRatio().compareTo(new BigDecimal(100)) < 0){
                vo2.setIsTwoFinished(0);
            }else {
                vo2.setIsTwoFinished(1);
            }
            if (plan.getIsThreePlanFinish() == 0 || plan.getThreePlanRatio().compareTo(new BigDecimal(100)) < 0){
                vo2.setIsThreeFinished(0);
            }else {
                vo2.setIsThreeFinished(1);
            }
            if (plan.getIsFourPlanFinish() == 0 || plan.getFourPlanRatio().compareTo(new BigDecimal(100)) < 0){
                vo2.setIsFourFinished(0);
            }else {
                vo2.setIsFourFinished(1);
            }

            //没有选择过月计划总投资为年-实际完成投资为当年
            if (plan.getIsOnePlanFinish() == 0 || plan.getOnePlanRatio().compareTo(new BigDecimal(100)) < 0 ||
                    plan.getIsTwoPlanFinish() == 0 || plan.getTwoPlanRatio().compareTo(new BigDecimal(100)) < 0 ||
                    plan.getIsThreePlanFinish() == 0 || plan.getThreePlanRatio().compareTo(new BigDecimal(100)) < 0 ||
                    plan.getIsFourPlanFinish() == 0 || plan.getFourPlanRatio().compareTo(new BigDecimal(100)) < 0
            ){
                vo2.setIsYearFinished(0);
            }else {
                vo2.setIsYearFinished(1);
            }
            //判断项目进程类型
            if (plan.getOneInvest() == null || plan.getTwoInvest() == null || plan.getThreeInvest() == null || plan.getFourInvest() == null ||
                    plan.getIsOneInvestFinish() == 0 || plan.getIsTwoInvestFinish() == 0 || plan.getIsThreeInvestFinish() == 0 || plan.getIsFourInvestFinish() == 0 ||
                    plan.getIsOnePlanFinish() == 0 || plan.getIsTwoPlanFinish() == 0 || plan.getIsThreePlanFinish() == 0 || plan.getIsFourPlanFinish() == 0) {
                vo2.setScheduleType(3);
            } else {
                if (plan.getOneInvest().compareTo(plan.getOneInvestFinish()) <= 0 &&
                        plan.getTwoInvest().compareTo(plan.getTwoInvestFinish()) <= 0 &&
                        plan.getThreeInvest().compareTo(plan.getThreeInvestFinish()) <= 0 &&
                        plan.getFourInvest().compareTo(plan.getFourInvestFinish()) <= 0 &&
                        plan.getOnePlanRatio().compareTo(new BigDecimal(100)) >= 0 &&
                        plan.getTwoPlanRatio().compareTo(new BigDecimal(100)) >= 0 &&
                        plan.getThreePlanRatio().compareTo(new BigDecimal(100)) >= 0 &&
                        plan.getFourPlanRatio().compareTo(new BigDecimal(100)) >= 0) {
                    vo2.setScheduleType(2);
                } else if ((plan.getOneInvest().compareTo(plan.getOneInvestFinish()) == 0 &&
                        plan.getTwoInvest().compareTo(plan.getTwoInvestFinish()) == 0 &&
                        plan.getThreeInvest().compareTo(plan.getThreeInvestFinish()) == 0 &&
                        plan.getFourInvest().compareTo(plan.getFourInvestFinish()) == 0 &&
                        plan.getOnePlanRatio().compareTo(new BigDecimal(100)) == 0 &&
                        plan.getTwoPlanRatio().compareTo(new BigDecimal(100)) == 0 &&
                        plan.getThreePlanRatio().compareTo(new BigDecimal(100)) == 0 &&
                        plan.getFourPlanRatio().compareTo(new BigDecimal(100)) == 0)) {
                    vo2.setScheduleType(1);
                } else {
                    vo2.setScheduleType(3);
                }
            }
        }
        //判断是否选择过项目进度类型，选择过，那么重新把集合赋值为筛选后的
        Integer scheduleType = dto.getProjectScheduleType();
        if (scheduleType != null && scheduleType != -1){
            vo2s = vo2s.stream().filter(l->scheduleType.equals(l.getScheduleType())).collect(Collectors.toList());
        }
        //统计季度
        vo.setOneFinished((int) vo2s.stream().filter(l->l.getIsOneFinished() == 1).count());
        vo.setOneUnFinished((int) vo2s.stream().filter(l->l.getIsOneFinished() == 0).count());
        vo.setTwoFinished((int) vo2s.stream().filter(l->l.getIsTwoFinished() == 1).count());
        vo.setTwoUnFinished((int) vo2s.stream().filter(l->l.getIsTwoFinished() == 0).count());
        vo.setThreeFinished((int) vo2s.stream().filter(l->l.getIsThreeFinished() == 1).count());
        vo.setThreeUnFinished((int) vo2s.stream().filter(l->l.getIsThreeFinished() == 0).count());
        vo.setFourFinished((int) vo2s.stream().filter(l->l.getIsFourFinished() == 1).count());
        vo.setFourUnFinished((int) vo2s.stream().filter(l->l.getIsFourFinished() == 0).count());

        //统计项目阶段
        List<DataScheduleStatVO.ScheduleInfo> list = new ArrayList<>();
        //按年
        Map<Integer, List<DataScheduleStatVO2>> map = vo2s.stream().collect(Collectors.groupingBy(DataScheduleStatVO2::getProjectStage));
        Set<Integer> stages = map.keySet();
        ArrayList<Integer> stages2 = new ArrayList<>(stages);
        Collections.sort(stages2);
        for (Integer stage : stages2) {
            //按照项目类型分组
            Map<Integer, List<DataScheduleStatVO2>> listMap = map.get(stage).stream().collect(Collectors.groupingBy(DataScheduleStatVO2::getProjectType));
            Set<Integer> types = listMap.keySet();
            ArrayList<Integer> types2 = new ArrayList<>(types);
            Collections.sort(types2);
            for (Integer type : types2) {
                List<DataScheduleStatVO2> vo2List = listMap.get(type);
                DataScheduleStatVO.ScheduleInfo info = new DataScheduleStatVO.ScheduleInfo();
                info.setProjectStageName(vo2List.get(0).getProjectStageName());
                info.setProjectTypeName(vo2List.get(0).getProjectTypeName());
                info.setProjectTotal(vo2List.size());
                if (month != null && month != -1) {
                    if (quarters[month] == 1) {
                        info.setFinishedTotal((int) vo2List.stream().filter(l->l.getIsOneFinished() == 1).count());
                        info.setUnFinishedTotal((int) vo2List.stream().filter(l->l.getIsOneFinished() == 0).count());
                    } else if (quarters[month] == 2) {
                        info.setFinishedTotal((int) vo2List.stream().filter(l->l.getIsTwoFinished() == 1).count());
                        info.setUnFinishedTotal((int) vo2List.stream().filter(l->l.getIsTwoFinished() == 0).count());
                    } else if (quarters[month] == 3) {
                        info.setFinishedTotal((int) vo2List.stream().filter(l->l.getIsThreeFinished() == 1).count());
                        info.setUnFinishedTotal((int) vo2List.stream().filter(l->l.getIsThreeFinished() == 0).count());
                    } else {
                        info.setFinishedTotal((int) vo2List.stream().filter(l->l.getIsFourFinished() == 1).count());
                        info.setUnFinishedTotal((int) vo2List.stream().filter(l->l.getIsFourFinished() == 0).count());
                    }
                }else {
                    info.setFinishedTotal((int) vo2List.stream().filter(l->l.getIsYearFinished() == 1).count());
                    info.setUnFinishedTotal((int) vo2List.stream().filter(l->l.getIsYearFinished() == 0).count());
                }
                list.add(info);
            }
        }
        vo.setList(list);
        return vo;
    }

    @Override
    public String dataEndDate() {
        LocalDate date = baseMapper.dataEndDate();
        if (date == null){
            return "暂无填写记录";
        }else {
            return date.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日"));
        }
    }

    @Override
    @Transactional
    public void saveWarning(ProjectWarningDTO dto) {
        //删除之前配置
        baseMapper.deleteWarning();
        //保存现在配置
        List<ProjectWarning> list = dto.getList();
        warningService.saveBatch(list);
    }

    @Override
    public ProjectWarningDTO detailWarning() {
        ProjectWarningDTO dto = new ProjectWarningDTO();
        List<ProjectWarning> list = warningService.list();
        dto.setList(list);
        return dto;
    }

    @Override
    public void repealWarning(ProjectRepealDTO dto) {
        //判断是否已经撤销过
        RepealRecord one = repealRecordService.getOne(new LambdaQueryWrapper<RepealRecord>()
                .eq(RepealRecord::getProjectId, dto.getProjectId())
                .eq(RepealRecord::getPlanYear, dto.getPlanYear())
                .eq(RepealRecord::getPlanQuarter, dto.getQuarter())
                .eq(RepealRecord::getPlanType, dto.getWarningType())
        );
        if (one != null){
            throw new ServiceException("请勿重复撤销");
        }
        if (dto.getRepealEndDate().compareTo(LocalDate.now()) == -1){
            throw new ServiceException("结束日期不能小于今天");
        }
        RepealRecord record = new RepealRecord();
        record.setProjectId(dto.getProjectId());
        record.setPlanYear(dto.getPlanYear());
        record.setPlanQuarter(dto.getQuarter());
        record.setPlanType(dto.getWarningType());
        record.setStartDate(LocalDate.now());
        record.setEndDate(dto.getRepealEndDate());
        repealRecordService.save(record);

    }

    /**
     * 导入项目
     * @param file
     * @return
     */
    @Override
    @Transactional
    public R importProject(MultipartFile file) {
        /*解析excel*/
        List<ProjectImportExcel>  list = this.parseExcelFile(file);
        if (list.size() == 0){
            throw new ServiceException("excel中未发现数据，请检查后再导入");
        }
        for (ProjectImportExcel project : list) {
            //判断是新增项目还是修改项目
            if (project.getIsExist()){
                /*修改项目*/
                //查询出项目详情,用返回给前端的VO
                ProjectInfoDetailVO dto = this.detail(project.getProjectId());
                //修改指定几个项目信息
                dto.setBuildScale(project.getBuildScale());
                dto.setBuildScaleUnit(project.getBuildScaleUnit());
                dto.setAllInvestMoney(project.getAllInvestMoney());
                dto.setProjectType(project.getProjectType());
                dto.setProjectStage(project.getProjectStage());
                dto.setDutyUnit(project.getDutyUnit());
                dto.setIsPilotPlan(project.getIsPilotPlan());
                //修改指定年的计划信息
                Boolean isExist = false;
                for (ProjectInvestPlan plan : dto.getList()) {
                    if (plan.getPlanYear().equals(project.getPlanYear())){
                        isExist = true;
                        plan.setProjectId(project.getProjectId());
                        plan.setYearlyInvest(project.getYearlyInvest());
                        plan.setOneInvest(project.getOneInvest());
                        plan.setTwoInvest(project.getTwoInvest());
                        plan.setThreeInvest(project.getThreeInvest());
                        plan.setFourInvest(project.getFourInvest());
                        plan.setYearlyTarget(project.getYearlyTarget());
                        plan.setOnePlan(project.getOnePlan());
                        plan.setTwoPlan(project.getTwoPlan());
                        plan.setThreePlan(project.getThreePlan());
                        plan.setFourPlan(project.getFourPlan());
                        plan.setQuestionable(project.getQuestionable());
                        plan.setWorkAdvise(project.getWorkAdvise());
                        plan.setLinkman(project.getLinkman());
                        plan.setPhone(project.getPhone());
                    }
                }
                //如果当前年计划不存在，则创建当前年计划
                if (!isExist){
                    ProjectInvestPlan plan = new ProjectInvestPlan();
                    plan.setProjectId(project.getProjectId());
                    plan.setPlanYear(project.getPlanYear());
                    plan.setYearlyInvest(project.getYearlyInvest());
                    plan.setOneInvest(project.getOneInvest());
                    plan.setTwoInvest(project.getTwoInvest());
                    plan.setThreeInvest(project.getThreeInvest());
                    plan.setFourInvest(project.getFourInvest());
                    plan.setYearlyTarget(project.getYearlyTarget());
                    plan.setOnePlan(project.getOnePlan());
                    plan.setTwoPlan(project.getTwoPlan());
                    plan.setThreePlan(project.getThreePlan());
                    plan.setFourPlan(project.getFourPlan());
                    plan.setQuestionable(project.getQuestionable());
                    plan.setWorkAdvise(project.getWorkAdvise());
                    plan.setLinkman(project.getLinkman());
                    plan.setPhone(project.getPhone());
                    plan.setIsFillPlan(0);
                    dto.getList().add(plan);
                }
                //调用项目修改接口修改
                this.update2(dto);
            }else {
                /*新增项目*/
                //组装项目新增DTO，调用项目新增接口生成 项目信息与年信息
                ProjectInfoDTO infoDTO = new ProjectInfoDTO();
                BeanUtils.copyProperties(project,infoDTO);
                List<ProjectInvestPlan> plans = new ArrayList<>();
                //创建年数组
                for (int i = project.getStartYear(); i <= project.getEndYear(); i++) {
                    ProjectInvestPlan plan = new ProjectInvestPlan();
                    if (i == project.getPlanYear()) {
                        plan.setPlanYear(project.getPlanYear());
                        plan.setYearlyInvest(project.getYearlyInvest());
                        plan.setOneInvest(project.getOneInvest());
                        plan.setTwoInvest(project.getTwoInvest());
                        plan.setThreeInvest(project.getThreeInvest());
                        plan.setFourInvest(project.getFourInvest());
                        plan.setYearlyTarget(project.getYearlyTarget());
                        plan.setOnePlan(project.getOnePlan());
                        plan.setTwoPlan(project.getTwoPlan());
                        plan.setThreePlan(project.getThreePlan());
                        plan.setFourPlan(project.getFourPlan());
                        plan.setQuestionable(project.getQuestionable());
                        plan.setWorkAdvise(project.getWorkAdvise());
                        plan.setLinkman(project.getLinkman());
                        plan.setPhone(project.getPhone());
                    }else {
                        plan.setPlanYear(i);
                    }
                    plans.add(plan);
                }
                //计划年如果不在开工年完工年之间,单独放入
                if (project.getPlanYear() < project.getStartYear() || project.getPlanYear() > project.getEndYear()){
                    ProjectInvestPlan plan = new ProjectInvestPlan();
                    plan.setPlanYear(project.getPlanYear());
                    plan.setYearlyInvest(project.getYearlyInvest());
                    plan.setOneInvest(project.getOneInvest());
                    plan.setTwoInvest(project.getTwoInvest());
                    plan.setThreeInvest(project.getThreeInvest());
                    plan.setFourInvest(project.getFourInvest());
                    plan.setYearlyTarget(project.getYearlyTarget());
                    plan.setOnePlan(project.getOnePlan());
                    plan.setTwoPlan(project.getTwoPlan());
                    plan.setThreePlan(project.getThreePlan());
                    plan.setFourPlan(project.getFourPlan());
                    plan.setQuestionable(project.getQuestionable());
                    plan.setWorkAdvise(project.getWorkAdvise());
                    plan.setLinkman(project.getLinkman());
                    plan.setPhone(project.getPhone());
                    plans.add(plan);
                }
                infoDTO.setList(plans);
                project.setProjectId(this.add(infoDTO));
            }
            //是否存在完成数据，存在则组装月修改DTO,生成月信息和修改年信息
            if (project.getHasFinished()){
                //获取项目和详情
                ProjectAndPlanDetailVO vo = this.detail2(project.getProjectId());
                Map<Integer, ProjectInvestPlanVO> planVOMap = vo.getList().stream().collect(Collectors.toMap(l -> l.getPlanYear(), l -> l));
                Map<Integer, ProjectPlanProgressVO> map = planVOMap.get(project.getPlanYear()).getList().stream().collect(Collectors.toMap(l -> l.getPlanMonth(), l -> l));
                ProjectPlanProgressVO progressVO = map.get(project.getPlanMonth());
                progressVO.setInvestMoney(project.getInvestMoney());
                progressVO.setWorkProgress(project.getWorkProgress());
                progressVO.setWorkProgressAll(project.getWorkProgressAll());
                progressVO.setPlanRatio(project.getPlanRatio());
                //调用修改接口保存
                this.updateFinished(vo);
            }
        }
        long add = list.stream().filter(l -> !l.getIsExist()).count();
        long update = list.stream().filter(l -> l.getIsExist()).count();
        return R.success("导入成功：新增"+add+"个项目，修改"+update+"个项目");
    }

    @Override
    public ResponseEntity<FileSystemResource> buildReport(Integer year, Integer quarter, HttpServletResponse response) {
        //转换季度
        String[] quarterValue = {"","一","二","三","四",};
        String quarterZh = quarterValue[quarter];
        //文件地址
        String rootUrl = System.getProperty("user.dir")+ File.separator + "temporaryFile";
        String tempFile = rootUrl + File.separator + "季度报告模板.docx";
        System.out.println("模板地址："+tempFile);
        String fileName = year+"年"+quarterZh+"季度报告"+".docx";
        String fileOutUrl = rootUrl+File.separator+fileName;
        System.out.println(fileOutUrl);
        //项目类型值
        List<Integer> trafficType = Arrays.asList(1,2,3,4,7);
        List<Integer> houseType = Arrays.asList(5,6);
        String[] typeValue = {"","公路","铁路","水运","枢纽","城市轨道","城市道路","民航"};
        String[] typeValue2 = {"","（一）公路","（二）铁路","（三）水运","（四）枢纽","（五）城市轨道","（六）城市道路","（七）民航"};
        /** 投资计划情况*/
        //重大项目个数(当年所有项目)
        List<ProjectInvestPlanVO2> projectList = investPlanService.getYearAllProject(year);
        if (projectList.size() == 0){
            throw new ServiceException(year+"年没有投资计划");
        }
        int projectTotal = projectList.size();
        //计划总投资
        BigDecimal currentYearlyPlanInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getYearlyInvest()))
                .map(ProjectInvestPlan::getYearlyInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        if (currentYearlyPlanInvest.equals(BigDecimal.ZERO)){
            throw new ServiceException(year+"年没有投资计划，请重新选择时间");
        }
        //市交通运输委完成金额
        BigDecimal trafficMoney = projectList.stream().filter(l -> trafficType.contains(l.getProjectType()) && ObjectUtil.isNotEmpty(l.getYearFinishInvest()))
                .map(ProjectInvestPlan::getYearFinishInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        //铁路公路等项目个数
        long trafficTotal = projectList.stream().filter(l -> trafficType.contains(l.getProjectType())).count();
        //市住房城乡建委完成金额
        BigDecimal houseMoney = projectList.stream().filter(l -> houseType.contains(l.getProjectType()) && ObjectUtil.isNotEmpty(l.getYearFinishInvest()))
                .map(ProjectInvestPlan::getYearFinishInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        //城市轨道和城市项目个数
        long houseTotal = projectList.stream().filter(l -> houseType.contains(l.getProjectType())).count();
        //一季度计划完成投资
        BigDecimal oneInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getOneInvest()) && l.getOneInvest().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getOneInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        //二季度计划完成投资
        BigDecimal twoInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getTwoInvest()) && l.getTwoInvest().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getTwoInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        //三季度计划完成投资
        BigDecimal threeInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getThreeInvest()) && l.getThreeInvest().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getThreeInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        //四季度计划完成投资
        BigDecimal fourInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getFourInvest()) && l.getFourInvest().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getFourInvest).reduce(BigDecimal.ZERO, BigDecimal::add);


        /** 投资完成情况表*/
        //总计
        ReportVO1 vo1 = this.calculateTableOne(projectList.stream().filter(l -> ObjectUtil.isNotEmpty(l.getYearlyInvest()))
                        .collect(Collectors.toList()), quarter);
        Map<String,ReportVO1> reportVOMap1 = new HashMap<>();
        Map<String,ReportVO1> reportVOMap2 = new HashMap<>();
        //当前季度完成投资
        BigDecimal currentQuarterFinished = vo1.getQuarterFinishedInvest();
        //当前季度完成投资率
        BigDecimal currentQuarterFinishedRatio = vo1.getQuarterFinishedRatio();
        //前几季度累计完成投资金额
        BigDecimal frontQuarterFinished = vo1.getQuarterAddFinishedInvest();
        //占全年投资计划
        BigDecimal currentYearlyFinishedRatio = vo1.getQuarterAddRatioYearPlan();
        //市交通运输委
        List<ProjectInvestPlanVO2> traffics = projectList.stream().filter(l -> trafficType.contains(l.getProjectType()) && ObjectUtil.isNotEmpty(l.getYearlyInvest()))
                .collect(Collectors.toList());
        reportVOMap1.put("一、市交通运输委",this.calculateTableOne(traffics, quarter));
        for (Integer i : trafficType) {
            reportVOMap1.put(typeValue[i], this.calculateTableOne(traffics.stream().filter(l->l.getProjectType()==i).collect(Collectors.toList()), quarter));
        }
        //市住房城乡建委
        List<ProjectInvestPlanVO2> houses = projectList.stream().filter(l -> houseType.contains(l.getProjectType()) && ObjectUtil.isNotEmpty(l.getYearlyInvest()))
                .collect(Collectors.toList());
        reportVOMap2.put("二、市住房城乡建委",this.calculateTableOne(houses, quarter));
        for (Integer i : houseType) {
            reportVOMap2.put(typeValue[i], this.calculateTableOne(houses.stream().filter(l->l.getProjectType()==i).collect(Collectors.toList()), quarter));
        }
        Set<String> heads1 = reportVOMap1.keySet();
        Set<String> heads2 = reportVOMap2.keySet();
        /** 各板块完成情况*/
        //获取系统中配置的投资进展比例
        ProjectWarning projectWarning = warningService.getOne(new LambdaQueryWrapper<ProjectWarning>()
                .eq(ProjectWarning::getWarningType, 1));
        if (ObjectUtil.isEmpty(projectWarning)){
            throw new ServiceException("请先配置进展比例");
        }
        Map<String,ReportVO2> reportVO2Map = new HashMap<>();
        List<List<ReportVO3>> VO3listList = new ArrayList<>();
        for (int i = 1; i < typeValue2.length; i++) {
            int j = i;
            List<ProjectInvestPlanVO2> list = projectList.stream().filter(l -> l.getProjectType() == j).collect(Collectors.toList());
            //插值
            reportVO2Map.put(typeValue2[i], this.calculateTableProjectType(list, quarter));
            //表单
            VO3listList.add(this.calculateTableSeven(list,projectWarning));
        }
        Set<String> heads3 = reportVO2Map.keySet();
        /** 存在问题*/
        List<String> question = new ArrayList<>();
        List<ProjectInvestPlanVO2> questionList = projectList.stream().filter(l -> StringUtils.isNotBlank(l.getQuestionable())).collect(Collectors.toList());
        if (questionList.size() > 0){
            for (int i = 1; i <= questionList.size(); i++) {
                ProjectInvestPlanVO2 vo2 = questionList.get(i - 1);
                question.add(i+"."+vo2.getName()+"存在"+vo2.getQuestionable()+"问题。");
            }
        }
        /** 工作意见*/
        List<String> advice = new ArrayList<>();
        List<ProjectInvestPlanVO2> adviceList = projectList.stream().filter(l -> StringUtils.isNotBlank(l.getWorkAdvise())).collect(Collectors.toList());
        if (adviceList.size() > 0){
            for (int i = 1; i <= adviceList.size(); i++) {
                ProjectInvestPlanVO2 vo2 = adviceList.get(i - 1);
                advice.add(i+".建议"+vo2.getName()+vo2.getWorkAdvise()+"。");
            }
        }

        /** 读取模板文件*/
        File directory = new File(rootUrl);
        if (!directory.exists()) {
            // mkdirs()方法会创建多级目录，mkdir()只创建单级目录
            boolean created = directory.mkdirs();
            if (!created){
                throw new ServiceException("创建输出文件夹失败");
            }
        }
        File outFile = new File(fileOutUrl);  // 加载Word模板
        if (!outFile.exists()){
            try {
                boolean isCreate = outFile.createNewFile();
                if (!isCreate){
                    throw new ServiceException("创建输出文件失败");
                }
            } catch (IOException e) {
                throw new ServiceException("创建输出文件失败");
            }
        }
        try (
            FileInputStream file = new FileInputStream(tempFile);
            FileOutputStream outputStream = new FileOutputStream(outFile);
            XWPFDocument document = new XWPFDocument(file);
        ){
            /** 表单插值*/
            List<XWPFTable> tables = document.getTables();
            //单独处理第一张表单
            List<XWPFTableRow> tableRows = tables.get(0).getRows();
            List<XWPFTableCell> tableCellList = tableRows.get(0).getTableCells();
            XWPFRun xwpfRun = tableCellList.get(1).getParagraphs().get(0).getRuns().get(0);
            xwpfRun.setText(year+"",0);
            XWPFRun xwpfRun2 = tableCellList.get(2).getParagraphs().get(0).getRuns().get(0);
            xwpfRun2.setText(quarterZh,0);
            XWPFRun xwpfRun3 = tableCellList.get(3).getParagraphs().get(0).getRuns().get(1);
            xwpfRun3.setText(quarterZh,0);
            Integer tag = 0;
            for (XWPFTableRow row : tableRows) {
                List<XWPFTableCell> cells = row.getTableCells();
                String rowHead = cells.get(0).getText().replaceAll("\\s*", "");
                ReportVO1 rowData = null;
                if (rowHead.contains("一、市交通运输委")){
                    rowData = reportVOMap1.get("一、市交通运输委");
                    tag = 1;
                }else if (rowHead.contains("二、市住房城乡建委")){
                    rowData = reportVOMap1.get("二、市住房城乡建委");
                    tag = 2;
                }
                if (tag == 0 && "合计".equals(rowHead)){
                    rowData = vo1;
                }
                if (tag == 1 && heads1.contains(rowHead)){
                    rowData = reportVOMap1.get(rowHead);
                }
                if (tag == 2 && heads2.contains(rowHead)){
                    rowData = reportVOMap2.get(rowHead);
                }
                if (rowData != null) {
                    cells.get(1).getParagraphs().get(0).getRuns().get(0).setText(rowData.getYearProjectTotal() + "", 0);
                    cells.get(2).getParagraphs().get(0).getRuns().get(0).setText(rowData.getYearPlanInvest() + "", 0);
                    cells.get(3).getParagraphs().get(0).getRuns().get(0).setText(rowData.getQuarterPlanInvest() + "", 0);
                    cells.get(4).getParagraphs().get(0).getRuns().get(0).setText(rowData.getQuarterFinishedInvest() + "", 0);
                    cells.get(5).getParagraphs().get(0).getRuns().get(0).setText(rowData.getQuarterFinishedRatio() + "%", 0);
                    cells.get(6).getParagraphs().get(0).getRuns().get(0).setText(rowData.getQuarterCompare() + "", 0);
                    cells.get(7).getParagraphs().get(0).getRuns().get(0).setText(rowData.getQuarterAddFinishedInvest() + "", 0);
                    cells.get(8).getParagraphs().get(0).getRuns().get(0).setText(rowData.getQuarterAddRatioYearPlan() + "", 0);
                    cells.get(9).getParagraphs().get(0).getRuns().get(0).setText(rowData.getLeadOrLag() + "%", 0);
                }
            }
            //批量处理后面7张相同格式表单
            for (int i = 1; i < tables.size(); i++) {
                List<ReportVO3> vo3List = VO3listList.get(i - 1);
                XWPFTable table = tables.get(i);
                List<XWPFTableRow> rows = table.getRows();
                //小计
                ReportVO3 v1 = vo3List.get(0);
                List<XWPFTableCell> cells = rows.get(2).getTableCells();
                cells.get(1).getParagraphs().get(0).getRuns().get(0).setText(v1.getOneInvestRatio().toString()+"%" , 0);
                cells.get(2).getParagraphs().get(0).getRuns().get(0).setText(v1.getOneProjectTotal().toString()  , 0);
                cells.get(3).getParagraphs().get(0).getRuns().get(0).setText(v1.getTwoInvestRatio().toString() +"%", 0);
                cells.get(4).getParagraphs().get(0).getRuns().get(0).setText(v1.getTwoProjectTotal().toString() , 0);
                cells.get(5).getParagraphs().get(0).getRuns().get(0).setText(v1.getTwoAggregateRatio().toString() +"%", 0);
                cells.get(6).getParagraphs().get(0).getRuns().get(0).setText(v1.getThreeInvestRatio().toString() +"%", 0);
                cells.get(7).getParagraphs().get(0).getRuns().get(0).setText(v1.getThreeProjectTotal().toString() , 0);
                cells.get(8).getParagraphs().get(0).getRuns().get(0).setText(v1.getThreeAggregateRatio().toString() +"%", 0);
                cells.get(9).getParagraphs().get(0).getRuns().get(0).setText(v1.getFourInvestRatio().toString() +"%", 0);
                cells.get(10).getParagraphs().get(0).getRuns().get(0).setText(v1.getFourProjectTotal().toString() , 0);
                cells.get(11).getParagraphs().get(0).getRuns().get(0).setText(v1.getFourAggregateRatio().toString() +"%", 0);
                //正常
                v1 = vo3List.get(1);
                cells = rows.get(3).getTableCells();
                cells.get(2).getParagraphs().get(0).getRuns().get(0).setText(v1.getOneProjectTotal().toString()  , 0);
                cells.get(4).getParagraphs().get(0).getRuns().get(0).setText(v1.getTwoProjectTotal().toString() , 0);
                cells.get(7).getParagraphs().get(0).getRuns().get(0).setText(v1.getThreeProjectTotal().toString() , 0);
                cells.get(10).getParagraphs().get(0).getRuns().get(0).setText(v1.getFourProjectTotal().toString() , 0);
                //超前
                v1 = vo3List.get(2);
                cells = rows.get(4).getTableCells();
                cells.get(2).getParagraphs().get(0).getRuns().get(0).setText(v1.getOneProjectTotal().toString() , 0);
                cells.get(4).getParagraphs().get(0).getRuns().get(0).setText(v1.getTwoProjectTotal().toString() , 0);
                cells.get(7).getParagraphs().get(0).getRuns().get(0).setText(v1.getThreeProjectTotal().toString() , 0);
                cells.get(10).getParagraphs().get(0).getRuns().get(0).setText(v1.getFourProjectTotal().toString() , 0);
                //轻微滞后
                v1 = vo3List.get(3);
                cells = rows.get(5).getTableCells();
                cells.get(1).getParagraphs().get(0).getRuns().get(1).setText(v1.getOneInvestRatio().toString() , 0);
                cells.get(2).getParagraphs().get(0).getRuns().get(0).setText(v1.getOneProjectTotal().toString() , 0);
                cells.get(3).getParagraphs().get(0).getRuns().get(1).setText(v1.getTwoInvestRatio().toString() , 0);
                cells.get(4).getParagraphs().get(0).getRuns().get(0).setText(v1.getTwoProjectTotal().toString() , 0);
                cells.get(5).getParagraphs().get(0).getRuns().get(1).setText(v1.getTwoAggregateRatio().toString() , 0);
                cells.get(6).getParagraphs().get(0).getRuns().get(1).setText(v1.getThreeInvestRatio().toString() , 0);
                cells.get(7).getParagraphs().get(0).getRuns().get(0).setText(v1.getThreeProjectTotal().toString() , 0);
                cells.get(8).getParagraphs().get(0).getRuns().get(1).setText(v1.getThreeAggregateRatio().toString() , 0);
                cells.get(9).getParagraphs().get(0).getRuns().get(1).setText(v1.getFourInvestRatio().toString() , 0);
                cells.get(10).getParagraphs().get(0).getRuns().get(0).setText(v1.getFourProjectTotal().toString() , 0);
                cells.get(11).getParagraphs().get(0).getRuns().get(1).setText(v1.getFourAggregateRatio().toString() , 0);
                //中度滞后
                v1 = vo3List.get(4);
                cells = rows.get(6).getTableCells();
                cells.get(1).getParagraphs().get(0).getRuns().get(1).setText(v1.getOneInvestRatio().toString() , 0);
                cells.get(2).getParagraphs().get(0).getRuns().get(0).setText(v1.getOneProjectTotal().toString() , 0);
                cells.get(3).getParagraphs().get(0).getRuns().get(1).setText(v1.getTwoInvestRatio().toString() , 0);
                cells.get(4).getParagraphs().get(0).getRuns().get(0).setText(v1.getTwoProjectTotal().toString() , 0);
                cells.get(5).getParagraphs().get(0).getRuns().get(1).setText(v1.getTwoAggregateRatio().toString() , 0);
                cells.get(6).getParagraphs().get(0).getRuns().get(1).setText(v1.getThreeInvestRatio().toString() , 0);
                cells.get(7).getParagraphs().get(0).getRuns().get(0).setText(v1.getThreeProjectTotal().toString() , 0);
                cells.get(8).getParagraphs().get(0).getRuns().get(1).setText(v1.getThreeAggregateRatio().toString() , 0);
                cells.get(9).getParagraphs().get(0).getRuns().get(1).setText(v1.getFourInvestRatio().toString() , 0);
                cells.get(10).getParagraphs().get(0).getRuns().get(0).setText(v1.getFourProjectTotal().toString() , 0);
                cells.get(11).getParagraphs().get(0).getRuns().get(1).setText(v1.getFourAggregateRatio().toString() , 0);
                //严重滞后
                v1 = vo3List.get(5);
                cells = rows.get(7).getTableCells();
                cells.get(1).getParagraphs().get(0).getRuns().get(1).setText(v1.getOneInvestRatio().toString() , 0);
                cells.get(2).getParagraphs().get(0).getRuns().get(0).setText(v1.getOneProjectTotal().toString() , 0);
                cells.get(3).getParagraphs().get(0).getRuns().get(1).setText(v1.getTwoInvestRatio().toString() , 0);
                cells.get(4).getParagraphs().get(0).getRuns().get(0).setText(v1.getTwoProjectTotal().toString() , 0);
                cells.get(5).getParagraphs().get(0).getRuns().get(1).setText(v1.getTwoAggregateRatio().toString() , 0);
                cells.get(6).getParagraphs().get(0).getRuns().get(1).setText(v1.getThreeInvestRatio().toString() , 0);
                cells.get(7).getParagraphs().get(0).getRuns().get(0).setText(v1.getThreeProjectTotal().toString() , 0);
                cells.get(8).getParagraphs().get(0).getRuns().get(1).setText(v1.getThreeAggregateRatio().toString() , 0);
                cells.get(9).getParagraphs().get(0).getRuns().get(1).setText(v1.getFourInvestRatio().toString() , 0);
                cells.get(10).getParagraphs().get(0).getRuns().get(0).setText(v1.getFourProjectTotal().toString() , 0);
                cells.get(11).getParagraphs().get(0).getRuns().get(1).setText(v1.getFourAggregateRatio().toString() , 0);
            }

            /** 文本插值*/
            Integer status = 0;
            ReportVO2 vo2 = new ReportVO2();
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                String paragraphText = paragraph.getText();
                if ("投资完成情况表".equals(paragraphText)){
                    status = 1;
                }
                if ("存在问题".equals(paragraphText)){
                    status = 2;
                }
                if (status == 0) {
                    //paragraph为一个段落
                    List<XWPFRun> runs = paragraph.getRuns();
                    //runs为一个段落数据分词后集合
                    for (XWPFRun run : runs) {
                        String text = run.getText(0);
                        if (text != null && text.contains("${")) {
                            if (text.contains("${YEAR}")){
                                text = text.replace("${YEAR}", year + "");
                            } else if (text.contains("${QUARTERZH}")) {
                                text = text.replace("${QUARTERZH}", quarterZh);
                            } else if (text.contains("${PROJECTTOTAL}")) {
                                text = text.replace("${PROJECTTOTAL}", projectTotal + "");
                            } else if (text.contains("${CURRENTYEARLYPLANINVEST}")) {
                                text = text.replace("${CURRENTYEARLYPLANINVEST}", currentYearlyPlanInvest + "");
                            } else if (text.contains("${TRAFFICMONEY}")) {
                                text = text.replace("${TRAFFICMONEY}", trafficMoney + "");
                            } else if (text.contains("${TRAFFICTOTAL}")) {
                                text = text.replace("${TRAFFICTOTAL}", trafficTotal + "");
                            } else if (text.contains("${HOUSEMONEY}")) {
                                text = text.replace("${HOUSEMONEY}", houseMoney + "");
                            } else if (text.contains("${HOUSETOTAL}")) {
                                text = text.replace("${HOUSETOTAL}", houseTotal + "");
                            } else if (text.contains("${ONEINVEST}")) {
                                text = text.replace("${ONEINVEST}", oneInvest + "");
                            } else if (text.contains("${TWOINVEST}")) {
                                text = text.replace("${TWOINVEST}", twoInvest + "");
                            } else if (text.contains("${THREEINVEST}")) {
                                text = text.replace("${THREEINVEST}", threeInvest + "");
                            } else if (text.contains("${FOURINVEST}")) {
                                text = text.replace("${FOURINVEST}", fourInvest + "");
                            } else if (text.contains("${CURRENTQUARTERFINISHED}")) {
                                text = text.replace("${CURRENTQUARTERFINISHED}", currentQuarterFinished + "");
                            } else if (text.contains("${CURRENTQUARTERFINISHEDRATIO}")) {
                                text = text.replace("${CURRENTQUARTERFINISHEDRATIO}", currentQuarterFinishedRatio + "");
                            } else if (text.contains("${FRONTQUARTERFINISHED}")) {
                                text = text.replace("${FRONTQUARTERFINISHED}", frontQuarterFinished + "");
                            } else if (text.contains("${CURRENTYEARLYFINISHEDRATIO}")) {
                                text = text.replace("${CURRENTYEARLYFINISHEDRATIO}", currentYearlyFinishedRatio + "");
                            }
                            run.setText(text, 0);
                        }
                    }
                }else if (status == 1){
                    if (heads3.contains(paragraphText)){
                        vo2 = reportVO2Map.get(paragraphText);
                    }
                    List<XWPFRun> runs = paragraph.getRuns();
                    //runs为一个段落数据分词后集合
                    for (XWPFRun run : runs) {
                        String text = run.getText(0);
                        if (text != null && text.contains("${")) {
                            switch (text){
                                case "${QUARTERZH}":
                                    text = text.replace("${QUARTERZH}", quarterZh);
                                    break;
                                case "${QUARTERFINISHEDINVEST}":
                                    text = text.replace("${QUARTERFINISHEDINVEST}", vo2.getQuarterFinishedInvest().toString());
                                    break;
                                case "${QUARTERFINISHEDRATIO}":
                                    text = text.replace("${QUARTERFINISHEDRATIO}", vo2.getQuarterFinishedRatio().toString());
                                    break;
                                case "${QUARTERADDFINISHEDINVEST}":
                                    text = text.replace("${QUARTERADDFINISHEDINVEST}", vo2.getQuarterAddFinishedInvest().toString());
                                    break;
                                case "${QUARTERADDRATIOYEARPLAN}":
                                    text = text.replace("${QUARTERADDRATIOYEARPLAN}", vo2.getQuarterAddRatioYearPlan().toString());
                                    break;
                                case "${ADVANCEPROJECTTOTAL}":
                                    text = text.replace("${ADVANCEPROJECTTOTAL}", vo2.getAdvanceProjectTotal().toString());
                                    break;
                                case "${ADVANCEPROJECT}":
                                    text = text.replace("${ADVANCEPROJECT}", vo2.getAdvanceProject());
                                    break;
                                case "${LAGPROJECTTOTAL}":
                                    text = text.replace("${LAGPROJECTTOTAL}", vo2.getLagProjectTotal().toString());
                                    break;
                                case "${LAGPROJECT}":
                                    text = text.replace("${LAGPROJECT}", vo2.getLagProject());
                                    break;
                            }
                            run.setText(text, 0);
                        }
                    }
                }else if (status == 2){
                    //paragraph为一个段落
                    List<XWPFRun> runs = paragraph.getRuns();
                    //runs为一个段落数据分词后集合
                    for (XWPFRun run : runs) {
                        String text = run.getText(0);
                        if (text != null && text.contains("${")) {
                            if (text.contains("${QUESTION}")) {
                                if (question.size() > 0){
                                    for (int i = 0; i < question.size(); i++) {
                                        if (i == 0){
                                            run.setText(text.replace("${QUESTION}", question.get(0)),0);
                                        }else {
                                            run.setText("   "+question.get(i));
                                        }
                                        if (i != (question.size() - 1)){
                                            run.addBreak();
                                        }
                                    }
                                }else {
                                    run.setText(text.replace("${QUESTION}", ""),0);
                                }
                            } else if (text.contains("${ADVICE}")) {
                                if (advice.size() > 0){
                                    for (int i = 0; i < advice.size(); i++) {
                                        if (i == 0){
                                            run.setText(text.replace("${ADVICE}", advice.get(0)),0);
                                        }else {
                                            run.setText("   "+advice.get(i));
                                        }
                                        if (i != (advice.size() -1)) {
                                            run.addBreak();
                                        }
                                    }
                                }else {
                                    run.setText(text.replace("${ADVICE}", ""),0);
                                }
                            }
                        }
                    }
                }
            }
            /** 写入指定位置，上传并返回URL*/
            // 保存并关闭Word文件
            document.write(outputStream);
        } catch (Exception e) {
            throw new ServiceException("生成报告失败："+e.getMessage());
        }
        //返回响应


        try {
            FileSystemResource file = new FileSystemResource(fileOutUrl);
            fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
            return ResponseEntity.ok()
                    .headers(headers)
                    .contentLength(file.contentLength())
                    .contentType(MediaType.APPLICATION_OCTET_STREAM)
                    .body(file);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public R<List<Integer>> getProjectYear() {
        ProjectInfo info = baseMapper.getProjectYear();
        List<Integer> list = new ArrayList<>();
        for (int i = info.getStartYear(); i <= info.getEndYear(); i++) {
            list.add(i);
        }
        return R.data(list);
    }

    //计算项目7个类型的表单部分
    private List<ReportVO3> calculateTableSeven(List<ProjectInvestPlanVO2> projectList,ProjectWarning projectWarning) {
        BigDecimal oneHundred = new BigDecimal(100);
        List<ReportVO3> list = new ArrayList<>();
        /** 计划投资*/
        //一季度计划完成投资
        BigDecimal oneInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getOneInvest()) && l.getOneInvest().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getOneInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        //二季度计划完成投资
        BigDecimal twoInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getTwoInvest()) && l.getTwoInvest().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getTwoInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        //三季度计划完成投资
        BigDecimal threeInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getThreeInvest()) && l.getThreeInvest().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getThreeInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        //四季度计划完成投资
        BigDecimal fourInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getFourInvest()) && l.getFourInvest().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getFourInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        /** 投资完成*/
        //一季度完成投资
        BigDecimal oneInvestFinish = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getOneInvestFinish()) && l.getOneInvestFinish().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getOneInvestFinish).reduce(BigDecimal.ZERO, BigDecimal::add);
        //二季度完成投资
        BigDecimal twoInvestFinish = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getTwoInvestFinish()) && l.getTwoInvestFinish().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getTwoInvestFinish).reduce(BigDecimal.ZERO, BigDecimal::add);
        //三季度完成投资
        BigDecimal threeInvestFinish = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getThreeInvestFinish()) && l.getThreeInvestFinish().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getThreeInvestFinish).reduce(BigDecimal.ZERO, BigDecimal::add);
        //四季度完成投资
        BigDecimal fourInvestFinish = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getFourInvestFinish()) && l.getFourInvestFinish().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getFourInvestFinish).reduce(BigDecimal.ZERO, BigDecimal::add);

        //二季度累计计划投资
        BigDecimal twoAddInvest = oneInvest.add(twoInvest);
        //三季度累计计划投资
        BigDecimal threeAddInvest = twoAddInvest.add(threeInvest);
        //全年累计计划投资
        BigDecimal fourAddInvest = threeAddInvest.add(fourInvest);

        //二季度累计投资
        BigDecimal twoAddInvestFinish = oneInvestFinish.add(twoInvestFinish);
        //三季度累计投资
        BigDecimal threeAddInvestFinish = twoAddInvestFinish.add(threeInvestFinish);
        //全年累计投资
        BigDecimal fourAddInvestFinish = threeAddInvestFinish.add(fourInvestFinish);

        //小计
        ReportVO3 v1 = new ReportVO3();
        v1.setOneInvestRatio(oneInvest.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : oneInvestFinish.multiply(
                new BigDecimal(100)).divide(oneInvest,2,RoundingMode.HALF_UP));
        v1.setOneProjectTotal((int) projectList.stream().filter(l->l.getIsOneInvestFinish() == 1).count());
        v1.setTwoInvestRatio(twoInvest.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : twoInvestFinish.multiply(
                new BigDecimal(100)).divide(twoInvest,2,RoundingMode.HALF_UP));
        v1.setTwoProjectTotal((int) projectList.stream().filter(l->l.getIsTwoInvestFinish() == 1).count());
        v1.setTwoAggregateRatio(twoAddInvest.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : twoAddInvestFinish.multiply(
                new BigDecimal(100)).divide(twoAddInvest,2,RoundingMode.HALF_UP));
        v1.setThreeInvestRatio(threeInvest.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : threeInvestFinish.multiply(
                new BigDecimal(100)).divide(threeInvest,2,RoundingMode.HALF_UP));
        v1.setThreeProjectTotal((int) projectList.stream().filter(l->l.getIsThreeInvestFinish() == 1).count());
        v1.setThreeAggregateRatio(threeAddInvest.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : threeAddInvestFinish.multiply(
                new BigDecimal(100)).divide(threeAddInvest,2,RoundingMode.HALF_UP));
        v1.setFourInvestRatio(fourInvest.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : fourInvestFinish.multiply(
                new BigDecimal(100)).divide(fourInvest,2,RoundingMode.HALF_UP));
        v1.setFourProjectTotal((int) projectList.stream().filter(l->l.getIsFourInvestFinish() == 1).count());
        v1.setFourAggregateRatio(fourAddInvest.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ZERO : fourAddInvestFinish.multiply(
                new BigDecimal(100)).divide(fourAddInvest,2,RoundingMode.HALF_UP));
        list.add(v1);
        //正常
        ReportVO3 v2 = new ReportVO3();
        v2.setOneProjectTotal((int) projectList.stream().filter(l->l.getIsOneInvestFinish() == 1 &&
                l.getOneInvestRatio().compareTo(oneHundred) == 0).count());
        v2.setTwoProjectTotal((int) projectList.stream().filter(l->l.getIsTwoInvestFinish() == 1 &&
                l.getTwoInvestRatio().compareTo(oneHundred) == 0 && l.getTwoAggregateRatio().compareTo(oneHundred) == 0).count());
        v2.setThreeProjectTotal((int) projectList.stream().filter(l->l.getIsThreeInvestFinish() == 1 &&
                l.getThreeInvestRatio().compareTo(oneHundred) == 0 && l.getThreeAggregateRatio().compareTo(oneHundred) == 0).count());
        v2.setFourProjectTotal((int) projectList.stream().filter(l->l.getIsFourInvestFinish() == 1 &&
                l.getFourInvestRatio().compareTo(oneHundred) == 0 && l.getFourAggregateRatio().compareTo(oneHundred) == 0).count());
        list.add(v2);
        //超前
        ReportVO3 v3 = new ReportVO3();
        v3.setOneProjectTotal((int) projectList.stream().filter(l->l.getIsOneInvestFinish() == 1 &&
                l.getOneInvestRatio().compareTo(oneHundred) > 0).count());
        v3.setTwoProjectTotal((int) projectList.stream().filter(l->l.getIsTwoInvestFinish() == 1 &&
                l.getTwoInvestRatio().compareTo(oneHundred) > 0 && l.getTwoAggregateRatio().compareTo(oneHundred)  > 0).count());
        v3.setThreeProjectTotal((int) projectList.stream().filter(l->l.getIsThreeInvestFinish() == 1 &&
                l.getThreeInvestRatio().compareTo(oneHundred) > 0 && l.getThreeAggregateRatio().compareTo(oneHundred)  > 0).count());
        v3.setFourProjectTotal((int) projectList.stream().filter(l->l.getIsFourInvestFinish() == 1 &&
                l.getFourInvestRatio().compareTo(oneHundred) > 0 && l.getFourAggregateRatio().compareTo(oneHundred)  > 0).count());
        list.add(v3);

        //过滤每个季度已经统计过的
        List<Long> oneIds = new ArrayList<>();
        List<Long> twoIds = new ArrayList<>();
        List<Long> threeIds = new ArrayList<>();
        List<Long> fourIds = new ArrayList<>();
        List<Long> one = new ArrayList<>();
        List<Long> two = new ArrayList<>();
        List<Long> three = new ArrayList<>();
        List<Long> four = new ArrayList<>();
        //严重滞后
        ReportVO3 v6 = new ReportVO3();
        v6.setOneInvestRatio(projectWarning.getOneOne());
        one = projectList.stream().filter(l -> l.getIsOneInvestFinish() == 1
                && l.getOneInvestRatio().compareTo(projectWarning.getOneOne()) < 0).map(ProjectInvestPlanVO2::getId).collect(Collectors.toList());
        v6.setOneProjectTotal(one.size());
        v6.setTwoInvestRatio(projectWarning.getTwoOne());
        two = projectList.stream().filter(l->l.getIsTwoInvestFinish() == 1
                && (l.getTwoInvestRatio().compareTo(projectWarning.getTwoOne()) < 0 || l.getTwoAggregateRatio().compareTo(projectWarning.getTwoOneAll()) < 0))
                .map(ProjectInvestPlanVO2::getId).collect(Collectors.toList());
        v6.setTwoProjectTotal(two.size());
        v6.setTwoAggregateRatio(projectWarning.getTwoOneAll());
        v6.setThreeInvestRatio(projectWarning.getThreeOne());
        three = projectList.stream().filter(l->l.getIsThreeInvestFinish() == 1
                && (l.getThreeInvestRatio().compareTo(projectWarning.getThreeOne()) < 0 || l.getThreeAggregateRatio().compareTo(projectWarning.getThreeOneAll()) < 0))
                .map(ProjectInvestPlanVO2::getId).collect(Collectors.toList());
        v6.setThreeProjectTotal(three.size());
        v6.setThreeAggregateRatio(projectWarning.getThreeOneAll());
        v6.setFourInvestRatio(projectWarning.getFourOne());
        four = projectList.stream().filter(l->l.getIsFourInvestFinish() == 1
                && (l.getFourInvestRatio().compareTo(projectWarning.getFourOne()) < 0 || l.getFourAggregateRatio().compareTo(projectWarning.getFourOneAll()) < 0))
                .map(ProjectInvestPlanVO2::getId).collect(Collectors.toList());
        v6.setFourProjectTotal(four.size());
        v6.setFourAggregateRatio(projectWarning.getFourOneAll());


        oneIds.addAll(one);
        twoIds.addAll(two);
        threeIds.addAll(three);
        fourIds.addAll(four);

        //中度滞后
        ReportVO3 v5 = new ReportVO3();
        v5.setOneInvestRatio(projectWarning.getOneTwo());
        one = projectList.stream().filter(l->l.getIsOneInvestFinish() == 1 && !oneIds.contains(l.getId())
                && (l.getOneInvestRatio().compareTo(projectWarning.getOneOne()) > 0 && l.getOneInvestRatio().compareTo(projectWarning.getOneTwo()) < 0))
                .map(ProjectInvestPlanVO2::getId).collect(Collectors.toList());
        v5.setOneProjectTotal(one.size());
        v5.setTwoInvestRatio(projectWarning.getTwoTwo());
        two = projectList.stream().filter(l->l.getIsTwoInvestFinish() == 1 && !twoIds.contains(l.getId())
                && ((l.getTwoInvestRatio().compareTo(projectWarning.getTwoOne()) > 0 && l.getTwoInvestRatio().compareTo(projectWarning.getTwoTwo()) < 0)
                || (l.getTwoAggregateRatio().compareTo(projectWarning.getTwoOneAll()) > 0 && l.getTwoAggregateRatio().compareTo(projectWarning.getTwoTwoAll()) < 0)))
                .map(ProjectInvestPlanVO2::getId).collect(Collectors.toList());
        v5.setTwoProjectTotal(two.size());
        v5.setTwoAggregateRatio(projectWarning.getTwoTwoAll());
        v5.setThreeInvestRatio(projectWarning.getThreeTwo());
        three = projectList.stream().filter(l->l.getIsThreeInvestFinish() == 1 && !threeIds.contains(l.getId())
                && ((l.getThreeInvestRatio().compareTo(projectWarning.getThreeOne()) > 0 && l.getThreeInvestRatio().compareTo(projectWarning.getThreeTwo()) < 0)
                        || (l.getThreeAggregateRatio().compareTo(projectWarning.getThreeOneAll()) > 0 && l.getThreeAggregateRatio().compareTo(projectWarning.getThreeTwoAll()) < 0)))
                .map(ProjectInvestPlanVO2::getId).collect(Collectors.toList());
        v5.setThreeProjectTotal(three.size());
        v5.setThreeAggregateRatio(projectWarning.getThreeTwoAll());
        v5.setFourInvestRatio(projectWarning.getFourTwo());
        four = projectList.stream().filter(l->l.getIsFourInvestFinish() == 1 && !fourIds.contains(l.getId())
                && ((l.getFourInvestRatio().compareTo(projectWarning.getFourOne()) > 0 && l.getFourInvestRatio().compareTo(projectWarning.getFourTwo()) < 0)
                || (l.getFourAggregateRatio().compareTo(projectWarning.getFourOneAll()) > 0 && l.getFourAggregateRatio().compareTo(projectWarning.getFourTwoAll()) < 0)))
                .map(ProjectInvestPlanVO2::getId).collect(Collectors.toList());
        v5.setFourProjectTotal(four.size());
        v5.setFourAggregateRatio(projectWarning.getFourTwoAll());

        oneIds.addAll(one);
        twoIds.addAll(two);
        threeIds.addAll(three);
        fourIds.addAll(four);

        //轻微滞后
        ReportVO3 v4 = new ReportVO3();
        v4.setOneInvestRatio(projectWarning.getOneThree());
        v4.setOneProjectTotal((int) projectList.stream().filter(l->l.getIsOneInvestFinish() == 1 && !oneIds.contains(l.getId())
                && l.getOneInvestRatio().compareTo(projectWarning.getOneTwo()) > 0 && l.getOneInvestRatio().compareTo(projectWarning.getOneThree()) < 0).count());
        v4.setTwoInvestRatio(projectWarning.getTwoThree());
        v4.setTwoProjectTotal((int) projectList.stream().filter(l->l.getIsTwoInvestFinish() == 1 && !twoIds.contains(l.getId())
                && ((l.getTwoInvestRatio().compareTo(projectWarning.getTwoTwo()) > 0 && l.getTwoInvestRatio().compareTo(projectWarning.getTwoThree()) < 0)
                || (l.getTwoAggregateRatio().compareTo(projectWarning.getTwoTwoAll()) > 0 && l.getTwoAggregateRatio().compareTo(projectWarning.getTwoThreeAll()) < 0))).count());
        v4.setTwoAggregateRatio(projectWarning.getTwoThreeAll());
        v4.setThreeInvestRatio(projectWarning.getThreeThree());
        v4.setThreeProjectTotal((int) projectList.stream().filter(l->l.getIsThreeInvestFinish() == 1 && !threeIds.contains(l.getId())
                && ((l.getThreeInvestRatio().compareTo(projectWarning.getThreeTwo()) > 0 && l.getThreeInvestRatio().compareTo(projectWarning.getThreeThree()) < 0)
                || (l.getTwoAggregateRatio().compareTo(projectWarning.getThreeTwoAll()) > 0 && l.getTwoAggregateRatio().compareTo(projectWarning.getThreeThreeAll()) < 0))).count());
        v4.setThreeAggregateRatio(projectWarning.getThreeThreeAll());
        v4.setFourInvestRatio(projectWarning.getFourThree());
        v4.setFourProjectTotal((int) projectList.stream().filter(l->l.getIsFourInvestFinish() == 1 && !fourIds.contains(l.getId())
                && ((l.getFourInvestRatio().compareTo(projectWarning.getFourTwo()) > 0 && l.getFourInvestRatio().compareTo(projectWarning.getFourThree()) < 0)
                || (l.getTwoAggregateRatio().compareTo(projectWarning.getFourTwoAll()) > 0 && l.getTwoAggregateRatio().compareTo(projectWarning.getFourThreeAll()) < 0))).count());
        v4.setFourAggregateRatio(projectWarning.getFourThreeAll());
        list.add(v4);
        list.add(v5);
        list.add(v6);

        return list;
    }

    //计算项目7个类型的插值部分
    private ReportVO2 calculateTableProjectType(List<ProjectInvestPlanVO2> projectList,Integer quarter) {
        ReportVO2 vo2 = new ReportVO2();
        if (projectList.size() == 0){
            return vo2;
        }
        BigDecimal currentYearlyPlanInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getYearlyInvest()))
                .map(ProjectInvestPlan::getYearlyInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        /** 计划投资*/
        //一季度计划完成投资
        BigDecimal oneInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getOneInvest()) && l.getOneInvest().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getOneInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        //二季度计划完成投资
        BigDecimal twoInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getTwoInvest()) && l.getTwoInvest().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getTwoInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        //三季度计划完成投资
        BigDecimal threeInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getThreeInvest()) && l.getThreeInvest().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getThreeInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        //四季度计划完成投资
        BigDecimal fourInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getFourInvest()) && l.getFourInvest().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getFourInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        /** 投资完成*/
        //一季度完成投资
        BigDecimal oneInvestFinish = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getOneInvestFinish()) && l.getOneInvestFinish().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getOneInvestFinish).reduce(BigDecimal.ZERO, BigDecimal::add);
        //二季度完成投资
        BigDecimal twoInvestFinish = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getTwoInvestFinish()) && l.getTwoInvestFinish().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getTwoInvestFinish).reduce(BigDecimal.ZERO, BigDecimal::add);
        //三季度完成投资
        BigDecimal threeInvestFinish = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getThreeInvestFinish()) && l.getThreeInvestFinish().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getThreeInvestFinish).reduce(BigDecimal.ZERO, BigDecimal::add);
        //四季度完成投资
        BigDecimal fourInvestFinish = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getFourInvestFinish()) && l.getFourInvestFinish().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getFourInvestFinish).reduce(BigDecimal.ZERO, BigDecimal::add);
        //当前季度完成投资
        BigDecimal currentQuarterFinished = BigDecimal.ZERO;
        //当前季度计划完成投资(实际为上面一到四季度的某个季度)
        BigDecimal currentQuarterPlanInvest = BigDecimal.ZERO;
        //当前季度完成投资率
        BigDecimal currentQuarterFinishedRatio = BigDecimal.ZERO;
        //前几季度累计完成投资金额
        BigDecimal frontQuarterFinished = BigDecimal.ZERO;
        //占全年投资计划
        BigDecimal currentYearlyFinishedRatio = BigDecimal.ZERO;
        //超前项目
        List<ProjectInvestPlanVO2> advanceProjects = new ArrayList<>();
        //滞后项目
        List<ProjectInvestPlanVO2> lagProjects = new ArrayList<>();
        switch (quarter){
            case 1 : currentQuarterFinished = oneInvestFinish;
                frontQuarterFinished = oneInvestFinish;
                currentQuarterPlanInvest = oneInvest;
                advanceProjects = projectList.stream().filter(l->l.getIsOneInvestFinish() == 1 && l.getOneInvestRatio().compareTo(new BigDecimal(100)) > 0)
                        .collect(Collectors.toList());
                lagProjects = projectList.stream().filter(l->l.getIsOneInvestFinish() == 1 && l.getOneInvestRatio().compareTo(new BigDecimal(100)) < 0)
                        .collect(Collectors.toList());
                break;
            case 2 : currentQuarterFinished = twoInvestFinish;
                frontQuarterFinished = oneInvestFinish.add(twoInvestFinish);
                currentQuarterPlanInvest = twoInvest;
                advanceProjects = projectList.stream().filter(l->l.getIsTwoInvestFinish() == 1 && l.getTwoAggregateRatio().compareTo(new BigDecimal(100)) > 0)
                        .collect(Collectors.toList());
                lagProjects = projectList.stream().filter(l->l.getIsTwoInvestFinish() == 1 && l.getTwoAggregateRatio().compareTo(new BigDecimal(100)) < 0)
                        .collect(Collectors.toList());
                break;
            case 3 : currentQuarterFinished = threeInvestFinish;
                frontQuarterFinished = oneInvestFinish.add(threeInvestFinish).add(twoInvestFinish);
                currentQuarterPlanInvest = threeInvest;
                advanceProjects = projectList.stream().filter(l->l.getIsThreeInvestFinish() == 1 && l.getThreeAggregateRatio().compareTo(new BigDecimal(100)) > 0)
                        .collect(Collectors.toList());
                lagProjects = projectList.stream().filter(l->l.getIsThreeInvestFinish() == 1 && l.getThreeAggregateRatio().compareTo(new BigDecimal(100)) < 0)
                        .collect(Collectors.toList());
                break;
            case 4 : currentQuarterFinished = fourInvestFinish;
                frontQuarterFinished = oneInvestFinish.add(twoInvestFinish).add(threeInvestFinish).add(fourInvestFinish);
                currentQuarterPlanInvest = fourInvest;
                advanceProjects = projectList.stream().filter(l->l.getIsFourInvestFinish() == 1 && l.getFourAggregateRatio().compareTo(new BigDecimal(100)) > 0)
                        .collect(Collectors.toList());
                lagProjects = projectList.stream().filter(l->l.getIsFourInvestFinish() == 1 && l.getFourAggregateRatio().compareTo(new BigDecimal(100)) < 0)
                        .collect(Collectors.toList());
                break;
            default : throw new ServiceException("季度不在规定范围内");
        }

        if (currentQuarterFinished.compareTo(BigDecimal.ZERO) > 0){
            currentQuarterFinishedRatio = currentQuarterFinished.multiply(new BigDecimal(100))
                    .divide(currentQuarterPlanInvest,2, RoundingMode.HALF_UP);
        }
        if (frontQuarterFinished.compareTo(BigDecimal.ZERO) > 0){
            currentYearlyFinishedRatio = frontQuarterFinished.multiply(new BigDecimal(100))
                    .divide(currentYearlyPlanInvest,2, RoundingMode.HALF_UP);
        }
        //季度完成投资
        vo2.setQuarterFinishedInvest(currentQuarterFinished);
        //季度完成率
        vo2.setQuarterFinishedRatio(currentQuarterFinishedRatio);
        //前季度累计完成
        vo2.setQuarterAddFinishedInvest(frontQuarterFinished);
        //前季度累计完成占全年
        vo2.setQuarterAddRatioYearPlan(currentYearlyFinishedRatio);
        //多少个项目投资进度超前
        //超前项目分别是
        if (advanceProjects.size() > 0){
            vo2.setAdvanceProjectTotal(advanceProjects.size());
            vo2.setAdvanceProject(advanceProjects.stream().map(l->l.getName()).collect(Collectors.joining(",")));
        }
        //多少个项目投资进度滞后
        //滞后项目分别是
        if (lagProjects.size() > 0){
            vo2.setLagProjectTotal(lagProjects.size());
            vo2.setLagProject(lagProjects.stream().map(l->l.getName()).collect(Collectors.joining(",")));
        }

        return vo2;
    }

    private ReportVO1 calculateTableOne(List<ProjectInvestPlanVO2> projectList,Integer quarter) {
        if (projectList.size() == 0){
            return null;
        }
        ReportVO1 vo1 = new ReportVO1();
        BigDecimal currentYearlyPlanInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getYearlyInvest()))
                .map(ProjectInvestPlan::getYearlyInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        /** 计划投资*/
        //一季度计划完成投资
        BigDecimal oneInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getOneInvest()) && l.getOneInvest().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getOneInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        //二季度计划完成投资
        BigDecimal twoInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getTwoInvest()) && l.getTwoInvest().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getTwoInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        //三季度计划完成投资
        BigDecimal threeInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getThreeInvest()) && l.getThreeInvest().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getThreeInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        //四季度计划完成投资
        BigDecimal fourInvest = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getFourInvest()) && l.getFourInvest().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getFourInvest).reduce(BigDecimal.ZERO, BigDecimal::add);
        /** 投资完成*/
        //一季度完成投资
        BigDecimal oneInvestFinish = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getOneInvestFinish()) && l.getOneInvestFinish().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getOneInvestFinish).reduce(BigDecimal.ZERO, BigDecimal::add);
        //二季度完成投资
        BigDecimal twoInvestFinish = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getTwoInvestFinish()) && l.getTwoInvestFinish().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getTwoInvestFinish).reduce(BigDecimal.ZERO, BigDecimal::add);
        //三季度完成投资
        BigDecimal threeInvestFinish = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getThreeInvestFinish()) && l.getThreeInvestFinish().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getThreeInvestFinish).reduce(BigDecimal.ZERO, BigDecimal::add);
        //四季度完成投资
        BigDecimal fourInvestFinish = projectList.stream().filter(l-> ObjectUtil.isNotEmpty(l.getFourInvestFinish()) && l.getFourInvestFinish().compareTo(BigDecimal.ZERO) != 0)
                .map(ProjectInvestPlan::getFourInvestFinish).reduce(BigDecimal.ZERO, BigDecimal::add);
        //当前季度完成投资
        BigDecimal currentQuarterFinished = BigDecimal.ZERO;
        //当前季度上一个季度完成投资（当第一季度时，则为0）
        BigDecimal currentLastQuarterFinished = BigDecimal.ZERO;
        //当前季度计划完成投资(实际为上面一到四季度的某个季度)
        BigDecimal currentQuarterPlanInvest = BigDecimal.ZERO;
        //当前季度完成投资率
        BigDecimal currentQuarterFinishedRatio = BigDecimal.ZERO;
        //前几季度累计计划投资金额
        BigDecimal frontQuarterPlanInvest = BigDecimal.ZERO;
        //前几季度累计完成投资金额
        BigDecimal frontQuarterFinished = BigDecimal.ZERO;
        //占全年投资计划
        BigDecimal currentYearlyFinishedRatio = BigDecimal.ZERO;

        switch (quarter){
            case 1 : currentQuarterFinished = oneInvestFinish;
                frontQuarterFinished = oneInvestFinish;
                currentQuarterPlanInvest = oneInvest;
                frontQuarterPlanInvest = oneInvest;
                break;
            case 2 : currentQuarterFinished = twoInvestFinish;
                currentLastQuarterFinished = oneInvestFinish;
                frontQuarterFinished = oneInvestFinish.add(twoInvestFinish);
                currentQuarterPlanInvest = twoInvest;
                frontQuarterPlanInvest = oneInvest.add(twoInvest);
                break;
            case 3 : currentQuarterFinished = threeInvestFinish;
                currentLastQuarterFinished = twoInvestFinish;
                frontQuarterFinished = oneInvestFinish.add(threeInvestFinish).add(twoInvestFinish);
                currentQuarterPlanInvest = threeInvest;
                frontQuarterPlanInvest = oneInvest.add(twoInvest).add(threeInvest);
                break;
            case 4 : currentQuarterFinished = fourInvestFinish;
                currentLastQuarterFinished = threeInvestFinish;
                frontQuarterFinished = oneInvestFinish.add(twoInvestFinish).add(threeInvestFinish).add(fourInvestFinish);
                currentQuarterPlanInvest = fourInvest;
                frontQuarterPlanInvest = threeInvest.add(oneInvest).add(twoInvest).add(fourInvest);
                break;
            default : throw new ServiceException("季度不在规定范围内");
        }

        if (currentQuarterFinished.compareTo(BigDecimal.ZERO) > 0){
            currentQuarterFinishedRatio = currentQuarterFinished.multiply(new BigDecimal(100))
                    .divide(currentQuarterPlanInvest,2, RoundingMode.HALF_UP);
        }
        if (frontQuarterFinished.compareTo(BigDecimal.ZERO) > 0){
            currentYearlyFinishedRatio = frontQuarterFinished.multiply(new BigDecimal(100))
                    .divide(currentYearlyPlanInvest,2, RoundingMode.HALF_UP);
        }
        //年
        vo1.setYearProjectTotal(projectList.size());
        vo1.setYearPlanInvest(currentYearlyPlanInvest);
        //季度
        vo1.setQuarterPlanInvest(currentQuarterPlanInvest);
        vo1.setQuarterFinishedInvest(currentQuarterFinished);
        //环比
        if (currentLastQuarterFinished.compareTo(BigDecimal.ZERO) == 0 || currentQuarterFinished.compareTo(BigDecimal.ZERO) == 0){
            vo1.setQuarterCompare(BigDecimal.ZERO);
        }else {
            vo1.setQuarterCompare( currentQuarterFinished
                            .divide(currentLastQuarterFinished,2, RoundingMode.HALF_UP));
        }
        vo1.setQuarterFinishedRatio(currentQuarterFinishedRatio);
        vo1.setQuarterAddFinishedInvest(frontQuarterFinished);
        vo1.setQuarterAddRatioYearPlan(currentYearlyFinishedRatio);
        //超前或滞后
        if (frontQuarterPlanInvest.compareTo(BigDecimal.ZERO) == 0) {
            vo1.setLeadOrLag(BigDecimal.ZERO);
        }else {
            if (frontQuarterPlanInvest.compareTo(frontQuarterFinished) == 0){
                vo1.setLeadOrLag(new BigDecimal(0));
            }else {
                vo1.setLeadOrLag(frontQuarterFinished.subtract(frontQuarterPlanInvest).multiply(new BigDecimal(100)).divide(frontQuarterPlanInvest,2,RoundingMode.HALF_UP));
            }
        }
        return vo1;
    }

    /**
     * 按照Map解析出指定格式的集合
     * @param file
     * @return
     */
    private List<ProjectImportExcel> parseExcelFile(MultipartFile file) {
        //获取项目类型，项目进展类型，并转换为map
        Map<String, Integer> typeMap = dictBizService.getList("projectType").stream().collect(Collectors.toMap(l -> l.getDictValue(), l -> Integer.valueOf(l.getDictKey())));
        Map<String, Integer> stageMap = dictBizService.getList("projectStage").stream().collect(Collectors.toMap(l -> l.getDictValue(), l -> Integer.valueOf(l.getDictKey())));
        if (typeMap.size() == 0 || stageMap.size() == 0){
            throw new ServiceException("请先设置项目类型和项目进展类型后再导入");
        }
        //获取当前已有项目，转换为：项目名称->项目信息
        Map<String, ProjectInfo> projectMap = this.list().stream().collect(Collectors.toMap(l -> l.getName(), l -> l));
        //解析Excel
        List<ProjectImportExcel> list = new ArrayList<>();
        try (InputStream inputStream = file.getInputStream()) {
            Workbook workbook;
            if (Objects.requireNonNull(file.getOriginalFilename()).toLowerCase().endsWith(".xls")) {
                workbook = new HSSFWorkbook(inputStream);
            } else if (file.getOriginalFilename().toLowerCase().endsWith(".xlsx")) {
                workbook = new XSSFWorkbook(inputStream);
            } else {
                throw new ServiceException("解析Excel失败");
            }
            //获取第一个sheet
            Sheet sheet = workbook.getSheetAt(0);
            //获取总行数
            int rows = sheet.getPhysicalNumberOfRows();
            //获取第二行名称，然后解析出项目类型,年月
            Row row2 = sheet.getRow(1);
            String title = row2.getCell(0, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();
            if (StringUtils.isBlank(title)){
                throw new ServiceException("未获取到标题，请检查Excel格式");
            }
            String pattern = "\\d{4}年\\d{1,2}月";
            Pattern regex = Pattern.compile(pattern);
            Matcher matcher = regex.matcher(title);
            int year,month;
            if (matcher.find()){
                String yearMonth = matcher.group();
                year = Integer.parseInt(yearMonth.substring(0,4));
                month = Integer.parseInt(yearMonth.substring(5,yearMonth.length()-1));
            }else {
                throw new ServiceException("标题中未获取到年月");
            }
            if (year > LocalDate.now().getYear()){
                throw new ServiceException("标题年份不能大于今年");
            }
            if (month < 0 || month > 12){
                throw new ServiceException("标题月份必须在1-12之间");
            }
            Integer projectType;
            Integer projectStage = 0;
            if (title.contains("重")){
                String name = title.substring(title.lastIndexOf("月") + 1, title.lastIndexOf("重"));
                Integer type = typeMap.get(name);
                if (type == null){
                    throw new ServiceException("未获取到项目类型："+name);
                }else {
                    projectType = type;
                }
            }else {
                throw new ServiceException("标题格式错误，无法获取项目类型");
            }
            //从第四行重获取建设规模
            Row row4 = sheet.getRow(2);
            String buildS = row4.getCell(2, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();
            int buildScaleUnit = 2;
            if (buildS.contains("公里")){
                buildScaleUnit = 1;
            }
            DataFormatter dataFormatter = new DataFormatter();
            //从第5行开始循环
            List<String> stages = Arrays.asList("一、","二、","三、","四、","五、","六、","七、","八、","九、","十、");
            for (int i = 4; i < rows; i++) {
                Row row = sheet.getRow(i);
                String oneColumn =  dataFormatter.formatCellValue(row.getCell(0,Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                if (StringUtils.isBlank(oneColumn)){
                    /*空行 或者 末尾行直接退出*/
                }else if (oneColumn.contains("注：")){
                    break;
                }else if (stages.contains(oneColumn)){
                    /*项目进程行*/
                    String stageTypeName = row.getCell(1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();
                    Integer type = stageMap.get(stageTypeName);
                    if (type == null){
                        throw new ServiceException("未获取到项目进程类型："+stageTypeName);
                    }else {
                        projectStage = type;
                    }
                }else {
                    /*项目信息行*/
                    //校验年是否被改变
                    ProjectImportExcel pro = new ProjectImportExcel();
                    String name = row.getCell(1, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();
                    try {
                        if (StringUtils.isBlank(name)){
                            throw new ServiceException("项目名称不能为空");
                        }
                        if (projectStage == 0){
                            throw new ServiceException("未获取到项目进程");
                        }
                        String buildScale =  dataFormatter.formatCellValue(row.getCell(2,Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                        BigDecimal allInvestMoney = StringChangeBigdecimal( dataFormatter.formatCellValue(row.getCell(3,Row.MissingCellPolicy.CREATE_NULL_AS_BLANK)));
                        String start = dataFormatter.formatCellValue(row.getCell(4, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                        String end = dataFormatter.formatCellValue(row.getCell(5, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                        if (StringUtils.isBlank(start ) || StringUtils.isBlank(end)){
                            throw new ServiceException("开工年完工年不能为空");
                        }
                        Integer startYear = Integer.valueOf(start);
                        Integer endYear = Integer.valueOf(end);
                        //校验计划年份是否在开工和完工之间
                        if (startYear > endYear){
                            throw new ServiceException("开工年不能大于完工年");
                        }
                        //todo 如果后面可以导入不是标题年的项目，则修改先判断是否存在计划，存在计划才校验
                        //校验标题年份是否在开工和完工之间
//                        if (year < startYear || year > endYear){
//                            throw new ServiceException("标题年份不在开工和完工年之间");
//                        }
                        ProjectInfo info = projectMap.get(name);
                        if (info != null){
                            pro.setProjectId(info.getId());
                            pro.setIsExist(true);
//                            if (!startYear.equals(info.getStartYear()) || !endYear.equals(info.getEndYear())){
//                                throw new ServiceException("项目已存在，开工年完工年和已有数据不同");
//                            }
                        }else {
                            pro.setIsExist(false);
                        }
                        String dutyUnit = row.getCell(6, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();
                        String isPilotPlan = row.getCell(7, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK).getStringCellValue();
                        Integer isPilotPlan2 = 0;
                        if (StringUtils.isNotBlank(isPilotPlan) && isPilotPlan.contains("是")){
                            isPilotPlan2 = 1;
                        }
                        /*年度信息行*/
                        BigDecimal yearlyInvest = StringChangeBigdecimal(dataFormatter.formatCellValue(row.getCell(8,Row.MissingCellPolicy.CREATE_NULL_AS_BLANK)));
                        BigDecimal oneInvest = StringChangeBigdecimal(dataFormatter.formatCellValue(row.getCell(9,Row.MissingCellPolicy.CREATE_NULL_AS_BLANK)));
                        BigDecimal twoInvest = StringChangeBigdecimal(dataFormatter.formatCellValue(row.getCell(10,Row.MissingCellPolicy.CREATE_NULL_AS_BLANK)));
                        BigDecimal threeInvest = StringChangeBigdecimal(dataFormatter.formatCellValue(row.getCell(11,Row.MissingCellPolicy.CREATE_NULL_AS_BLANK)));
                        BigDecimal fourInvest = StringChangeBigdecimal(dataFormatter.formatCellValue(row.getCell(12,Row.MissingCellPolicy.CREATE_NULL_AS_BLANK)));
                        String yearlyTarget = dataFormatter.formatCellValue(row.getCell(13, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                        String onePlan = dataFormatter.formatCellValue(row.getCell(14, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                        String twoPlan = dataFormatter.formatCellValue(row.getCell(15, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                        String threePlan = dataFormatter.formatCellValue(row.getCell(16, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                        String fourPlan = dataFormatter.formatCellValue(row.getCell(17, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                        String questionable = dataFormatter.formatCellValue(row.getCell(22, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                        String workAdvise = dataFormatter.formatCellValue(row.getCell(23, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                        String linkman = dataFormatter.formatCellValue(row.getCell(24, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                        String phone = dataFormatter.formatCellValue(row.getCell(25, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                        /*月度信息行*/
                        BigDecimal investMoney = StringChangeBigdecimal(dataFormatter.formatCellValue(row.getCell(18,Row.MissingCellPolicy.CREATE_NULL_AS_BLANK)));
                        String workProgress = dataFormatter.formatCellValue(row.getCell(19, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                        String workProgressAll = dataFormatter.formatCellValue(row.getCell(20, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                        String planRatioString = dataFormatter.formatCellValue(row.getCell(21, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK));
                        BigDecimal planRatio = StringChangeBigdecimal(planRatioString.contains("%")?planRatioString.substring(0,planRatioString.length()-1):planRatioString);
                        if (planRatio != null && (planRatio.compareTo(BigDecimal.ZERO) == -1 || planRatio.compareTo(new BigDecimal(100)) == 1)){
                            throw new ServiceException("工程整体形象进度要在0-100之间");
                        }
                        /*设置信息*/
                        pro.setName(name);
                        pro.setPlanYear(year);
                        pro.setPlanMonth(month);
                        pro.setProjectType(projectType);
                        pro.setProjectStage(projectStage);
                        pro.setBuildScale(buildScale);
                        pro.setBuildScaleUnit(buildScaleUnit);
                        pro.setAllInvestMoney(allInvestMoney);
                        pro.setStartYear(startYear);
                        pro.setEndYear(endYear);
                        pro.setDutyUnit(dutyUnit);
                        pro.setIsPilotPlan(isPilotPlan2);
                        pro.setYearlyInvest(yearlyInvest);
                        pro.setOneInvest(oneInvest);
                        pro.setTwoInvest(twoInvest);
                        pro.setThreeInvest(threeInvest);
                        pro.setFourInvest(fourInvest);
                        pro.setYearlyTarget(yearlyTarget);
                        pro.setOnePlan(onePlan);
                        pro.setTwoPlan(twoPlan);
                        pro.setThreePlan(threePlan);
                        pro.setFourPlan(fourPlan);
                        pro.setQuestionable(questionable);
                        pro.setWorkAdvise(workAdvise);
                        pro.setLinkman(linkman);
                        pro.setPhone(phone);
                        pro.setInvestMoney(investMoney);
                        pro.setWorkProgress(workProgress);
                        pro.setWorkProgressAll(workProgressAll);
                        pro.setPlanRatio(planRatio);
                        if (investMoney != null || StringUtils.isNotBlank(workProgress) || StringUtils.isNotBlank(workProgressAll) || planRatio != null){
                            pro.setHasFinished(true);
                        }else {
                            pro.setHasFinished(false);
                        }
                        list.add(pro);
                    }catch (Exception e){
                        if (e.getMessage().contains("decimal")){
                            throw new ServiceException("项目：" + name + " 解析失败，原因：" + "数字转换异常，请检查数字格式，和不要设置公式");
                        }else {
                            throw new ServiceException("项目：" + name + " 解析失败，原因：" + e.getMessage());
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new ServiceException("excel解析失败：" + e.getMessage());
        }
        return list;
    }

    //string转化为Big,如果string为空，则返回null
    private BigDecimal StringChangeBigdecimal(String big){
        BigDecimal b = null;
        if (StringUtils.isNotBlank(big)){
            b = new BigDecimal(big);
        }
        return b;
    }

    @Override
    public IPage<pageWarningVO> pageWarning(pageWarningDTO dto) {
        Integer current = dto.getCurrent();
        Integer size = dto.getSize();
        IPage<pageWarningVO> iPage = new Page<>(current,size);
        /*查询出所有数据，手动筛选，手动分页*/
        //1 获取所有项目 所有年的计划
        List<InvestPlanWarningVO> planList = baseMapper.getAllYearPlan();
        //2 获取所有异常设置，如果没设置异常，则直接返回
        List<ProjectWarning> list = warningService.list();
        if (planList.size() == 0 || list.size() == 0){
            return iPage;
        }
        Map<Integer, ProjectWarning> map = list.stream().collect(Collectors.toMap(l -> l.getWarningType(), l -> l));
        ProjectWarning investWarning = map.get(1);
        ProjectWarning planWarning = map.get(2);
        if (investWarning == null || planWarning == null){
            throw new ServiceException("获取异常配置错误");
        }
        //3 获取所有的撤销记录，按照项目id，异常类型，年份，季度 分组
        List<RepealRecord> records = repealRecordService.list();
        Map<RepealRecordVO, RepealRecord> recordMap = new HashMap<>();
        try {
            recordMap = records.stream().collect(Collectors.toMap(l -> new RepealRecordVO(l.getProjectId(), l.getPlanYear(), l.getPlanQuarter(), l.getPlanType()), l -> l));
        }catch (Exception e){
            throw new ServiceException("撤销记录数据异常");
        }
        //4 循环所有年计划
        List<pageWarningVO> vos = new ArrayList<>();
        for (InvestPlanWarningVO plan : planList) {
            /*季度计划没有填写 和 实际完成没有填写 则不统计*/
            /*-------------投资-------------*/
            //一季度
            if (plan.getOneInvest() != null && plan.getIsOneInvestFinish() == 1){
                Boolean isWarning = false;
                Integer warningGrade = 0;
                String warningGradeName = "";
                //      填写了则每个季度直接对比数值，从1到3
                if (investWarning.getOneOne() != null && plan.getOneInvestRatio().compareTo(investWarning.getOneOne()) == -1){
                    isWarning = true;
                    warningGrade = 1;
                    warningGradeName = "一级";
                }else if (investWarning.getOneTwo() != null && plan.getOneInvestRatio().compareTo(investWarning.getOneTwo()) == -1){
                    isWarning = true;
                    warningGrade = 2;
                    warningGradeName = "二级";
                }else if (investWarning.getOneThree() != null && plan.getOneInvestRatio().compareTo(investWarning.getOneThree()) == -1){
                    isWarning = true;
                    warningGrade = 3;
                    warningGradeName = "三级";
                }
                // 如果异常则添加到异常集合中
                if (isWarning){
                    pageWarningVO vo = new pageWarningVO(plan.getProjectId(),plan.getProjectName(),1,"项目投资异常",1,"第一季度",LocalDate.of(plan.getPlanYear(), 4, 1),warningGrade,warningGradeName);
                    //判断是否撤销
                    vo.setPlanYear(plan.getPlanYear());
                    RepealRecord record = recordMap.get(new RepealRecordVO(plan.getProjectId(), plan.getPlanYear(), 1, 1));
                    if (record != null){
                        vo.setIsRepeal("是");
                        vo.setRepealStartDate(record.getStartDate());
                        vo.setRepealEndDate(record.getEndDate());
                    }
                    vos.add(vo);
                }
            }
            //二季度
            if (plan.getTwoInvest() != null && plan.getIsTwoInvestFinish() == 1){
                Boolean isWarning = false;
                Integer warningGrade = 0;
                String warningGradeName = "";
                //      填写了则每个季度直接对比数值，从1到3
                if ((investWarning.getTwoOne() != null && plan.getTwoInvestRatio().compareTo(investWarning.getTwoOne()) == -1) ||
                        (investWarning.getTwoOneAll() != null && plan.getTwoAggregateRatio().compareTo(investWarning.getTwoOneAll()) == -1)){
                    isWarning = true;
                    warningGrade = 1;
                    warningGradeName = "一级";
                }else if ((investWarning.getTwoTwo() != null && plan.getTwoInvestRatio().compareTo(investWarning.getTwoTwo()) == -1) ||
                        (investWarning.getTwoTwoAll() != null && plan.getTwoAggregateRatio().compareTo(investWarning.getTwoTwoAll()) == -1)){
                    isWarning = true;
                    warningGrade = 2;
                    warningGradeName = "二级";
                }else if ((investWarning.getTwoThree() != null && plan.getTwoInvestRatio().compareTo(investWarning.getTwoThree()) == -1) ||
                        (investWarning.getTwoThreeAll() != null && plan.getTwoAggregateRatio().compareTo(investWarning.getTwoThreeAll()) == -1)){
                    isWarning = true;
                    warningGrade = 3;
                    warningGradeName = "三级";
                }
                // 如果异常则添加到异常集合中
                if (isWarning){
                    pageWarningVO vo = new pageWarningVO(plan.getProjectId(),plan.getProjectName(),1,"项目投资异常",2,"第二季度",LocalDate.of(plan.getPlanYear(), 7, 1),warningGrade,warningGradeName);
                    vo.setPlanYear(plan.getPlanYear());
                    //判断是否撤销
                    RepealRecord record = recordMap.get(new RepealRecordVO(plan.getProjectId(), plan.getPlanYear(), 2, 1));
                    if (record != null){
                        vo.setIsRepeal("是");
                        vo.setRepealStartDate(record.getStartDate());
                        vo.setRepealEndDate(record.getEndDate());
                    }
                    vos.add(vo);
                }
            }

            //三季度
            if (plan.getThreeInvest() != null && plan.getIsThreeInvestFinish() == 1){
                Boolean isWarning = false;
                Integer warningGrade = 0;
                String warningGradeName = "";
                //      填写了则每个季度直接对比数值，从1到3
                if ((investWarning.getThreeOne() != null && plan.getThreeInvestRatio().compareTo(investWarning.getThreeOne()) == -1) ||
                        (investWarning.getThreeOneAll() != null && plan.getThreeAggregateRatio().compareTo(investWarning.getThreeOneAll()) == -1)){
                    isWarning = true;
                    warningGrade = 1;
                    warningGradeName = "一级";
                }else if ((investWarning.getThreeTwo() != null && plan.getThreeInvestRatio().compareTo(investWarning.getThreeTwo()) == -1) ||
                        (investWarning.getThreeTwoAll() != null && plan.getThreeAggregateRatio().compareTo(investWarning.getThreeTwoAll()) == -1)){
                    isWarning = true;
                    warningGrade = 2;
                    warningGradeName = "二级";
                }else if ((investWarning.getThreeThree() != null && plan.getThreeInvestRatio().compareTo(investWarning.getThreeThree()) == -1) ||
                        (investWarning.getThreeThreeAll() != null && plan.getThreeAggregateRatio().compareTo(investWarning.getThreeThreeAll()) == -1)){
                    isWarning = true;
                    warningGrade = 3;
                    warningGradeName = "三级";
                }
                // 如果异常则添加到异常集合中
                if (isWarning){
                    pageWarningVO vo = new pageWarningVO(plan.getProjectId(),plan.getProjectName(),1,"项目投资异常",3,"第三季度",LocalDate.of(plan.getPlanYear(), 10, 1),warningGrade,warningGradeName);
                    vo.setPlanYear(plan.getPlanYear());
                    //判断是否撤销
                    RepealRecord record = recordMap.get(new RepealRecordVO(plan.getProjectId(), plan.getPlanYear(), 3, 1));
                    if (record != null){
                        vo.setIsRepeal("是");
                        vo.setRepealStartDate(record.getStartDate());
                        vo.setRepealEndDate(record.getEndDate());
                    }
                    vos.add(vo);
                }
            }

            //四季度
            if (plan.getFourInvest() != null && plan.getIsFourInvestFinish() == 1){
                Boolean isWarning = false;
                Integer warningGrade = 0;
                String warningGradeName = "";
                //      填写了则每个季度直接对比数值，从1到3
                if ((investWarning.getFourOne() != null && plan.getFourInvestRatio().compareTo(investWarning.getFourOne()) == -1) ||
                        (investWarning.getFourOneAll() != null && plan.getFourAggregateRatio().compareTo(investWarning.getFourOneAll()) == -1)){
                    isWarning = true;
                    warningGrade = 1;
                    warningGradeName = "一级";
                }else if ((investWarning.getFourTwo() != null && plan.getFourInvestRatio().compareTo(investWarning.getFourTwo()) == -1) ||
                        (investWarning.getFourTwoAll() != null && plan.getFourAggregateRatio().compareTo(investWarning.getFourTwoAll()) == -1)){
                    isWarning = true;
                    warningGrade = 2;
                    warningGradeName = "二级";
                }else if ((investWarning.getFourThree() != null && plan.getFourInvestRatio().compareTo(investWarning.getFourThree()) == -1) ||
                        (investWarning.getFourThreeAll() != null && plan.getFourAggregateRatio().compareTo(investWarning.getFourThreeAll()) == -1)){
                    isWarning = true;
                    warningGrade = 3;
                    warningGradeName = "三级";
                }
                // 如果异常则添加到异常集合中
                if (isWarning){
                    pageWarningVO vo = new pageWarningVO(plan.getProjectId(),plan.getProjectName(),1,"项目投资异常",4,"第四季度",LocalDate.of(plan.getPlanYear()+1, 1, 1),warningGrade,warningGradeName);
                    vo.setPlanYear(plan.getPlanYear());
                    //判断是否撤销
                    RepealRecord record = recordMap.get(new RepealRecordVO(plan.getProjectId(), plan.getPlanYear(), 4, 1));
                    if (record != null){
                        vo.setIsRepeal("是");
                        vo.setRepealStartDate(record.getStartDate());
                        vo.setRepealEndDate(record.getEndDate());
                    }
                    vos.add(vo);
                }
            }
            /*-------------进度-------------*/
            //一季度
            if (StringUtils.isNotBlank(plan.getOnePlan()) && plan.getIsOnePlanFinish() == 1){
                Boolean isWarning = false;
                Integer warningGrade = 0;
                String warningGradeName = "";
                //      填写了则每个季度直接对比数值，从1到3
                if (planWarning.getOneOne() != null && plan.getOnePlanRatio().compareTo(planWarning.getOneOne()) == -1){
                    isWarning = true;
                    warningGrade = 1;
                    warningGradeName = "一级";
                }else if (planWarning.getOneTwo() != null && plan.getOnePlanRatio().compareTo(planWarning.getOneTwo()) == -1){
                    isWarning = true;
                    warningGrade = 2;
                    warningGradeName = "二级";
                }else if (planWarning.getOneThree() != null && plan.getOnePlanRatio().compareTo(planWarning.getOneThree()) == -1){
                    isWarning = true;
                    warningGrade = 3;
                    warningGradeName = "三级";
                }
                // 如果异常则添加到异常集合中
                if (isWarning){
                    pageWarningVO vo = new pageWarningVO(plan.getProjectId(),plan.getProjectName(),2,"项目进度异常",1,"第一季度",LocalDate.of(plan.getPlanYear(), 4, 1),warningGrade,warningGradeName);
                    vo.setPlanYear(plan.getPlanYear());
                    //判断是否撤销
                    RepealRecord record = recordMap.get(new RepealRecordVO(plan.getProjectId(), plan.getPlanYear(), 1, 2));
                    if (record != null){
                        vo.setIsRepeal("是");
                        vo.setRepealStartDate(record.getStartDate());
                        vo.setRepealEndDate(record.getEndDate());
                    }
                    vos.add(vo);
                }
            }
            //二季度
            if (StringUtils.isNotBlank(plan.getOnePlan()) && plan.getIsTwoPlanFinish() == 1){
                Boolean isWarning = false;
                Integer warningGrade = 0;
                String warningGradeName = "";
                //      填写了则每个季度直接对比数值，从1到3
                if (planWarning.getTwoOne() != null && plan.getTwoPlanRatio().compareTo(planWarning.getTwoOne()) == -1){
                    isWarning = true;
                    warningGrade = 1;
                    warningGradeName = "一级";
                }else if (planWarning.getTwoTwo() != null && plan.getTwoPlanRatio().compareTo(planWarning.getTwoTwo()) == -1){
                    isWarning = true;
                    warningGrade = 2;
                    warningGradeName = "二级";
                }else if (planWarning.getTwoThree() != null && plan.getTwoPlanRatio().compareTo(planWarning.getTwoThree()) == -1){
                    isWarning = true;
                    warningGrade = 3;
                    warningGradeName = "三级";
                }
                // 如果异常则添加到异常集合中
                if (isWarning){
                    pageWarningVO vo = new pageWarningVO(plan.getProjectId(),plan.getProjectName(),2,"项目进度异常",2,"第二季度",LocalDate.of(plan.getPlanYear(), 7, 1),warningGrade,warningGradeName);
                    vo.setPlanYear(plan.getPlanYear());
                    //判断是否撤销
                    RepealRecord record = recordMap.get(new RepealRecordVO(plan.getProjectId(), plan.getPlanYear(), 2, 2));
                    if (record != null){
                        vo.setIsRepeal("是");
                        vo.setRepealStartDate(record.getStartDate());
                        vo.setRepealEndDate(record.getEndDate());
                    }
                    vos.add(vo);
                }
            }
            //三季度
            if (StringUtils.isNotBlank(plan.getThreePlan()) && plan.getIsThreePlanFinish() == 1){
                Boolean isWarning = false;
                Integer warningGrade = 0;
                String warningGradeName = "";
                //      填写了则每个季度直接对比数值，从1到3
                if (planWarning.getThreeOne() != null && plan.getThreePlanRatio().compareTo(planWarning.getThreeOne()) == -1){
                    isWarning = true;
                    warningGrade = 1;
                    warningGradeName = "一级";
                }else if (planWarning.getThreeTwo() != null && plan.getThreePlanRatio().compareTo(planWarning.getThreeTwo()) == -1){
                    isWarning = true;
                    warningGrade = 2;
                    warningGradeName = "二级";
                }else if (planWarning.getThreeThree() != null && plan.getThreePlanRatio().compareTo(planWarning.getThreeThree()) == -1){
                    isWarning = true;
                    warningGrade = 3;
                    warningGradeName = "三级";
                }
                // 如果异常则添加到异常集合中
                if (isWarning){
                    pageWarningVO vo = new pageWarningVO(plan.getProjectId(),plan.getProjectName(),2,"项目进度异常",3,"第三季度",LocalDate.of(plan.getPlanYear(), 10, 1),warningGrade,warningGradeName);
                    vo.setPlanYear(plan.getPlanYear());
                    //判断是否撤销
                    RepealRecord record = recordMap.get(new RepealRecordVO(plan.getProjectId(), plan.getPlanYear(), 3, 2));
                    if (record != null){
                        vo.setIsRepeal("是");
                        vo.setRepealStartDate(record.getStartDate());
                        vo.setRepealEndDate(record.getEndDate());
                    }
                    vos.add(vo);
                }
            }
            //四季度
            if (StringUtils.isNotBlank(plan.getFourPlan()) && plan.getIsFourPlanFinish() == 1){
                Boolean isWarning = false;
                Integer warningGrade = 0;
                String warningGradeName = "";
                //      填写了则每个季度直接对比数值，从1到3
                if (planWarning.getFourOne() != null && plan.getFourPlanRatio().compareTo(planWarning.getFourOne()) == -1){
                    isWarning = true;
                    warningGrade = 1;
                    warningGradeName = "一级";
                }else if (planWarning.getFourTwo() != null && plan.getFourPlanRatio().compareTo(planWarning.getFourTwo()) == -1){
                    isWarning = true;
                    warningGrade = 2;
                    warningGradeName = "二级";
                }else if (planWarning.getFourThree() != null && plan.getFourPlanRatio().compareTo(planWarning.getFourThree()) == -1){
                    isWarning = true;
                    warningGrade = 3;
                    warningGradeName = "三级";
                }
                // 如果异常则添加到异常集合中
                if (isWarning){
                    pageWarningVO vo = new pageWarningVO(plan.getProjectId(),plan.getProjectName(),2,"项目进度异常",4,"第四季度",LocalDate.of(plan.getPlanYear()+1, 1, 1),warningGrade,warningGradeName);
                    vo.setPlanYear(plan.getPlanYear());
                    //判断是否撤销
                    RepealRecord record = recordMap.get(new RepealRecordVO(plan.getProjectId(), plan.getPlanYear(), 4, 2));
                    if (record != null){
                        vo.setIsRepeal("是");
                        vo.setRepealStartDate(record.getStartDate());
                        vo.setRepealEndDate(record.getEndDate());
                    }
                    vos.add(vo);
                }
            }

        }
        //5 异常集合先按照搜索条件过滤，再手动分组
        if (dto.getType() != null){
            vos = vos.stream().filter(l->dto.getType().equals(l.getWarningType())).collect(Collectors.toList());
        }
        if (dto.getGrade() != null){
            vos = vos.stream().filter(l->dto.getGrade().equals(l.getWarningGrade())).collect(Collectors.toList());
        }
        if (dto.getIsAnnul() != null){
            String str = dto.getIsAnnul() == 1? "是" : "否";
            vos = vos.stream().filter(l->str.equals(l.getIsRepeal())).collect(Collectors.toList());
        }
        if (StringUtils.isNotBlank(dto.getSearchValue())){
            vos = vos.stream().filter(l->l.getProjectName().contains(dto.getSearchValue())).collect(Collectors.toList());
        }
        int start = (current-1)*size;
        int end = current*size > vos.size() ? vos.size() : current*size;
        List<pageWarningVO> subList = vos.subList(start, end);
        iPage.setRecords(subList);
        iPage.setTotal(vos.size());
        return iPage;
    }



}
