diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/gov/enumeration/GovProjectStatusEnum.java b/pmapi/src/main/java/com/ningdatech/pmapi/gov/enumeration/GovProjectStatusEnum.java new file mode 100644 index 0000000..4da341b --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/gov/enumeration/GovProjectStatusEnum.java @@ -0,0 +1,47 @@ +package com.ningdatech.pmapi.gov.enumeration; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +import java.util.Objects; + +/** + * GovProjectStatusEnum + * + * @return + * @author ZPF + * @since 2023/10/24 16:27 + */ +@Getter +@AllArgsConstructor +@NoArgsConstructor +public enum GovProjectStatusEnum { + /** + * 项目归集 状态 + */ + APPROVAL("01", "评审中"), + PENDING("02", "待立项"), + REJECTED("03","已驳回"), + APPROVED("04","已立项"), + PURCHASED("05","已采购"), + HAS_PRE_INS("06","已初验"), + HAS_FINAL_INS("07","已终验"), + TERMINATED("00","已终止"); + + private String code; + private String desc; + + public static String getDescByCode(Integer code) { + if (Objects.isNull(code)) { + return StringUtils.EMPTY; + } + for (GovProjectStatusEnum t : GovProjectStatusEnum.values()) { + if (code.equals(t.getCode())) { + return t.desc; + } + } + return StringUtils.EMPTY; + } +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/CockpitStatsStatisticsTask.java b/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/CockpitStatsStatisticsTask.java index 021d549..80a5a61 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/CockpitStatsStatisticsTask.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/CockpitStatsStatisticsTask.java @@ -18,10 +18,13 @@ import com.ningdatech.pmapi.dashboard.model.po.SecrecyPasswordGradePO; import com.ningdatech.pmapi.dashboard.service.ICockpitStatsService; import com.ningdatech.pmapi.expert.entity.ExpertUserFullInfo; import com.ningdatech.pmapi.expert.service.IExpertUserFullInfoService; +import com.ningdatech.pmapi.gov.enumeration.GovProjectStatusEnum; import com.ningdatech.pmapi.gov.model.entity.GovBizProjectApply; +import com.ningdatech.pmapi.gov.model.entity.GovBizProjectApprove; import com.ningdatech.pmapi.gov.model.entity.GovBizProjectBaseinfo; import com.ningdatech.pmapi.gov.model.entity.GovOperationProjectBaseinfo; import com.ningdatech.pmapi.gov.service.IGovBizProjectApplyService; +import com.ningdatech.pmapi.gov.service.IGovBizProjectApproveService; import com.ningdatech.pmapi.gov.service.IGovBizProjectBaseinfoService; import com.ningdatech.pmapi.gov.service.IGovOperationProjectBaseinfoService; import com.ningdatech.pmapi.performance.model.entity.PerformanceAppraisalProject; @@ -30,6 +33,8 @@ import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; import com.ningdatech.pmapi.projectlib.model.entity.Project; import com.ningdatech.pmapi.projectlib.service.IProjectService; import com.ningdatech.pmapi.sys.model.dto.RegionDTO; +import com.ningdatech.pmapi.sys.model.entity.WflowEarlyWarningRecords; +import com.ningdatech.pmapi.sys.service.IEarlyWarningRecordsService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -43,6 +48,7 @@ import java.net.UnknownHostException; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; +import java.util.stream.Stream; /** * @author ZPF @@ -79,10 +85,16 @@ public class CockpitStatsStatisticsTask { private IGovBizProjectBaseinfoService baseinfoService; @Autowired + private IGovBizProjectApplyService applyService; + + @Autowired + private IGovBizProjectApproveService approveService; + + @Autowired private IGovOperationProjectBaseinfoService operationBaseInfoService; @Autowired - private IGovBizProjectApplyService applyService; + private IEarlyWarningRecordsService earlyWarningRecordsService; private List years = Lists.newArrayList(2021,2022,2023,2024,2025); @@ -191,6 +203,18 @@ public class CockpitStatsStatisticsTask { .eq(StringUtils.isNotBlank(regionCode) && !DashboardConstant.CockpitStats.TOTAL.equals(regionCode), GovBizProjectBaseinfo::getBaseAreaCode, regionCode + RegionContant.MORE_CODE)); + List approves = Lists.newArrayList(); + List applies = Lists.newArrayList(); + if(CollUtil.isNotEmpty(baseInfos)){ + List baseProjIds = baseInfos.stream().map(GovBizProjectBaseinfo::getBaseProjId).collect(Collectors.toList()); + approves = approveService.list(Wrappers.lambdaQuery(GovBizProjectApprove.class) + .in(GovBizProjectApprove::getBaseProjId, baseProjIds)); + + applies = applyService.list(Wrappers.lambdaQuery(GovBizProjectApply.class) + .in(GovBizProjectApply::getBaseProjId, baseProjIds)); + } + + //运维备案 List operationBaseInfos = operationBaseInfoService.list(Wrappers.lambdaQuery(GovOperationProjectBaseinfo.class) .eq(GovOperationProjectBaseinfo::getDeleted, Boolean.FALSE) @@ -225,7 +249,8 @@ public class CockpitStatsStatisticsTask { }).collect(Collectors.toList()).size(); cockpitStats.setMonitorOverdueConstructionProjectsNum(overdueConstructionProjectsNum); //1.2 环节滞后项目 - cockpitStats.setMonitorLaggingProjectsNum(0); + cockpitStats.setMonitorLaggingProjectsNum(computeLagging(projects)); + //1.3预审驳回项目 Integer preFailed = projects.stream().filter(p -> { if(Objects.nonNull(p.getStatus()) && @@ -235,6 +260,7 @@ public class CockpitStatsStatisticsTask { return Boolean.FALSE; }).collect(Collectors.toList()).size(); cockpitStats.setMonitorRejectedPreReviewProjectsNum(preFailed); + //1.4 建设方案评审失败 Integer constructionFailed = projects.stream().filter(p -> { if(Objects.nonNull(p.getStatus()) && p.getStatus().equals(ProjectStatusEnum.SCHEME_REVIEW_FAILED.getCode())){ @@ -308,62 +334,92 @@ public class CockpitStatsStatisticsTask { }).collect(Collectors.toList()).size(); cockpitStats.setTopPlanProjectsNum(planProjectNum); //3.2 批复项目数(可以用批复金额来判断) - Integer approvalNum = projects.stream().filter(p -> { + Integer approvalNumDeclared = projects.stream().filter(p -> { if(Objects.nonNull(p.getApprovalAmount())){ return Boolean.TRUE; } return Boolean.FALSE; }).collect(Collectors.toList()).size(); + Integer approvalNumGov = baseInfos.stream().filter(p -> { + if(Objects.nonNull(p.getBaseProjSetProg()) && Lists.newArrayList(GovProjectStatusEnum.APPROVED.getCode(), + GovProjectStatusEnum.PURCHASED.getCode(),GovProjectStatusEnum.HAS_PRE_INS.getCode(), + GovProjectStatusEnum.HAS_FINAL_INS.getCode()).contains(p.getBaseProjSetProg())){ + return Boolean.TRUE; + } + return Boolean.FALSE; + }).collect(Collectors.toList()).size(); + Double approvalAmount = projects.stream().filter(p -> { if(Objects.nonNull(p.getApprovalAmount())){ return Boolean.TRUE; } return Boolean.FALSE; }).mapToDouble(p -> p.getApprovalAmount().doubleValue()).sum(); - cockpitStats.setTopApprovalProjectsNum(approvalNum); - cockpitStats.setTopApprovalProjectsAmount(BigDecimal.valueOf(approvalAmount)); + + Double approvalAmountGov = approves.stream().filter(a -> { + if(Objects.nonNull(a.getBaseInitialReviewTotalMoney())){ + return Boolean.TRUE; + } + return Boolean.FALSE; + }).mapToDouble(a -> a.getBaseInitialReviewTotalMoney().doubleValue()).sum(); + + cockpitStats.setTopApprovalProjectsNum(approvalNumDeclared + approvalNumGov); + cockpitStats.setTopApprovalProjectsAmount(BigDecimal.valueOf(approvalAmount).add(BigDecimal.valueOf(approvalAmountGov))); //3.3 平均建设周期 - OptionalDouble od = projects.stream().mapToInt(p -> { - if (StringUtils.isNotBlank(p.getBuildCycle())) { - try { - Integer buildCycle = Integer.valueOf(p.getBuildCycle()); - return buildCycle; - } catch (Exception e) { - return 0; - } + OptionalDouble od = Stream.concat(projects.stream().map(Project::getBuildCycle), + applies.stream().map(GovBizProjectApply::getBaseProjDuration)).mapToInt(c -> { + try { + Integer buildCycle = Integer.valueOf(c); + return buildCycle; + } catch (Exception e) { + return 0; } - return 0; }).average(); Double average = od.isPresent() ? od.getAsDouble() : 0.0; cockpitStats.setTopAverageConstructionPeriod(average.intValue()); //3.4 在建项目数 采购备案后的项目 Integer contructionNum = projects.stream().filter(p -> { - if(Objects.nonNull(p.getStatus()) && p.getStatus().compareTo(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode()) >= 0){ + if(Objects.nonNull(p.getStatus()) && + p.getStatus().compareTo(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode()) >= 0 + && p.getStatus().compareTo(ProjectStatusEnum.ACCEPTED.getCode()) < 0){ return Boolean.TRUE; } return Boolean.FALSE; }).collect(Collectors.toList()).size(); - cockpitStats.setTopOngoingProjectsNum(contructionNum); - //4.地图 只要放总数 取的时候 会有逻辑(也要取项目归集) + Integer contructionNumGov = baseInfos.stream().filter(b -> { + if(Objects.nonNull(b.getBaseProjSetProg()) && + Lists.newArrayList(GovProjectStatusEnum.PURCHASED.getCode(),GovProjectStatusEnum.HAS_PRE_INS.getCode()).contains(b.getBaseProjSetProg())){ + return Boolean.TRUE; + } + return Boolean.FALSE; + }).collect(Collectors.toList()).size(); + cockpitStats.setTopOngoingProjectsNum(contructionNum + contructionNumGov); + //4.地图 只要放总数 取的时候 会有逻辑(也要取项目归集) cockpitStats.setProjectsTotal(projects.size() + baseProjCount); //5.下面项目状态数 //5.1 处于计划 (单位内部) Integer inPlanNum = projects.stream().filter(p -> { - if(Objects.nonNull(p.getStatus()) && p.getStatus().equals(ProjectStatusEnum.UNDER_INTERNAL_AUDIT.getCode())){ + if(Objects.nonNull(p.getStatus()) && + p.getStatus().equals(ProjectStatusEnum.UNDER_INTERNAL_AUDIT.getCode())){ return Boolean.TRUE; } return Boolean.FALSE; }).collect(Collectors.toList()).size(); cockpitStats.setProjectsTotalPlan(inPlanNum); + //5.2 处于申报 (预审) Integer inApplyNum = projects.stream().filter(p -> { - if(Objects.nonNull(p.getStatus()) && p.getStatus().equals(ProjectStatusEnum.PRE_APPLYING.getCode())){ + if(Objects.nonNull(p.getStatus()) && + p.getStatus().compareTo(ProjectStatusEnum.UNDER_INTERNAL_AUDIT.getCode()) > 0 + && p.getStatus().compareTo(ProjectStatusEnum.TO_BE_APPROVED.getCode()) <= 0){ return Boolean.TRUE; } return Boolean.FALSE; }).collect(Collectors.toList()).size(); + cockpitStats.setProjectsTotalApply(inApplyNum); + //5.3 处于审批 (建设方案) Integer inApproveNum = projects.stream().filter(p -> { if(Objects.nonNull(p.getStatus()) && p.getStatus().equals(ProjectStatusEnum.SCHEME_UNDER_REVIEW.getCode())){ @@ -373,14 +429,8 @@ public class CockpitStatsStatisticsTask { }).collect(Collectors.toList()).size(); cockpitStats.setProjectsTotalApprove(inApproveNum); //5.4 建设 (建设中) - Integer inContructionNum = projects.stream().filter(p -> { - if(Objects.nonNull(p.getStatus()) && - p.getStatus().equals(ProjectStatusEnum.UNDER_CONSTRUCTION.getCode())){ - return Boolean.TRUE; - } - return Boolean.FALSE; - }).collect(Collectors.toList()).size(); - cockpitStats.setProjectsTotalConstruction(inContructionNum); + cockpitStats.setProjectsTotalConstruction(contructionNum + contructionNumGov); + //5.5 验收 和 绩效 可以一起查 List inAccpetProjects = projects.stream().filter(p -> { if(Objects.nonNull(p.getStatus()) && @@ -389,15 +439,23 @@ public class CockpitStatsStatisticsTask { } return Boolean.FALSE; }).collect(Collectors.toList()); + List inAccpetProjectsGov = baseInfos.stream().filter(b -> { + if(Objects.nonNull(b.getBaseProjSetProg()) && + b.getBaseProjSetProg().equals(GovProjectStatusEnum.HAS_FINAL_INS.getCode())){ + return Boolean.TRUE; + } + return Boolean.FALSE; + }).collect(Collectors.toList()); + List inAccpetCodes = inAccpetProjects.stream().map(Project::getProjectCode).collect(Collectors.toList()); List performances = performanceAppraisalProjectService.list(Wrappers.lambdaQuery(PerformanceAppraisalProject.class) .in(CollUtil.isNotEmpty(inAccpetCodes),PerformanceAppraisalProject::getProjectCode, inAccpetCodes) .in(CollUtil.isEmpty(inAccpetCodes),PerformanceAppraisalProject::getProjectCode, Lists.newArrayList("NONE")) .isNotNull(PerformanceAppraisalProject::getVerifyTotalScore)); - cockpitStats.setProjectsTotalAccept(inAccpetProjects.size() - performances.size()); + cockpitStats.setProjectsTotalAccept(inAccpetProjects.size() + inAccpetProjectsGov.size()); cockpitStats.setProjectsTotalPerformance(performances.size()); cockpitStats.setProjectsTotalLogOff(0); - cockpitStats.setProjectsTotalOperation(0); + cockpitStats.setProjectsTotalOperation(inAccpetProjects.size() + inAccpetProjectsGov.size() + operationBaseInfos.size()); //6.项目效益 cockpitStats.setExcellentBestAppNum(0); @@ -522,6 +580,30 @@ public class CockpitStatsStatisticsTask { return cockpitStats; } + /** + * 计算环节滞后项目 + * @param projects + * @return + */ + private Integer computeLagging(List projects) { + List projectCodes = projects.stream().map(Project::getProjectCode).collect(Collectors.toList()); + Map map = projects.stream().collect(Collectors.toMap(p -> p.getProjectCode(), p -> p)); + List records = earlyWarningRecordsService.list(Wrappers.lambdaQuery(WflowEarlyWarningRecords.class) + .in(WflowEarlyWarningRecords::getProjectCode, projectCodes)); + return records.stream().mapToInt(r -> { + if(!map.containsKey(r.getProjectCode())){ + return 0; + } + Project project = map.get(r.getProjectCode()); + //如果状态 相等 说明预警了 但是没处理 +1 + if(Objects.nonNull(project.getStatus()) && Objects.nonNull(r.getProjectStatus()) && + project.getStatus().equals(r.getProjectStatus())){ + return 1; + } + return 0; + }).sum(); + } + private void buidMonitorRise(CockpitStats cockpitStats, CockpitStats thisYearData, CockpitStats lastYearData) { if(Objects.isNull(thisYearData) || Objects.isNull(lastYearData)){ return;