package com.hz.pm.api.dashboard.manage;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.hz.pm.api.dashboard.model.vo.FundStatisticsVO;
import com.hz.pm.api.gov.model.entity.GovBizProjectApply;
import com.hz.pm.api.gov.model.entity.GovBizProjectApprove;
import com.hz.pm.api.gov.model.entity.GovBizProjectBaseinfo;
import com.hz.pm.api.gov.model.entity.GovBizProjectProcure;
import com.hz.pm.api.gov.service.IGovBizProjectApplyService;
import com.hz.pm.api.gov.service.IGovBizProjectApproveService;
import com.hz.pm.api.gov.service.IGovBizProjectBaseinfoService;
import com.hz.pm.api.gov.service.IGovBizProjectProcureService;
import com.hz.pm.api.projectlib.model.enumeration.ProjectStatusEnum;
import com.hz.pm.api.projectlib.model.entity.Project;
import com.hz.pm.api.projectlib.service.IProjectService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ForkJoinPool;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Classname FundStatisticsManage
 * @Description
 * @Date 2023/11/24 17:44
 * @Author PoffyZhang
 */
@Component
@RequiredArgsConstructor
@Slf4j
public class FundStatisticsManage {
    private final IProjectService projectService;

    private final IGovBizProjectBaseinfoService baseinfoService;

    private final IGovBizProjectApplyService applyService;

    private final IGovBizProjectApproveService approveService;

    private final IGovBizProjectProcureService procureService;

    private Integer[] years = new Integer[]{2021, 2022, 2023, 2024, 2025};

    private Integer[] threeYears = new Integer[]{LocalDateTime.now().getYear() - 2,
            LocalDateTime.now().getYear() - 1, LocalDateTime.now().getYear()};

    /**
     * 项目统计
     *
     * @param year
     * @return
     */
    public FundStatisticsVO statistics(Integer year) {
        FundStatisticsVO res = new FundStatisticsVO();

        CompletableFuture.allOf(
                CompletableFuture.runAsync(() -> {
                    //选择的年份去计算的数据
                    yearCompleteAmount(res, year);
                }, ForkJoinPool.commonPool()),
                CompletableFuture.runAsync(() -> {
                    //近三年
                    threeYearsCompleteAmount(res);
                }, ForkJoinPool.commonPool()),
                CompletableFuture.runAsync(() -> {
                    //所有年 用于算累积
                    allYearsCompleteAmount(res);
                }, ForkJoinPool.commonPool())
        ).join();

        return res;
    }

    /**
     * 计算 所有年的
     *
     * @param res
     */
    private void allYearsCompleteAmount(FundStatisticsVO res) {
        //1.申报项目 和 归集项目
        //申报项目
        List<Project> allProjects = projectService.list(Wrappers.lambdaQuery(Project.class)
                .eq(Project::getNewest, Boolean.TRUE)
                .in(Project::getProjectYear, years));

        //项目归集
        List<GovBizProjectApply> allApplieYears = applyService.list(Wrappers.lambdaQuery(GovBizProjectApply.class)
                .in(GovBizProjectApply::getBaseProjSetYear, years));

        List<String> allProjIds = allApplieYears.stream().map(GovBizProjectApply::getBaseProjId)
                .collect(Collectors.toList());

        List<GovBizProjectBaseinfo> allBaseInfos;
        List<GovBizProjectApply> allApplies = Lists.newArrayList();
        List<GovBizProjectApprove> allApproves = Lists.newArrayList();
        List<GovBizProjectProcure> allProcures = Lists.newArrayList();

        if (CollUtil.isNotEmpty(allProjIds)) {
            allBaseInfos = baseinfoService.list(Wrappers.lambdaQuery(GovBizProjectBaseinfo.class)
                    .eq(GovBizProjectBaseinfo::getDeleted, Boolean.FALSE)
                    .in(GovBizProjectBaseinfo::getBaseProjId, allProjIds));
            if (CollUtil.isNotEmpty(allBaseInfos)) {
                List<String> allBaseProjIds = allBaseInfos.stream().map(GovBizProjectBaseinfo::getBaseProjId)
                        .collect(Collectors.toList());
                allApplies = applyService.list(Wrappers.lambdaQuery(GovBizProjectApply.class)
                        .in(GovBizProjectApply::getBaseProjId, allBaseProjIds));
                allApproves = approveService.list(Wrappers.lambdaQuery(GovBizProjectApprove.class)
                        .in(GovBizProjectApprove::getBaseProjId, allBaseProjIds));
                allProcures = procureService.list(Wrappers.lambdaQuery(GovBizProjectProcure.class)
                        .in(GovBizProjectProcure::getBaseProjId, allBaseProjIds));
            }
        }

        //2.4 累积 核减
        res.setAccumulatedDeductionTotalAmount(completeDeductionAmount(allProjects, allApplies,
                allApproves, allProcures));
    }

    /**
     * 计算核减资金的方法
     *
     * @param projects
     * @param applies
     * @param approves
     * @param procures
     * @return
     */
    private BigDecimal completeDeductionAmount(List<Project> projects,
                                               List<GovBizProjectApply> applies, List<GovBizProjectApprove> approves,
                                               List<GovBizProjectProcure> procures) {
        //首先完成年度计划 并且未注销的项目
        List<Project> normalProjects = projects.stream().filter(p -> {
            if (Objects.nonNull(p.getStatus()) &&
                    p.getStatus().compareTo(ProjectStatusEnum.BE_SUSPENDED.getCode()) > 0) {
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }).collect(Collectors.toList());
        //计划核减
        FundStatisticsVO.HeJianAmount planHejian = computePlanHeJian(normalProjects, applies, approves);
        //批复核减
        FundStatisticsVO.HeJianAmount approvalHejian = computeApprovalHeJian(normalProjects, approves, planHejian.getApproval());
        //合同核减
        FundStatisticsVO.HeJianAmount contractHejian = computeContractHeJian(normalProjects, procures, approvalHejian.getApproval());

        return planHejian.getDiff().add(approvalHejian.getDiff()).add(contractHejian.getDiff());
    }

    //计算 计划阶段的 核减金额
    private FundStatisticsVO.HeJianAmount computePlanHeJian(List<Project> projects, List<GovBizProjectApply> applies,
                                                            List<GovBizProjectApprove> approves) {
        FundStatisticsVO.HeJianAmount heJianAmount = new FundStatisticsVO.HeJianAmount();

        //申报的申报金额(申报项目:初步方案申报金额 项目归集:项目总投资)
        final BigDecimal[] declaredAmountApprove = {BigDecimal.ZERO};
        projects.stream().map(p -> Objects.nonNull(p.getDeclareAmount()) ? p.getDeclareAmount() : BigDecimal.ZERO)
                .reduce(BigDecimal::add).ifPresent(b -> declaredAmountApprove[0] = b);
        final BigDecimal[] declaredAmountApproveGov = {BigDecimal.ZERO};
        applies.stream().map(g -> Objects.nonNull(g.getBaseProjTotalAmount()) ? g.getBaseProjTotalAmount() : BigDecimal.ZERO)
                .reduce(BigDecimal::add).ifPresent(b -> declaredAmountApproveGov[0] = b);
        BigDecimal declaredAmountApproveTotal = declaredAmountApprove[0].add(declaredAmountApproveGov[0]);
        heJianAmount.setApprove(declaredAmountApproveTotal);

        //申报的批复金额(申报项目:建设方案申报金额 项目归集:建议总投资)
        final BigDecimal[] approvalAmountApprove = {BigDecimal.ZERO};
        projects.stream().map(p -> Objects.nonNull(p.getApprovalAmount()) ? p.getApprovalAmount() : BigDecimal.ZERO)
                .reduce(BigDecimal::add).ifPresent(b -> approvalAmountApprove[0] = b);
        final BigDecimal[] approvalAmountApproveGov = {BigDecimal.ZERO};
        approves.stream().map(p -> Objects.nonNull(p.getBaseExpertTotalMoney()) ? p.getBaseExpertTotalMoney() : BigDecimal.ZERO)
                .reduce(BigDecimal::add).ifPresent(b -> approvalAmountApproveGov[0] = b);
        BigDecimal approvalAmountApproveTotal = approvalAmountApprove[0].add(approvalAmountApproveGov[0]);
        heJianAmount.setApproval(approvalAmountApproveTotal);
        //申报的差额
        BigDecimal subtractApprove = declaredAmountApproveTotal.subtract(approvalAmountApproveTotal);
        heJianAmount.setDiff(subtractApprove);
        return heJianAmount;
    }

    //计算 批复阶段的 核减金额
    private FundStatisticsVO.HeJianAmount computeApprovalHeJian(List<Project> projects, List<GovBizProjectApprove> approves,
                                                                BigDecimal approvalAmountApproveTotal) {
        FundStatisticsVO.HeJianAmount approvalHejian = new FundStatisticsVO.HeJianAmount();
        approvalHejian.setApprove(approvalAmountApproveTotal);
        //批复的批复金额(申报项目:归集信息建议批复总投资 项目归集:建议批复总投资)
        final BigDecimal[] approvalAmountApproval = {BigDecimal.ZERO};
        projects.stream().map(p -> Objects.nonNull(p.getProposeTotalInvest()) ? p.getProposeTotalInvest() : BigDecimal.ZERO)
                .reduce(BigDecimal::add).ifPresent(b -> approvalAmountApproval[0] = b);
        final BigDecimal[] approvalAmountApprovalGov = {BigDecimal.ZERO};
        approves.stream().map(p -> Objects.nonNull(p.getBaseInitialReviewTotalMoney()) ? p.getBaseInitialReviewTotalMoney() : BigDecimal.ZERO)
                .reduce(BigDecimal::add).ifPresent(b -> approvalAmountApprovalGov[0] = b);
        BigDecimal approvalAmountApprovalTotal = approvalAmountApproval[0].add(approvalAmountApprovalGov[0]);
        approvalHejian.setApproval(approvalAmountApprovalTotal);
        //批复的差额
        BigDecimal subtractApproval = approvalAmountApproveTotal.subtract(approvalAmountApprovalTotal);
        approvalHejian.setDiff(subtractApproval);
        return approvalHejian;
    }

    //计算 合同阶段的 核减金额
    private FundStatisticsVO.HeJianAmount computeContractHeJian(List<Project> projects, List<GovBizProjectProcure> procures,
                                                                BigDecimal approvalAmountApprovalTotal) {
        FundStatisticsVO.HeJianAmount contractHejian = new FundStatisticsVO.HeJianAmount();
        contractHejian.setApprove(approvalAmountApprovalTotal);
        //合同的批复金额(申报项目:成交金额 项目归集:成交金额)
        final BigDecimal[] approvalAmountContract = {BigDecimal.ZERO};
        projects.stream().map(p -> Objects.nonNull(p.getTransactionAmount()) ? p.getTransactionAmount() : BigDecimal.ZERO)
                .reduce(BigDecimal::add).ifPresent(b -> approvalAmountContract[0] = b);
        final BigDecimal[] approvalAmountContractGov = {BigDecimal.ZERO};
        procures.stream().map(p -> Objects.nonNull(p.getBaseProjPurchaseAmount()) ? p.getBaseProjPurchaseAmount() : BigDecimal.ZERO)
                .reduce(BigDecimal::add).ifPresent(b -> approvalAmountContractGov[0] = b);
        BigDecimal approvalAmountContractTotal = approvalAmountContract[0].add(approvalAmountContractGov[0]);
        contractHejian.setApproval(approvalAmountContractTotal);
        //合同的差额
        BigDecimal subtractContract = approvalAmountApprovalTotal.subtract(approvalAmountContractTotal);
        contractHejian.setDiff(subtractContract);
        return contractHejian;
    }

    /**
     * 近三年
     *
     * @param res
     */
    private void threeYearsCompleteAmount(FundStatisticsVO res) {
        //申报项目
        List<Project> threeYearsProjects = projectService.list(Wrappers.lambdaQuery(Project.class)
                .eq(Project::getNewest, Boolean.TRUE)
                .in(Project::getProjectYear, threeYears));
        //项目归集
        List<GovBizProjectApply> threeYearsApplieYears = applyService.list(Wrappers.lambdaQuery(GovBizProjectApply.class)
                .in(GovBizProjectApply::getBaseProjSetYear, threeYears));
        List<String> threeYearsProjIds = threeYearsApplieYears.stream().map(GovBizProjectApply::getBaseProjId)
                .collect(Collectors.toList());
        List<GovBizProjectBaseinfo> threeYearsBaseInfos = Lists.newArrayList();
        List<GovBizProjectApply> threeYearsApplies = Lists.newArrayList();
        List<GovBizProjectApprove> threeYearsApproves = Lists.newArrayList();
        List<GovBizProjectProcure> threeYearsProcures = Lists.newArrayList();

        if (CollUtil.isNotEmpty(threeYearsProjIds)) {
            threeYearsBaseInfos = baseinfoService.list(Wrappers.lambdaQuery(GovBizProjectBaseinfo.class)
                    .eq(GovBizProjectBaseinfo::getDeleted, Boolean.FALSE)
                    .in(GovBizProjectBaseinfo::getBaseProjId, threeYearsProjIds));
            if (CollUtil.isNotEmpty(threeYearsBaseInfos)) {
                List<String> threeYearsBaseProjIds = threeYearsBaseInfos.stream().map(GovBizProjectBaseinfo::getBaseProjId)
                        .collect(Collectors.toList());
                threeYearsApplies = applyService.list(Wrappers.lambdaQuery(GovBizProjectApply.class)
                        .in(GovBizProjectApply::getBaseProjId, threeYearsBaseProjIds));
                threeYearsApproves = approveService.list(Wrappers.lambdaQuery(GovBizProjectApprove.class)
                        .in(GovBizProjectApprove::getBaseProjId, threeYearsBaseProjIds));
                threeYearsProcures = procureService.list(Wrappers.lambdaQuery(GovBizProjectProcure.class)
                        .in(GovBizProjectProcure::getBaseProjId, threeYearsBaseProjIds));
            }
        }

        //2.4 近三年 核减
        res.setThreeYearsDeductionTotalAmount(completeDeductionAmount(threeYearsProjects, threeYearsApplies,
                threeYearsApproves, threeYearsProcures));

        //安全起见 再排序下
        Arrays.sort(threeYears);

        List<FundStatisticsVO.AmountData> threeYearsDeduction = Lists.newArrayList();
        for (Integer year : threeYears) {
            FundStatisticsVO.AmountData amountData = new FundStatisticsVO.AmountData();
            //申报项目
            List<Project> thisYearsProjects = projectService.list(Wrappers.lambdaQuery(Project.class)
                    .eq(Project::getNewest, Boolean.TRUE)
                    .eq(Project::getProjectYear, year));
            //项目归集
            List<GovBizProjectApply> thisYearApplieYears = applyService.list(Wrappers.lambdaQuery(GovBizProjectApply.class)
                    .eq(GovBizProjectApply::getBaseProjSetYear, year));
            List<String> thisYearProjIds = thisYearApplieYears.stream().map(GovBizProjectApply::getBaseProjId)
                    .collect(Collectors.toList());
            List<GovBizProjectBaseinfo> thisYearBaseInfos;
            List<GovBizProjectApply> thisYearApplies = Lists.newArrayList();
            List<GovBizProjectApprove> thisYearApproves = Lists.newArrayList();
            List<GovBizProjectProcure> thisYearProcures = Lists.newArrayList();

            if (CollUtil.isNotEmpty(thisYearProjIds)) {
                thisYearBaseInfos = baseinfoService.list(Wrappers.lambdaQuery(GovBizProjectBaseinfo.class)
                        .eq(GovBizProjectBaseinfo::getDeleted, Boolean.FALSE)
                        .in(GovBizProjectBaseinfo::getBaseProjId, threeYearsProjIds));
                if (CollUtil.isNotEmpty(thisYearBaseInfos)) {
                    List<String> threeYearsBaseProjIds = threeYearsBaseInfos.stream().map(GovBizProjectBaseinfo::getBaseProjId)
                            .collect(Collectors.toList());
                    thisYearApplies = applyService.list(Wrappers.lambdaQuery(GovBizProjectApply.class)
                            .in(GovBizProjectApply::getBaseProjId, threeYearsBaseProjIds));
                    thisYearApproves = approveService.list(Wrappers.lambdaQuery(GovBizProjectApprove.class)
                            .in(GovBizProjectApprove::getBaseProjId, threeYearsBaseProjIds));
                    thisYearProcures = procureService.list(Wrappers.lambdaQuery(GovBizProjectProcure.class)
                            .in(GovBizProjectProcure::getBaseProjId, threeYearsBaseProjIds));
                }
            }
            amountData.setName(year.toString());
            amountData.setAmount(completeDeductionAmount(thisYearsProjects, thisYearApplies,
                    thisYearApproves, thisYearProcures));
            threeYearsDeduction.add(amountData);
        }
        res.setThreeYearsDeduction(threeYearsDeduction);
    }

    /**
     * 选择年份去计算
     *
     * @param res
     */
    private void yearCompleteAmount(FundStatisticsVO res, Integer year) {
        //申报项目
        List<Project> projects = projectService.list(Wrappers.lambdaQuery(Project.class)
                .eq(Project::getNewest, Boolean.TRUE)
                .eq(Objects.nonNull(year), Project::getProjectYear, year)
                .in(Objects.isNull(year), Project::getProjectYear, years));
        //项目归集
        List<GovBizProjectApply> applieYears = applyService.list(Wrappers.lambdaQuery(GovBizProjectApply.class)
                .eq(Objects.nonNull(year), GovBizProjectApply::getBaseProjSetYear, year)
                .in(Objects.isNull(year), GovBizProjectApply::getBaseProjSetYear, years));
        List<String> yearProjIds = applieYears.stream().map(GovBizProjectApply::getBaseProjId)
                .collect(Collectors.toList());
        List<GovBizProjectBaseinfo> baseInfos = Lists.newArrayList();
        List<GovBizProjectApply> applies = Lists.newArrayList();
        List<GovBizProjectApprove> approves = Lists.newArrayList();
        List<GovBizProjectProcure> procures = Lists.newArrayList();
        if (CollUtil.isNotEmpty(yearProjIds)) {
            baseInfos = baseinfoService.list(Wrappers.lambdaQuery(GovBizProjectBaseinfo.class)
                    .eq(GovBizProjectBaseinfo::getDeleted, Boolean.FALSE)
                    .in(GovBizProjectBaseinfo::getBaseProjId, yearProjIds));
            if (CollUtil.isNotEmpty(baseInfos)) {
                List<String> baseProjIds = baseInfos.stream().map(GovBizProjectBaseinfo::getBaseProjId)
                        .collect(Collectors.toList());
                applies = applyService.list(Wrappers.lambdaQuery(GovBizProjectApply.class)
                        .in(GovBizProjectApply::getBaseProjId, baseProjIds));
                approves = approveService.list(Wrappers.lambdaQuery(GovBizProjectApprove.class)
                        .in(GovBizProjectApprove::getBaseProjId, baseProjIds));
                procures = procureService.list(Wrappers.lambdaQuery(GovBizProjectProcure.class)
                        .in(GovBizProjectProcure::getBaseProjId, baseProjIds));
            }
        }
        //2
        //2.1 总申请金额
        final BigDecimal[] declaredTotalAmount = {BigDecimal.ZERO};
        projects.stream()
                .map(p -> Objects.nonNull(p.getDeclareAmount()) ? p.getDeclareAmount() : BigDecimal.ZERO)
                .reduce(BigDecimal::add).ifPresent(b -> declaredTotalAmount[0] = b);
        final BigDecimal[] declaredTotalAmountGov = {BigDecimal.ZERO};
        applies.stream()
                .map(a -> Objects.nonNull(a.getBaseProjTotalAmount()) ? a.getBaseProjTotalAmount() : BigDecimal.ZERO)
                .reduce(BigDecimal::add).ifPresent(b -> declaredTotalAmountGov[0] = b);
        res.setDeclaredTotalAmount(declaredTotalAmount[0].add(declaredTotalAmountGov[0]));
        //2.2 总批复金额
        final BigDecimal[] approvalTotalAmount = {BigDecimal.ZERO};
        projects.stream()
                .map(p -> Objects.nonNull(p.getApprovalAmount()) ? p.getApprovalAmount() : BigDecimal.ZERO)
                .reduce(BigDecimal::add).ifPresent(b -> approvalTotalAmount[0] = b);
        final BigDecimal[] approvalTotalAmountGov = {BigDecimal.ZERO};
        approves.stream()
                .map(a -> Objects.nonNull(a.getBaseExpertTotalMoney()) ? a.getBaseExpertTotalMoney() : BigDecimal.ZERO)
                .reduce(BigDecimal::add).ifPresent(b -> approvalTotalAmountGov[0] = b);
        res.setApprovalTotalAmount(approvalTotalAmount[0].add(approvalTotalAmountGov[0]));
        //2.3 总合同金额
        final BigDecimal[] contractTotalAmount = {BigDecimal.ZERO};
        projects.stream()
                .map(p -> Objects.nonNull(p.getContractAmount()) ? p.getContractAmount() : BigDecimal.ZERO)
                .reduce(BigDecimal::add).ifPresent(b -> contractTotalAmount[0] = b);
        final BigDecimal[] contractTotalAmountGov = {BigDecimal.ZERO};
        procures.stream()
                .map(p -> Objects.nonNull(p.getBaseProjPurchaseAmount()) ? p.getBaseProjPurchaseAmount() : BigDecimal.ZERO)
                .reduce(BigDecimal::add).ifPresent(b -> contractTotalAmountGov[0] = b);
        res.setApprovalTotalAmount(contractTotalAmount[0].add(contractTotalAmountGov[0]));

        //计划核减
        FundStatisticsVO.HeJianAmount planHejian = computePlanHeJian(projects, applies, approves);
        //批复核减
        FundStatisticsVO.HeJianAmount approvalHejian = computeApprovalHeJian(projects, approves, planHejian.getApproval());
        //合同核减
        FundStatisticsVO.HeJianAmount contractHejian = computeContractHeJian(projects, procures, approvalHejian.getApproval());
        res.setPlanDeduction(planHejian);
        res.setApprovalDeduction(approvalHejian);
        res.setContractDeduction(contractHejian);

        //部门TOP10
        res.setDepartmentTop10(computeTop10(projects, baseInfos, applies, approves, procures));
    }

    /**
     * 计算 部门TOP10
     *
     * @param projects
     * @param applies
     * @param approves
     * @param procures
     * @return
     */
    private List<FundStatisticsVO.AmountData> computeTop10(List<Project> projects, List<GovBizProjectBaseinfo> baseInfos,
                                                           List<GovBizProjectApply> applies, List<GovBizProjectApprove> approves,
                                                           List<GovBizProjectProcure> procures) {
        //申报项目颗粒度
        Map<String, List<Project>> groupProjectMap = projects.stream()
                .filter(p -> StringUtils.isNotBlank(p.getBuildOrgCode()))
                .collect(Collectors.groupingBy(Project::getBuildOrgCode));
        List<FundStatisticsVO.AmountData> projectAmounts = Lists.newArrayList();
        for (Map.Entry<String, List<Project>> entry : groupProjectMap.entrySet()) {
            FundStatisticsVO.AmountData orgAmount = new FundStatisticsVO.AmountData();
            List<Project> ps = entry.getValue();
            if (CollUtil.isNotEmpty(ps)) {
                orgAmount.setName(ps.get(0).getBuildOrgName());
            }
            orgAmount.setAmount(completeDeductionAmount(entry.getValue(),
                    Collections.emptyList(), Collections.emptyList(),
                    Collections.emptyList()));
            projectAmounts.add(orgAmount);
        }

        //项目归集颗粒度
        Map<String, List<GovBizProjectBaseinfo>> groupGovMap = baseInfos.stream()
                .filter(b -> StringUtils.isNotBlank(b.getBaseBuildDeprtDing()))
                .collect(Collectors.groupingBy(GovBizProjectBaseinfo::getBaseBuildDeprtDing));
        List<FundStatisticsVO.AmountData> govAmounts = Lists.newArrayList();
        for (Map.Entry<String, List<GovBizProjectBaseinfo>> entry : groupGovMap.entrySet()) {
            FundStatisticsVO.AmountData govAmount = new FundStatisticsVO.AmountData();
            List<GovBizProjectBaseinfo> bs = entry.getValue();
            List<String> baseProjIds = Lists.newArrayList();
            if (CollUtil.isNotEmpty(bs)) {
                govAmount.setName(bs.get(0).getBaseBuildDeprt());
                baseProjIds = bs.stream().map(GovBizProjectBaseinfo::getBaseProjId)
                        .collect(Collectors.toList());
            }

            List<String> finalBaseProjIds = baseProjIds;
            List<GovBizProjectApply> appliesThis = applies.stream().filter(a -> Objects.nonNull(a.getBaseProjId())
                    && finalBaseProjIds.contains(a.getBaseProjId())).collect(Collectors.toList());
            List<GovBizProjectApprove> approvesThis = approves.stream().filter(a -> Objects.nonNull(a.getBaseProjId())
                    && finalBaseProjIds.contains(a.getBaseProjId())).collect(Collectors.toList());
            List<GovBizProjectProcure> procuresThis = procures.stream().filter(a -> Objects.nonNull(a.getBaseProjId())
                    && finalBaseProjIds.contains(a.getBaseProjId())).collect(Collectors.toList());
            govAmount.setAmount(completeDeductionAmount(Collections.emptyList(),
                    appliesThis, approvesThis, procuresThis));
            govAmounts.add(govAmount);
        }

        //求出TOP10
        return Stream.concat(projectAmounts.stream(), govAmounts.stream())
                .collect(Collectors.toMap(FundStatisticsVO.AmountData::getName, Function.identity(),
                        (v1, v2) -> {
                            v1.setAmount(v1.getAmount().add(v2.getAmount()));
                            return v1;
                        })).values().stream()
                .sorted(Comparator.comparing(FundStatisticsVO.AmountData::getAmount).reversed())
                .limit(10).collect(Collectors.toList());
    }
}
