diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/common/enumeration/CommonEnum.java b/pmapi/src/main/java/com/ningdatech/pmapi/common/enumeration/CommonEnum.java index b4c5c10..be73781 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/common/enumeration/CommonEnum.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/common/enumeration/CommonEnum.java @@ -26,7 +26,9 @@ public enum CommonEnum { LS_QY(331126,"庆元县",2), LS_JN(331127,"景宁畲族自治县",2), LS_LQ(331181,"龙泉市",2), - LS_KFQ(331199,"开发区",2); + LS_KFQ(331199,"开发区",2), + ZWDD(0,"浙政钉",3), + MOBILE(1,"短信",3); private Integer code; private String desc; diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/common/handler/GlobalResponseHandler.java b/pmapi/src/main/java/com/ningdatech/pmapi/common/handler/GlobalResponseHandler.java index 2c0646c..53d9cb1 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/common/handler/GlobalResponseHandler.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/common/handler/GlobalResponseHandler.java @@ -32,7 +32,9 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; "com.ningdatech.pmapi.performance.controller", "com.ningdatech.pmapi.irs.controller", "com.ningdatech.pmapi.safety.controller", - "com.ningdatech.pmapi.portrait.controller" + "com.ningdatech.pmapi.portrait.controller", + "com.ningdatech.pmapi.irs.controller", + "com.ningdatech.pmapi.dashboard.controller" }) public class GlobalResponseHandler implements ResponseBodyAdvice { diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/constant/AnalysisBasicConstant.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/constant/AnalysisBasicConstant.java new file mode 100644 index 0000000..17c455e --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/constant/AnalysisBasicConstant.java @@ -0,0 +1,16 @@ +package com.ningdatech.pmapi.dashboard.constant; + +/** + * @author liuxinxin + * @date 2023/8/2 下午2:46 + */ + +public class AnalysisBasicConstant { + + + /** + * 丽水市区域编码 + */ + public static final String LS_REGION_CODE = "331100"; + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/constant/ChartTypeEnum.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/constant/ChartTypeEnum.java new file mode 100644 index 0000000..cdcb0ec --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/constant/ChartTypeEnum.java @@ -0,0 +1,65 @@ +package com.ningdatech.pmapi.dashboard.constant; + +/** + * @author liuxinxin + * @date 2023/8/2 下午2:52 + */ + +public enum ChartTypeEnum { + + /** + * 各区域专家数量分布 + */ + REGION_EXPERT_NUMBER_CHART, + + /** + * 各区域专家学历分布 + */ + REGION_EXPERT_EDUCATION_CHART, + + /** + * 各区域专家职称级别分布 + */ + REGION_EXPERT_TITLE_LEVEL_CHART, + + /** + * 各类型评审次数 + */ + MEETING_TYPE_CNT_CHART, + + /** + * 项目增补情况 + */ + PROJECT_SUPPLEMENTATION_STATUS_CHART, + + /** + * 各类型项目数量 + */ + EACH_TYPE_QUANTITY_OF_PROJECT_CHART, + + /** + * 各区域项目数量 + */ + PROJECTS_NUMBER_IN_EACH_REGION_CHART, + + /** + * 各领域项目数量 + */ + PROJECTS_NUMBER_IN_VARIOUS_FIELDS_CHART, + + /** + * 各阶段项目数量 + */ + PROJECTS_NUMBER_IN_EACH_STAGE_CHART, + + /** + * 各领域项目投资金额 + */ + PROJECTS_INVESTMENT_AMOUNT_IN_VARIOUS_FIELDS_CHART, + + /** + * 各区域项目投资情况 + */ + PROJECTS_INVESTMENT_SITUATION_IN_VARIOUS_REGIONS + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/controller/DashboardController.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/controller/DashboardController.java new file mode 100644 index 0000000..f5a93fe --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/controller/DashboardController.java @@ -0,0 +1,65 @@ +package com.ningdatech.pmapi.dashboard.controller; + +import com.ningdatech.log.annotation.WebLog; +import com.ningdatech.pmapi.dashboard.manage.DashboardExpertManage; +import com.ningdatech.pmapi.dashboard.manage.DashboardProjectManage; +import com.ningdatech.pmapi.dashboard.model.po.QueryYearPO; +import com.ningdatech.pmapi.dashboard.model.vo.DashboardInvestmentSummaryVO; +import com.ningdatech.pmapi.dashboard.model.vo.DashboardProjectCntSummaryVO; +import com.ningdatech.pmapi.dashboard.model.vo.DashboardProjectSummaryVO; +import com.ningdatech.pmapi.dashboard.model.vo.ExpertDashboardSummaryVO; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.validation.Valid; + +/** + * @author liuxinxin + * @date 2023/8/2 上午10:36 + */ + +@RestController +@RequestMapping("/api/v1/dashboard") +@Validated +@RequiredArgsConstructor +@Api(value = "DashboardController", tags = "驾驶舱相关接口") +public class DashboardController { + + private final DashboardExpertManage dashboardExpertManage; + private final DashboardProjectManage dashboardProjectManage; + + @PostMapping("/expert-summary") + @ApiOperation("专家驾驶舱统计数据") + @WebLog("专家驾驶舱统计数据") + public ExpertDashboardSummaryVO getExpertDashboardSummary(@Valid @RequestBody QueryYearPO queryYearPO) { + return dashboardExpertManage.getExpertDashboardSummary(queryYearPO); + } + + @PostMapping("project-summary") + @ApiOperation("驾驶舱项目总览") + @WebLog("驾驶舱项目总览") + public DashboardProjectSummaryVO getProjectSummary(@Valid @RequestBody QueryYearPO queryYearPO) { + return dashboardProjectManage.getProjectSummary(queryYearPO); + } + + @PostMapping("project-cnt-summary") + @ApiOperation("驾驶舱项目数量") + @WebLog("驾驶舱项目数量") + public DashboardProjectCntSummaryVO getProjectCntSummary(@Valid @RequestBody QueryYearPO queryYearPO) { + return dashboardProjectManage.getProjectCntSummary(queryYearPO); + } + + @PostMapping("investment-summary") + @ApiOperation("驾驶舱投资金额") + @WebLog("驾驶舱投资金额") + public DashboardInvestmentSummaryVO getInvestmentSummary(@Valid @RequestBody QueryYearPO queryYearPO) { + return dashboardProjectManage.getInvestmentSummary(queryYearPO); + } + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/helper/DashboardChartAssembler.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/helper/DashboardChartAssembler.java new file mode 100644 index 0000000..749f350 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/helper/DashboardChartAssembler.java @@ -0,0 +1,106 @@ +package com.ningdatech.pmapi.dashboard.helper; + +import cn.hutool.core.collection.CollUtil; +import com.ningdatech.pmapi.dashboard.constant.ChartTypeEnum; +import com.ningdatech.pmapi.dashboard.model.basic.AnalysisChart; +import com.ningdatech.pmapi.dashboard.model.basic.AnalysisData; +import com.ningdatech.pmapi.meta.helper.DictionaryCache; +import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; +import com.ningdatech.pmapi.projectlib.model.entity.Project; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * @author liuxinxin + * @date 2023/8/4 下午2:36 + */ + +@Component +@RequiredArgsConstructor +public class DashboardChartAssembler { + + private final DictionaryCache dictionaryCache; + + + public static AnalysisChart buildProjectStateAnalysisChart(Map> projectGroupMap, ChartTypeEnum chartTypeEnum) { + AnalysisChart analysisChart = new AnalysisChart(); + List dataList = new ArrayList<>(); + analysisChart.setChartType(chartTypeEnum); + analysisChart.setDataList(dataList); + for (Integer key : projectGroupMap.keySet()) { + AnalysisData analysisData = new AnalysisData(); + String chartKey = ProjectStatusEnum.getDesc(key); + List projectList = projectGroupMap.get(key); + analysisData.setKey(chartKey); + analysisData.setValue(CollUtil.isEmpty(projectList) ? 0 : projectList.size()); + dataList.add(analysisData); + } + return analysisChart; + } + + public static AnalysisChart buildInvestmentAnalysisChart(Map keyValueMap + , Map> projectGroupMap, ChartTypeEnum chartTypeEnum) { + AnalysisChart analysisChart = new AnalysisChart(); + List dataList = new ArrayList<>(); + analysisChart.setChartType(chartTypeEnum); + analysisChart.setDataList(dataList); + for (T key : keyValueMap.keySet()) { + AnalysisData analysisData = new AnalysisData(); + String chartKey = keyValueMap.get(key); + List projectList = projectGroupMap.get(key); + + BigDecimal approvedTotalInvestmentIncreaseSum = new BigDecimal("0"); + if (CollUtil.isNotEmpty(projectList)) { + for (Project project : projectList) { + BigDecimal approvedTotalInvestmentIncrease = project.getApprovedTotalInvestmentIncrease(); + if (Objects.nonNull(approvedTotalInvestmentIncrease)) { + approvedTotalInvestmentIncreaseSum.add(approvedTotalInvestmentIncrease); + } + } + } + analysisData.setKey(chartKey); + analysisData.setValue(approvedTotalInvestmentIncreaseSum); + dataList.add(analysisData); + } + return analysisChart; + } + + public static AnalysisChart buildAnalysisChart(Map keyValueMap + , Map> projectGroupMap, ChartTypeEnum chartTypeEnum) { + AnalysisChart analysisChart = new AnalysisChart(); + List dataList = new ArrayList<>(); + analysisChart.setChartType(chartTypeEnum); + analysisChart.setDataList(dataList); + for (T key : keyValueMap.keySet()) { + AnalysisData analysisData = new AnalysisData(); + String chartKey = keyValueMap.get(key); + List projectList = projectGroupMap.get(key); + analysisData.setKey(chartKey); + analysisData.setValue(CollUtil.isEmpty(projectList) ? 0 : projectList.size()); + dataList.add(analysisData); + } + return analysisChart; + } + + public AnalysisChart assemblerAnalysisChart(Map> dictionaryCodeIdMap + , ChartTypeEnum chartTypeEnum) { + AnalysisChart analysisChart = new AnalysisChart(); + List dataList = new ArrayList<>(); + analysisChart.setChartType(chartTypeEnum); + analysisChart.setDataList(dataList); + + for (String dictionaryCode : dictionaryCodeIdMap.keySet()) { + AnalysisData analysisData = new AnalysisData(); + analysisData.setKey(dictionaryCache.getByCode(dictionaryCode).getName()); + analysisData.setValue(dictionaryCodeIdMap.get(dictionaryCode).size()); + dataList.add(analysisData); + } + return analysisChart; + } +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/helper/DashboardHelper.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/helper/DashboardHelper.java new file mode 100644 index 0000000..738cac3 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/helper/DashboardHelper.java @@ -0,0 +1,77 @@ +package com.ningdatech.pmapi.dashboard.helper; + +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ningdatech.pmapi.dashboard.constant.AnalysisBasicConstant; +import com.ningdatech.pmapi.sys.model.entity.Region; +import com.ningdatech.pmapi.sys.service.IRegionService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author liuxinxin + * @date 2023/8/3 下午3:13 + */ + +@Component +@RequiredArgsConstructor +public class DashboardHelper { + + private final IRegionService iRegionService; + + /** + * 获取丽水区域相关信息 + */ + public Map getLiShuiRegionCodeNameMap() { + List regionList = iRegionService.list(Wrappers.lambdaQuery(Region.class) + .eq(Region::getParentCode, AnalysisBasicConstant.LS_REGION_CODE)); + Map regionCodeNameMap = regionList.stream().collect(Collectors.toMap(Region::getRegionCode, Region::getRegionName)); + return regionCodeNameMap; + } + + /** + * 获取增补情况键值表 + */ + public Map getTemporaryAugmentMap() { +// 0:否 1:是 + Map map = new HashMap<>(); + map.put(1, "增补项目"); + map.put(0, "非增补项目"); + return map; + } + + + /** + * 获取项目类型键值表 + */ + public Map getProjectTypeMap() { + // "项目类型 1:建设 2:运维 + Map map = new HashMap<>(); + map.put(1, "建设"); + map.put(2, "运维"); + return map; + } + + /** + * 获取项目类型键值表 + */ + public Map getBizDomainMap() { + // 综合业务领域 1: '党政机关整体智治',2: '数字政府',3: '数字经济',4: '数字社会',7: '数字文化',5: '数字法治',6: '一体化智能化公共数据平台', 8: '基层智治' + Map map = new HashMap<>(); + map.put(1, "党政机关整体智治"); + map.put(2, "数字政府"); + map.put(3, "数字经济"); + map.put(4, "数字社会"); + map.put(5, "数字文化"); + map.put(6, "数字法治"); + map.put(7, "一体化智能化公共数据平台"); + map.put(8, "基层智治"); + return map; + } + + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/manage/DashboardExpertManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/manage/DashboardExpertManage.java new file mode 100644 index 0000000..d53a236 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/manage/DashboardExpertManage.java @@ -0,0 +1,168 @@ +package com.ningdatech.pmapi.dashboard.manage; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ningdatech.pmapi.dashboard.constant.ChartTypeEnum; +import com.ningdatech.pmapi.dashboard.helper.DashboardChartAssembler; +import com.ningdatech.pmapi.dashboard.helper.DashboardHelper; +import com.ningdatech.pmapi.dashboard.model.basic.AnalysisChart; +import com.ningdatech.pmapi.dashboard.model.basic.AnalysisData; +import com.ningdatech.pmapi.dashboard.model.basic.StarExpertBO; +import com.ningdatech.pmapi.dashboard.model.po.QueryYearPO; +import com.ningdatech.pmapi.dashboard.model.vo.ExpertDashboardSummaryVO; +import com.ningdatech.pmapi.expert.constant.ExpertUserInfoStepEnum; +import com.ningdatech.pmapi.expert.entity.ExpertUserFullInfo; +import com.ningdatech.pmapi.expert.service.IExpertUserFullInfoService; +import com.ningdatech.pmapi.meeting.entity.domain.Meeting; +import com.ningdatech.pmapi.meeting.entity.domain.MeetingExpertJudge; +import com.ningdatech.pmapi.meeting.entity.enumeration.MeetingStatusEnum; +import com.ningdatech.pmapi.meeting.service.IMeetingExpertJudgeService; +import com.ningdatech.pmapi.meeting.service.IMeetingService; +import com.ningdatech.pmapi.meta.constant.DictExpertInfoTypeEnum; +import com.ningdatech.pmapi.meta.model.entity.ExpertDictionary; +import com.ningdatech.pmapi.meta.service.IExpertDictionaryService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * @author liuxinxin + * @date 2023/8/2 上午10:39 + */ + +@Component +@RequiredArgsConstructor +public class DashboardExpertManage { + + private final DashboardHelper dashboardHelper; + private final IExpertUserFullInfoService iExpertUserFullInfoService; + private final IMeetingService iMeetingService; + // private final DictionaryCache dictionaryCache; + private final IMeetingExpertJudgeService iMeetingExpertJudgeService; + private final IExpertDictionaryService iExpertDictionaryService; + private final DashboardChartAssembler dashboardChartAssembler; + + + public ExpertDashboardSummaryVO getExpertDashboardSummary(QueryYearPO queryYearPO) { + String queryRegionCode = queryYearPO.getRegionCode(); + List analysisChartList = new ArrayList<>(); + + // 获取丽水区域 code name Map + Map liShuiRegionCodeNameMap = dashboardHelper.getLiShuiRegionCodeNameMap(); + // 获取库内所有的专家列表 + List evidenceHasBeenSubmittedExpertInfoList = iExpertUserFullInfoService.list(Wrappers.lambdaQuery(ExpertUserFullInfo.class) + .eq(ExpertUserFullInfo::getUserInfoStep, ExpertUserInfoStepEnum.EVIDENCE_HAS_BEEN_SUBMITTED.getKey())); + + // 专家regionCode分组map列表 + Map> regionCodeExpertMap = evidenceHasBeenSubmittedExpertInfoList.stream() + .collect(Collectors.groupingBy(ExpertUserFullInfo::getRegionCode)); + + // 各区域专家数量 + AnalysisChart regionExpertNumberChartAnalysisChart = new AnalysisChart(); + List regionExpertNumberChartDataList = new ArrayList<>(); + regionExpertNumberChartAnalysisChart.setChartType(ChartTypeEnum.REGION_EXPERT_NUMBER_CHART); + regionExpertNumberChartAnalysisChart.setDataList(regionExpertNumberChartDataList); + for (String regionCode : liShuiRegionCodeNameMap.keySet()) { + AnalysisData analysisData = new AnalysisData(); + String regionName = liShuiRegionCodeNameMap.get(regionCode); + List expertUserFullInfoList = regionCodeExpertMap.get(regionCode); + Integer expertCnt = 0; + if (CollectionUtil.isNotEmpty(expertUserFullInfoList)) { + expertCnt = expertUserFullInfoList.size(); + } + analysisData.setKey(regionName); + analysisData.setValue(expertCnt); + regionExpertNumberChartDataList.add(analysisData); + } + analysisChartList.add(regionExpertNumberChartAnalysisChart); + + // 查询区域的专家id 列表 + List regionDegreeExpertIdList = new ArrayList<>(); + if (StringUtils.isNotBlank(queryRegionCode)) { + List expertUserFullInfoList = regionCodeExpertMap.get(queryRegionCode); + if (CollectionUtil.isNotEmpty(expertUserFullInfoList)) { + regionDegreeExpertIdList = expertUserFullInfoList.stream() + .map(ExpertUserFullInfo::getUserId) + .collect(Collectors.toList()); + } + } else { + regionDegreeExpertIdList = evidenceHasBeenSubmittedExpertInfoList.stream() + .map(ExpertUserFullInfo::getUserId) + .collect(Collectors.toList()); + } + + if (CollectionUtil.isNotEmpty(regionDegreeExpertIdList)) { + // 区域学历分布 + List degreeExpertDictionaryList = iExpertDictionaryService + .listByUserId(regionDegreeExpertIdList, DictExpertInfoTypeEnum.DEGREE); + Map> degreeCodeMap = degreeExpertDictionaryList.stream() + .map(ExpertDictionary::getDictionaryCode) + .collect(Collectors.groupingBy(Function.identity())); + AnalysisChart regionExpertEducationChartAnalysisChart = + dashboardChartAssembler.assemblerAnalysisChart(degreeCodeMap, ChartTypeEnum.REGION_EXPERT_EDUCATION_CHART); + analysisChartList.add(regionExpertEducationChartAnalysisChart); + + // 区域职称级别分布 + List titleLevelExpertDictionaryList = iExpertDictionaryService + .listByUserId(regionDegreeExpertIdList, DictExpertInfoTypeEnum.TITLE_LEVEL); + Map> titleLevelCodeMap = titleLevelExpertDictionaryList.stream() + .collect(Collectors.groupingBy(ExpertDictionary::getDictionaryCode)); + AnalysisChart regionExpertTitleLevelChartAnalysisChart = + dashboardChartAssembler.assemblerAnalysisChart(titleLevelCodeMap, ChartTypeEnum.REGION_EXPERT_TITLE_LEVEL_CHART); + analysisChartList.add(regionExpertTitleLevelChartAnalysisChart); + } + + // 评审次数 + List normalMeetingList = iMeetingService.list(Wrappers.lambdaQuery(Meeting.class) + .eq(StringUtils.isNotBlank(queryRegionCode), Meeting::getRegionCode, queryRegionCode) + .ne(Meeting::getStatus, MeetingStatusEnum.CANCELED.getCode())); + Integer meetingCnt = normalMeetingList.size(); + + // 各类型评审次数 + Map> meetingTypeMap = normalMeetingList.stream().collect(Collectors.groupingBy(Meeting::getType)); + AnalysisChart meetingTypeCntChartAnalysisChart = + dashboardChartAssembler.assemblerAnalysisChart(meetingTypeMap, ChartTypeEnum.MEETING_TYPE_CNT_CHART); + analysisChartList.add(meetingTypeCntChartAnalysisChart); + + // 明星专家列表 + List starExpertList = new ArrayList<>(); + List meetingExpertJudgeList = iMeetingExpertJudgeService.list(); + Map> expertIdMeetingExpertJudgeMap = meetingExpertJudgeList.stream() + .collect(Collectors.groupingBy(MeetingExpertJudge::getExpertId)); + Map expertIdExpertNameMap = evidenceHasBeenSubmittedExpertInfoList.stream() + .collect(Collectors.toMap(ExpertUserFullInfo::getUserId, ExpertUserFullInfo::getExpertName)); + + for (Long expertId : expertIdMeetingExpertJudgeMap.keySet()) { + String expertName = expertIdExpertNameMap.get(expertId); + List expertMeetingExpertJudgeList = expertIdMeetingExpertJudgeMap.get(expertId); + DoubleSummaryStatistics statistics = expertMeetingExpertJudgeList + .stream().filter(r -> Objects.nonNull(r.getScore())) + .map(MeetingExpertJudge::getScore).mapToDouble(Number::doubleValue).summaryStatistics(); + double average = statistics.getAverage(); + StarExpertBO starExpertBO = new StarExpertBO(); + starExpertBO.setAveragePerformanceScore(average); + starExpertBO.setExpertId(expertId); + starExpertBO.setExpertName(expertName); + starExpertList.add(starExpertBO); + } + starExpertList = starExpertList.stream() + .sorted(Comparator.comparing(StarExpertBO::getAveragePerformanceScore) + .reversed()).collect(Collectors.toList()); + if (starExpertList.size() > 5) { + starExpertList = starExpertList.subList(0, 5); + } + + // 装配返回类 + ExpertDashboardSummaryVO expertDashboardSummaryVO = new ExpertDashboardSummaryVO(); + expertDashboardSummaryVO.setMeetingCnt(meetingCnt); + expertDashboardSummaryVO.setStarExpertList(starExpertList); + expertDashboardSummaryVO.setAnalysisChartList(analysisChartList); + return expertDashboardSummaryVO; + } + +} + diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/manage/DashboardProjectManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/manage/DashboardProjectManage.java new file mode 100644 index 0000000..663fac5 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/manage/DashboardProjectManage.java @@ -0,0 +1,317 @@ +package com.ningdatech.pmapi.dashboard.manage; + +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ningdatech.pmapi.dashboard.constant.ChartTypeEnum; +import com.ningdatech.pmapi.dashboard.helper.DashboardChartAssembler; +import com.ningdatech.pmapi.dashboard.helper.DashboardHelper; +import com.ningdatech.pmapi.dashboard.model.basic.AnalysisChart; +import com.ningdatech.pmapi.dashboard.model.basic.CompanyProjectCntBO; +import com.ningdatech.pmapi.dashboard.model.basic.ProjectATIISBO; +import com.ningdatech.pmapi.dashboard.model.po.QueryYearPO; +import com.ningdatech.pmapi.dashboard.model.vo.DashboardInvestmentSummaryVO; +import com.ningdatech.pmapi.dashboard.model.vo.DashboardProjectCntSummaryVO; +import com.ningdatech.pmapi.dashboard.model.vo.DashboardProjectSummaryVO; +import com.ningdatech.pmapi.projectdeclared.model.entity.Purchase; +import com.ningdatech.pmapi.projectdeclared.service.IPurchaseService; +import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; +import com.ningdatech.pmapi.projectlib.model.entity.Project; +import com.ningdatech.pmapi.projectlib.model.entity.ProjectDelayApply; +import com.ningdatech.pmapi.projectlib.service.INdProjectDelayApplyService; +import com.ningdatech.pmapi.projectlib.service.IProjectService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.math.BigDecimal; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author liuxinxin + * @date 2023/8/2 上午10:39 + */ + +@Component +@RequiredArgsConstructor +public class DashboardProjectManage { + + private final IProjectService iProjectService; + private final INdProjectDelayApplyService iProjectDelayApplyService; + private final DashboardHelper dashboardHelper; + private final IPurchaseService iPurchaseService; + + public DashboardProjectSummaryVO getProjectSummary(QueryYearPO queryYearPO) { + // 预算年度 + Integer year = queryYearPO.getYear(); + String regionCode = queryYearPO.getRegionCode(); + List allProjectWithRepeatList = iProjectService.list(Wrappers.lambdaQuery(Project.class) + .eq(Objects.nonNull(year), Project::getProjectYear, year) + .eq(StringUtils.isNotBlank(regionCode), Project::getAreaCode, regionCode) + ); + List allProjectList = allProjectWithRepeatList.stream() + .filter(r -> r.getNewest()).collect(Collectors.toList()); + + List allProjectIdWithRepeatList = allProjectWithRepeatList.stream().map(Project::getId).collect(Collectors.toList()); + + // 项目总数 + Integer projectCnt = allProjectList.size(); + + // 待立项项目数 + List toBeApprovedProjectList = allProjectList.stream() + .filter(r -> ProjectStatusEnum.TO_BE_APPROVED.getCode().equals(r.getStatus())) + .collect(Collectors.toList()); + Integer toBeApprovedProjectCnt = toBeApprovedProjectList.size(); + + // 已立项项目数 + Integer approvedProjectCnt = projectCnt - toBeApprovedProjectCnt; + + // 项目立项率 + Double projectApprovalRate = new BigDecimal((float) approvedProjectCnt / projectCnt).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); + + // 项目申报总金额 + List declareAmountList = allProjectList.stream().filter(r -> Objects.nonNull(r.getDeclareAmount())) + .map(Project::getDeclareAmount). + collect(Collectors.toList()); + BigDecimal declareAmountSum = new BigDecimal("0"); + for (BigDecimal declareAmount : declareAmountList) { + declareAmountSum.add(declareAmount); + } + + // 项目批复总金额 + List approvedTotalInvestmentIncreaseList = allProjectList.stream().filter(r -> Objects.nonNull(r.getApprovedTotalInvestmentIncrease())) + .map(Project::getApprovedTotalInvestmentIncrease) + .collect(Collectors.toList()); + BigDecimal approvedTotalInvestmentIncreaseSum = new BigDecimal("0"); + for (BigDecimal approvedTotalInvestmentIncrease : approvedTotalInvestmentIncreaseList) { + approvedTotalInvestmentIncreaseSum.add(approvedTotalInvestmentIncrease); + } + + // 资金核定率 + BigDecimal fundApprovalRate = new BigDecimal("0"); + if (new BigDecimal("0").compareTo(approvedTotalInvestmentIncreaseSum) != 0) { + fundApprovalRate = declareAmountSum.divide(approvedTotalInvestmentIncreaseSum, 2, BigDecimal.ROUND_HALF_UP); + } + + + // 项目采购总金额 + BigDecimal projectProcurementTotalAmount = new BigDecimal("0"); + List purchaseList = iPurchaseService.list(Wrappers.lambdaQuery(Purchase.class) + .in(Purchase::getProjectId, allProjectIdWithRepeatList)); + for (Purchase purchase : purchaseList) { + BigDecimal transactionAmount = purchase.getTransactionAmount(); + if (Objects.nonNull(transactionAmount)) { + projectProcurementTotalAmount.add(transactionAmount); + } + } + +// 项目画像 + + // 延期项目数 延期占比 + List projectDelayApplyList = iProjectDelayApplyService + .list(Wrappers.lambdaQuery(ProjectDelayApply.class) + .in(ProjectDelayApply::getProjectId, allProjectIdWithRepeatList)); + Map> projectDelayApplyListMap = projectDelayApplyList.stream().collect(Collectors.groupingBy(ProjectDelayApply::getProjectId)); + Integer delayProjectCnt = projectDelayApplyListMap.keySet().size(); + Double delayProportion = new BigDecimal((float) delayProjectCnt / projectCnt).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); + + // 项目变更数量 项目变更金额 + List changedProjectList = new ArrayList<>(); + Map> allProjectMap = allProjectWithRepeatList.stream().collect(Collectors.groupingBy(Project::getProjectCode)); + for (String projectCode : allProjectMap.keySet()) { + List projectList = allProjectMap.get(projectCode); + Project newestProject = projectList.stream() + .filter(r -> r.getNewest()) + .collect(Collectors.toList()).get(0); + Boolean isChanged = false; + for (Project project : projectList) { + Boolean newest = project.getNewest(); + Boolean isBackReject = project.getIsBackReject(); + if (!newest && isBackReject) { + isChanged = true; + break; + } + } + if (isChanged) { + changedProjectList.add(newestProject); + } + } + Integer changedProjectCnt = changedProjectList.size(); + + // 项目变更金额 + BigDecimal changedProjectContractAmountSum = new BigDecimal("0"); + for (Project project : changedProjectList) { + BigDecimal contractAmount = project.getContractAmount(); + if (Objects.nonNull(contractAmount)) { + changedProjectContractAmountSum.add(contractAmount); + } + } + + // 装配返回VO + DashboardProjectSummaryVO dashboardProjectSummaryVO = new DashboardProjectSummaryVO(); + dashboardProjectSummaryVO.setProjectCnt(projectCnt); + dashboardProjectSummaryVO.setApprovedProjectCnt(approvedProjectCnt); + dashboardProjectSummaryVO.setToBeApprovedProjectCnt(toBeApprovedProjectCnt); + dashboardProjectSummaryVO.setProjectApprovalRate(projectApprovalRate); + dashboardProjectSummaryVO.setDeclareAmountSum(declareAmountSum); + dashboardProjectSummaryVO.setApprovedTotalInvestmentIncreaseSum(approvedTotalInvestmentIncreaseSum); + + dashboardProjectSummaryVO.setDelayProjectCnt(delayProjectCnt); + dashboardProjectSummaryVO.setDelayProportion(delayProportion); + dashboardProjectSummaryVO.setChangedProjectCnt(changedProjectCnt); + dashboardProjectSummaryVO.setChangedProjectContractAmountSum(changedProjectContractAmountSum); + dashboardProjectSummaryVO.setFundApprovalRate(fundApprovalRate); + return dashboardProjectSummaryVO; + } + + public DashboardProjectCntSummaryVO getProjectCntSummary(QueryYearPO queryYearPO) { + // 预算年度 + Integer year = queryYearPO.getYear(); + String regionCode = queryYearPO.getRegionCode(); + List allProjectList = iProjectService.list(Wrappers.lambdaQuery(Project.class) + .eq(Project::getNewest, true) + .eq(Objects.nonNull(year), Project::getProjectYear, year) + .eq(StringUtils.isNotBlank(regionCode), Project::getAreaCode, regionCode) + ); + + // 单位项目数量TOP5 + List companyProjectCntTop5List = new ArrayList<>(); + Map> buildOrgNameProjectGroupMap = allProjectList.stream() + .collect(Collectors.groupingBy(Project::getBuildOrgName)); + for (String buildOrgName : buildOrgNameProjectGroupMap.keySet()) { + List projectList = buildOrgNameProjectGroupMap.get(buildOrgName); + CompanyProjectCntBO companyProjectCntBO = new CompanyProjectCntBO(); + companyProjectCntBO.setBuildOrgName(buildOrgName); + companyProjectCntBO.setProjectCnt(projectList.size()); + companyProjectCntTop5List.add(companyProjectCntBO); + } + companyProjectCntTop5List = companyProjectCntTop5List.stream() + .sorted(Comparator.comparing(CompanyProjectCntBO::getProjectCnt).reversed()) + .collect(Collectors.toList()); + if (companyProjectCntTop5List.size() > 5) { + companyProjectCntTop5List = companyProjectCntTop5List.subList(0, 5); + } + + // 项目增补情况 + Map> isTemporaryAugmentGroupMap = allProjectList.stream() + .collect(Collectors.groupingBy(Project::getIsTemporaryAugment)); + Map temporaryAugmentMap = dashboardHelper.getTemporaryAugmentMap(); + AnalysisChart isTemporaryAugmentAnalysisChart = DashboardChartAssembler.buildAnalysisChart(temporaryAugmentMap, isTemporaryAugmentGroupMap + , ChartTypeEnum.PROJECT_SUPPLEMENTATION_STATUS_CHART); + + // 各类型项目数量 + Map> projectTypeGroupMap = allProjectList.stream() + .collect(Collectors.groupingBy(Project::getProjectType)); + Map projectTypeMap = dashboardHelper.getTemporaryAugmentMap(); + AnalysisChart projectTypeAnalysisChart = DashboardChartAssembler.buildAnalysisChart(projectTypeMap, projectTypeGroupMap + , ChartTypeEnum.EACH_TYPE_QUANTITY_OF_PROJECT_CHART); + + // 各区域项目数量 + Map> areaCodeGroupMap = allProjectList.stream() + .collect(Collectors.groupingBy(Project::getAreaCode)); + Map liShuiRegionCodeNameMap = dashboardHelper.getLiShuiRegionCodeNameMap(); + AnalysisChart areaCodeAnalysisChart = DashboardChartAssembler.buildAnalysisChart(liShuiRegionCodeNameMap, areaCodeGroupMap + , ChartTypeEnum.PROJECTS_NUMBER_IN_EACH_REGION_CHART); + + // 各领域项目数量 + Map> bizDomainGroupMap = allProjectList.stream() + .collect(Collectors.groupingBy(Project::getBizDomain)); + Map bizDomainMap = dashboardHelper.getBizDomainMap(); + AnalysisChart bizDomainAnalysisChart = DashboardChartAssembler.buildAnalysisChart(bizDomainMap, bizDomainGroupMap + , ChartTypeEnum.PROJECTS_NUMBER_IN_VARIOUS_FIELDS_CHART); + + // 各阶段项目数量 + Map> projectStateGroupMap = allProjectList.stream() + .collect(Collectors.groupingBy(Project::getStage)); + AnalysisChart projectStateAnalysisChart = DashboardChartAssembler + .buildProjectStateAnalysisChart(projectStateGroupMap, ChartTypeEnum.PROJECTS_NUMBER_IN_EACH_STAGE_CHART); + + DashboardProjectCntSummaryVO dashboardProjectCntSummaryVO = new DashboardProjectCntSummaryVO(); + dashboardProjectCntSummaryVO.setCompanyProjectCntTop5List(companyProjectCntTop5List); + List analysisChartList = new ArrayList<>(); + dashboardProjectCntSummaryVO.setAnalysisChartList(analysisChartList); + analysisChartList.add(isTemporaryAugmentAnalysisChart); + analysisChartList.add(projectTypeAnalysisChart); + analysisChartList.add(bizDomainAnalysisChart); + analysisChartList.add(areaCodeAnalysisChart); + analysisChartList.add(projectStateAnalysisChart); + return dashboardProjectCntSummaryVO; + } + + + public DashboardInvestmentSummaryVO getInvestmentSummary(QueryYearPO queryYearPO) { + // 预算年度 + Integer year = queryYearPO.getYear(); + String regionCode = queryYearPO.getRegionCode(); + List allProjectList = iProjectService.list(Wrappers.lambdaQuery(Project.class) + .eq(Project::getNewest, true) + .eq(Objects.nonNull(year), Project::getProjectYear, year) + .eq(StringUtils.isNotBlank(regionCode), Project::getAreaCode, regionCode) + ); + + // 项目预算TOP5 + List projectATIISTop5List = allProjectList.stream().filter(r -> Objects.nonNull(r.getApprovedTotalInvestmentIncrease())) + .map(r -> { + ProjectATIISBO projectATIISBO = new ProjectATIISBO(); + projectATIISBO.setProjectId(r.getId()); + projectATIISBO.setProjectCode(r.getProjectCode()); + projectATIISBO.setProjectName(r.getProjectName()); + projectATIISBO.setApprovedTotalInvestmentIncrease(r.getApprovedTotalInvestmentIncrease()); + return projectATIISBO; + }).collect(Collectors.toList()); + projectATIISTop5List = projectATIISTop5List.stream() + .sorted(Comparator.comparing(ProjectATIISBO::getApprovedTotalInvestmentIncrease) + .reversed()).collect(Collectors.toList()); + if (projectATIISTop5List.size() > 5) { + projectATIISTop5List = projectATIISTop5List.subList(0, 5); + } + + // 单位预算TOP5 + List companyProjectATIISTop5List = new ArrayList<>(); + Map> buildOrgNameProjectGroupMap = allProjectList.stream() + .collect(Collectors.groupingBy(Project::getBuildOrgName)); + for (String buildOrgName : buildOrgNameProjectGroupMap.keySet()) { + List projectList = buildOrgNameProjectGroupMap.get(buildOrgName); + CompanyProjectCntBO companyProjectCntBO = new CompanyProjectCntBO(); + companyProjectCntBO.setBuildOrgName(buildOrgName); + BigDecimal approvedTotalInvestmentIncreaseSum = new BigDecimal("0"); + for (Project project : projectList) { + BigDecimal approvedTotalInvestmentIncrease = project.getApprovedTotalInvestmentIncrease(); + if (Objects.nonNull(approvedTotalInvestmentIncrease)) { + approvedTotalInvestmentIncreaseSum.add(approvedTotalInvestmentIncrease); + } + } + companyProjectCntBO.setApprovedTotalInvestmentIncreaseSum(approvedTotalInvestmentIncreaseSum); + companyProjectATIISTop5List.add(companyProjectCntBO); + } + companyProjectATIISTop5List = companyProjectATIISTop5List.stream() + .sorted(Comparator.comparing(CompanyProjectCntBO::getApprovedTotalInvestmentIncreaseSum).reversed()) + .collect(Collectors.toList()); + if (companyProjectATIISTop5List.size() > 5) { + companyProjectATIISTop5List = companyProjectATIISTop5List.subList(0, 5); + } + + // 各领域项目投资情况 + Map> bizDomainGroupMap = allProjectList.stream() + .collect(Collectors.groupingBy(Project::getBizDomain)); + Map bizDomainMap = dashboardHelper.getBizDomainMap(); + AnalysisChart bizDomainInvestmentAnalysisChart = DashboardChartAssembler.buildInvestmentAnalysisChart(bizDomainMap, bizDomainGroupMap + , ChartTypeEnum.PROJECTS_INVESTMENT_AMOUNT_IN_VARIOUS_FIELDS_CHART); + + // 各区域项目投资情况 + Map> areaCodeGroupMap = allProjectList.stream() + .collect(Collectors.groupingBy(Project::getAreaCode)); + Map liShuiRegionCodeNameMap = dashboardHelper.getLiShuiRegionCodeNameMap(); + AnalysisChart areaCodeInvestmentAnalysisChart = DashboardChartAssembler.buildInvestmentAnalysisChart(liShuiRegionCodeNameMap, areaCodeGroupMap + , ChartTypeEnum.PROJECTS_INVESTMENT_SITUATION_IN_VARIOUS_REGIONS); + + DashboardInvestmentSummaryVO dashboardInvestmentSummaryVO = new DashboardInvestmentSummaryVO(); + dashboardInvestmentSummaryVO.setCompanyProjectATIISTop5List(companyProjectATIISTop5List); + dashboardInvestmentSummaryVO.setProjectATIISTop5List(projectATIISTop5List); + List analysisChartList = new ArrayList<>(); + dashboardInvestmentSummaryVO.setAnalysisChartList(analysisChartList); + analysisChartList.add(areaCodeInvestmentAnalysisChart); + analysisChartList.add(bizDomainInvestmentAnalysisChart); + return dashboardInvestmentSummaryVO; + } + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/AnalysisChart.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/AnalysisChart.java new file mode 100644 index 0000000..7091913 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/AnalysisChart.java @@ -0,0 +1,25 @@ +package com.ningdatech.pmapi.dashboard.model.basic; + +import com.ningdatech.pmapi.dashboard.constant.ChartTypeEnum; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * @author liuxinxin + * @date 2023/8/2 下午3:02 + */ + +@Data +@ApiModel("图表数据") +public class AnalysisChart { + + @ApiModelProperty("图表数据类型") + private ChartTypeEnum chartType; + + @ApiModelProperty("数据列表") + private List dataList; + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/AnalysisData.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/AnalysisData.java new file mode 100644 index 0000000..448e15d --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/AnalysisData.java @@ -0,0 +1,21 @@ +package com.ningdatech.pmapi.dashboard.model.basic; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author liuxinxin + * @date 2023/8/2 下午2:27 + */ + +@Data +@ApiModel("分析数据基础类") +public class AnalysisData { + + @ApiModelProperty("key") + private String key; + + @ApiModelProperty("值") + private Object value; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/CompanyProjectCntBO.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/CompanyProjectCntBO.java new file mode 100644 index 0000000..ea92abe --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/CompanyProjectCntBO.java @@ -0,0 +1,31 @@ +package com.ningdatech.pmapi.dashboard.model.basic; + +import com.ningdatech.pmapi.common.compare.Compare; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * @author liuxinxin + * @date 2023/8/4 下午3:51 + */ + +@Data +@ApiModel("单位项目数量") +public class CompanyProjectCntBO { + + @ApiModelProperty("建设单位名称") + private String buildOrgName; + + @Compare("建设单位统一社会信用代码") + private String orgCreditCode; + + @ApiModelProperty("项目数量") + private Integer projectCnt; + + @ApiModelProperty("项目预算(批复金额总合)") + private BigDecimal approvedTotalInvestmentIncreaseSum; + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/ProjectATIISBO.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/ProjectATIISBO.java new file mode 100644 index 0000000..b334aaf --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/ProjectATIISBO.java @@ -0,0 +1,31 @@ +package com.ningdatech.pmapi.dashboard.model.basic; + +import com.ningdatech.pmapi.common.compare.Compare; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * @author liuxinxin + * @date 2023/8/4 下午4:12 + */ + +@Data +@ApiModel("项目预算") +public class ProjectATIISBO { + + @ApiModelProperty("项目id") + private Long projectId; + + @ApiModelProperty("项目编号") + private String projectCode; + + @ApiModelProperty("项目名称") + private String projectName; + + @ApiModelProperty("批复金额") + @Compare("批复金额") + private BigDecimal approvedTotalInvestmentIncrease; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/QueryTimeYearBO.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/QueryTimeYearBO.java new file mode 100644 index 0000000..beca0f2 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/QueryTimeYearBO.java @@ -0,0 +1,23 @@ +package com.ningdatech.pmapi.dashboard.model.basic; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * @author liuxinxin + * @date 2023/7/27 下午3:24 + */ + +@Data +@ApiModel("查询年份起止BO") +public class QueryTimeYearBO { + + @ApiModelProperty("开始年份时间") + private LocalDateTime startYearTime; + + @ApiModelProperty("截止年份时间") + private LocalDateTime endYearTime; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/StarExpertBO.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/StarExpertBO.java new file mode 100644 index 0000000..b3e354a --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/StarExpertBO.java @@ -0,0 +1,24 @@ +package com.ningdatech.pmapi.dashboard.model.basic; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author liuxinxin + * @date 2023/8/2 下午3:57 + */ + +@Data +@ApiModel("明星专家") +public class StarExpertBO { + + @ApiModelProperty("专家姓名") + private String expertName; + + @ApiModelProperty("专家id") + private Long expertId; + + @ApiModelProperty("履职平均分") + private Double averagePerformanceScore; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/YearTrendBO.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/YearTrendBO.java new file mode 100644 index 0000000..a3a327b --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/basic/YearTrendBO.java @@ -0,0 +1,45 @@ +package com.ningdatech.pmapi.dashboard.model.basic; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author liuxinxin + * @date 2023/8/4 下午4:27 + */ + +@Data +@ApiModel("年度走势BO") +public class YearTrendBO { + + @ApiModelProperty("年份") + private Integer year; + + @ApiModelProperty("项目总数") + private Integer projectCnt; + + /** + * 建设类项目总数 + */ + + /** + * 运维类项目总数 + */ + + /** + * 建设类项目批复金额 + */ + + /** + * 运维类项目批复金额 + */ + + /** + * 资金核定率 + */ + + /** + * 立项率 + */ +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/po/QueryYearPO.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/po/QueryYearPO.java new file mode 100644 index 0000000..6f0dae6 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/po/QueryYearPO.java @@ -0,0 +1,21 @@ +package com.ningdatech.pmapi.dashboard.model.po; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author liuxinxin + * @date 2023/8/2 下午3:51 + */ + +@Data +@ApiModel("查询年份") +public class QueryYearPO { + + @ApiModelProperty("查询年份") + private Integer year; + + @ApiModelProperty("区域编码") + private String regionCode; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/DashboardInvestmentSummaryVO.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/DashboardInvestmentSummaryVO.java new file mode 100644 index 0000000..7405847 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/DashboardInvestmentSummaryVO.java @@ -0,0 +1,34 @@ +package com.ningdatech.pmapi.dashboard.model.vo; + +import com.ningdatech.pmapi.dashboard.model.basic.AnalysisChart; +import com.ningdatech.pmapi.dashboard.model.basic.CompanyProjectCntBO; +import com.ningdatech.pmapi.dashboard.model.basic.ProjectATIISBO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * @author liuxinxin + * @date 2023/8/2 下午3:36 + */ + +@Data +@ApiModel("驾驶舱投资金额统计数据") +public class DashboardInvestmentSummaryVO { + + /** + * 近5年项目投资走势 + * 近5年资金核定率走势 + */ + + @ApiModelProperty("项目预算TOP5") + private List projectATIISTop5List; + + @ApiModelProperty("单位预算TOP5") + private List companyProjectATIISTop5List; + + @ApiModelProperty("各领域项目投资金额,各区域项目投资情况") + private List analysisChartList; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/DashboardProjectCntSummaryVO.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/DashboardProjectCntSummaryVO.java new file mode 100644 index 0000000..9f7b312 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/DashboardProjectCntSummaryVO.java @@ -0,0 +1,30 @@ +package com.ningdatech.pmapi.dashboard.model.vo; + +import com.ningdatech.pmapi.dashboard.model.basic.AnalysisChart; +import com.ningdatech.pmapi.dashboard.model.basic.CompanyProjectCntBO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * @author liuxinxin + * @date 2023/8/2 下午3:36 + */ + +@Data +@ApiModel("项目数量驶舱统计数据") +public class DashboardProjectCntSummaryVO { + /** + * 近5年项目数量走势 + * 近5年立项率走势 + */ + + @ApiModelProperty("单位项目数量TOP5") + private List companyProjectCntTop5List; + + @ApiModelProperty("项目增补情况,各类型项目数量,各区域项目数量,各领域项目数量,各阶段项目数量") + private List analysisChartList; + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/DashboardProjectSummaryVO.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/DashboardProjectSummaryVO.java new file mode 100644 index 0000000..166dd82 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/DashboardProjectSummaryVO.java @@ -0,0 +1,58 @@ +package com.ningdatech.pmapi.dashboard.model.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * @author liuxinxin + * @date 2023/8/2 下午3:37 + */ +@Data +@ApiModel("驾驶舱项目总览驶舱统计数据") +public class DashboardProjectSummaryVO { + /** + * 项目画像 + */ + + @ApiModelProperty("项目总数") + private Integer projectCnt; + + @ApiModelProperty("待立项项目数") + private Integer toBeApprovedProjectCnt; + + @ApiModelProperty("已立项项目数") + private Integer approvedProjectCnt; + + @ApiModelProperty("项目立项率") + private Double projectApprovalRate; + + @ApiModelProperty("项目申报总金额") + private BigDecimal declareAmountSum; + + @ApiModelProperty("项目批复总金额") + private BigDecimal approvedTotalInvestmentIncreaseSum; + + @ApiModelProperty("延期项目数") + private Integer delayProjectCnt; + + @ApiModelProperty("延期占比") + private Double delayProportion; + + @ApiModelProperty("项目变更数量") + private Integer changedProjectCnt; + + @ApiModelProperty("项目变更金额") + private BigDecimal changedProjectContractAmountSum; + + @ApiModelProperty("项目采购总金额") + private BigDecimal projectProcurementTotalAmount; + + // 批复总金额/申报总金额 + @ApiModelProperty("资金核定率") + private BigDecimal fundApprovalRate; + + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/ExpertDashboardSummaryVO.java b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/ExpertDashboardSummaryVO.java new file mode 100644 index 0000000..bf56914 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/dashboard/model/vo/ExpertDashboardSummaryVO.java @@ -0,0 +1,31 @@ +package com.ningdatech.pmapi.dashboard.model.vo; + +import com.ningdatech.pmapi.dashboard.model.basic.AnalysisChart; +import com.ningdatech.pmapi.dashboard.model.basic.StarExpertBO; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +/** + * @author liuxinxin + * @date 2023/8/2 下午3:07 + */ + +@Data +@ApiModel("专家驾驶舱统计数据") +public class ExpertDashboardSummaryVO { + + @ApiModelProperty("明星专家列表") + private List starExpertList; + + @ApiModelProperty("评审次数") + private Integer meetingCnt; + + @ApiModelProperty("图表列表 各区域专家总数,学历分布,职称级别分布,各类型评审次数") + List analysisChartList; + + +} + diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/controller/DashboardController.java b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/controller/ExpertDashboardController.java similarity index 98% rename from pmapi/src/main/java/com/ningdatech/pmapi/meeting/controller/DashboardController.java rename to pmapi/src/main/java/com/ningdatech/pmapi/meeting/controller/ExpertDashboardController.java index 412ef49..2578f8e 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/meeting/controller/DashboardController.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/meeting/controller/ExpertDashboardController.java @@ -28,7 +28,7 @@ import java.util.List; @RestController @AllArgsConstructor @RequestMapping("/api/v1/dashboard") -public class DashboardController { +public class ExpertDashboardController { private final DashboardManage dashboardManage; diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/projectlib/enumeration/WarningFlowTypeEnum.java b/pmapi/src/main/java/com/ningdatech/pmapi/projectlib/enumeration/WarningFlowTypeEnum.java new file mode 100644 index 0000000..891d926 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/projectlib/enumeration/WarningFlowTypeEnum.java @@ -0,0 +1,58 @@ +package com.ningdatech.pmapi.projectlib.enumeration; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +import java.util.Objects; + +/** + * + * 预警填报类型枚举 + * @author CMM + * @since 2023/02/24 16:14 + */ +@Getter +@NoArgsConstructor +@AllArgsConstructor +public enum WarningFlowTypeEnum { + /** + * 预警填报类型枚举 + */ + UNIT_INNER_AUDIT(1, "预审申报",ProjectStatusEnum.PENDING_PREQUALIFICATION.getCode()), + PRELIMINARY_PREVIEW(2, "建设方案申报",ProjectStatusEnum.PLAN_TO_BE_DECLARED.getCode()), + DEPT_UNITED_REVIEW(3,"采购结果备案",ProjectStatusEnum.TO_BE_PURCHASED.getCode()), + CONSTRUCTION_PLAN_REVIEW(4,"初验备案",ProjectStatusEnum.UNDER_CONSTRUCTION.getCode()), + PROJECT_FINAL_INSPECTION(5,"验收申报",ProjectStatusEnum.TO_BE_FINALLY_INSPECTED.getCode()); + + private Integer code; + private String desc; + + //对应的 待提交时的项目状态 + private Integer projectStutas; + + public static String getDescByCode(Integer code) { + if (Objects.isNull(code)) { + return StringUtils.EMPTY; + } + for (WarningFlowTypeEnum t : WarningFlowTypeEnum.values()) { + if (code.equals(t.getCode())) { + return t.desc; + } + } + return StringUtils.EMPTY; + } + + public static WarningFlowTypeEnum getByCode(Integer code) { + if (Objects.isNull(code)) { + return null; + } + for (WarningFlowTypeEnum t : WarningFlowTypeEnum.values()) { + if (code.equals(t.getCode())) { + return t; + } + } + return null; + } +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/listener/EarlyWarningListener.java b/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/listener/EarlyWarningListener.java index 56aa2e6..0423328 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/listener/EarlyWarningListener.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/listener/EarlyWarningListener.java @@ -4,15 +4,24 @@ import cn.hutool.core.collection.CollUtil; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ningdatech.pmapi.common.constant.BizConst; +import com.ningdatech.pmapi.common.enumeration.CommonEnum; import com.ningdatech.pmapi.common.helper.UserInfoHelper; +import com.ningdatech.pmapi.meeting.helper.YxtCallOrSmsHelper; import com.ningdatech.pmapi.projectlib.enumeration.InstTypeEnum; import com.ningdatech.pmapi.projectlib.model.entity.Project; import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst; import com.ningdatech.pmapi.projectlib.service.IProjectInstService; import com.ningdatech.pmapi.projectlib.service.IProjectService; +import com.ningdatech.pmapi.staging.enums.MsgTypeEnum; +import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService; +import com.ningdatech.pmapi.sys.manage.NoticeManage; +import com.ningdatech.pmapi.sys.model.entity.Notify; import com.ningdatech.pmapi.sys.model.entity.WflowEarlyWarningRecords; import com.ningdatech.pmapi.sys.service.IEarlyWarningRecordsService; +import com.ningdatech.pmapi.sys.service.INotifyService; +import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo; import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO; +import com.ningdatech.yxt.model.cmd.SendSmsCmd; import com.wflow.enums.WarningRuleTypeEnum; import com.wflow.workflow.notify.event.EarlyWarningEvent; import lombok.RequiredArgsConstructor; @@ -49,6 +58,14 @@ public class EarlyWarningListener { private final UserInfoHelper userInfoHelper; + private final YxtCallOrSmsHelper yxtCallOrSmsHelper; + + private final NoticeManage noticeManage; + + private final INdWorkNoticeStagingService workNoticeStagingService; + + private final INotifyService notifyService; + @Async @EventListener public void onApplicationEvent(EarlyWarningEvent event) { @@ -104,9 +121,19 @@ public class EarlyWarningListener { } for(HistoricActivityInstance hai : hais){ + if(StringUtils.isBlank(noticeMethod) || + (!noticeMethod.contains(String.valueOf(CommonEnum.ZWDD.getCode())) && + !noticeMethod.contains(String.valueOf(CommonEnum.MOBILE.getCode())))){ + log.info("通知方式为空或者错误!"); + return; + } + + //1.存入 预警记录 String assignee = hai.getAssignee(); UserFullInfoDTO user = userInfoHelper.getUserFullInfoByEmployeeCode(assignee); WflowEarlyWarningRecords records = new WflowEarlyWarningRecords(); + String content = convertContent(noticeContent,project.getProjectName(), + InstTypeEnum.getByCode(pi.getInstType()),timeout); records.setAreaCode(project.getAreaCode()); records.setBuildOrgCode(project.getBuildOrgCode()); records.setBuildOrgName(project.getBuildOrgName()); @@ -115,12 +142,34 @@ public class EarlyWarningListener { records.setInstStart(hai.getStartTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime()); records.setInstType(pi.getInstType()); records.setNoticeMethod(noticeMethod); - records.setNoticeContent(convertContent(noticeContent,project.getProjectName(),InstTypeEnum.getByCode(pi.getInstType()),timeout)); + records.setNoticeContent(content); records.setProjectName(project.getProjectName()); records.setRuleType(WarningRuleTypeEnum.PROCESS_WARNING.getCode()); records.setWarningUsername(Objects.nonNull(user) ? user.getUsername() : StringUtils.EMPTY); records.setWarningEmployeecode(assignee); earlyWarningRecordsService.save(records); + + //2.消息提醒 + Notify notify = noticeManage.assemblyAuditNotify(user.getUserId(), project, content); + notify.setType(MsgTypeEnum.PROJECT_REVIEW.name()); + notifyService.save(notify); + + //3.发短信 + if(noticeMethod.contains(String.valueOf(CommonEnum.MOBILE.getCode()))){ + SendSmsCmd.SendSmsContext context = new SendSmsCmd.SendSmsContext(); + context.setReceiveNumber(user.getMobile()); + context.setContent(content); + yxtCallOrSmsHelper.sendSms(context); + } + + //4.浙政钉 + if(noticeMethod.contains(String.valueOf(CommonEnum.ZWDD.getCode()))){ + // 获取发送浙政钉工作通知必要信息 + WorkNoticeInfo passWorkNoticeInfo = noticeManage.getSendWorkNoticeInfo(assignee); + passWorkNoticeInfo.setMsg(content); + // 放入工作通知暂存表中,通过扫表异步发送 + workNoticeStagingService.addByWorkNotice(passWorkNoticeInfo, MsgTypeEnum.PROJECT_REVIEW); + } } } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/EarlyWarningInstanceNotStartTask.java b/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/EarlyWarningInstanceNotStartTask.java new file mode 100644 index 0000000..c941c8b --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/scheduler/task/EarlyWarningInstanceNotStartTask.java @@ -0,0 +1,119 @@ +package com.ningdatech.pmapi.scheduler.task; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.date.StopWatch; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ningdatech.pmapi.common.enumeration.CommonEnum; +import com.ningdatech.pmapi.projectlib.enumeration.WarningFlowTypeEnum; +import com.ningdatech.pmapi.projectlib.model.entity.Project; +import com.ningdatech.pmapi.projectlib.model.entity.ProjectInst; +import com.ningdatech.pmapi.projectlib.service.IProjectInstService; +import com.ningdatech.pmapi.projectlib.service.IProjectService; +import com.wflow.bean.entity.WflowEarlyWarning; +import com.wflow.enums.WarningRuleTypeEnum; +import com.wflow.service.IEarlyWarningService; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * @author ZPF + * @date 2023/8/3 上午9:53 + * 预警填报 超时任务 + */ +@Component +@Slf4j +@RequiredArgsConstructor +public class EarlyWarningInstanceNotStartTask { + + @Value("${hostname}") + private String HOST_NAME; + + private final IEarlyWarningService earlyWarningService; + + private final IProjectService projectService; + + private final IProjectInstService projectInstService; + + @Scheduled(cron = "0 2 * * * ?") + public void doTask() throws UnknownHostException { + if (!HOST_NAME.equals(InetAddress.getLocalHost().getHostName())) { + return; + } + + log.info("=========== 预警填报超时任务开始 ========"); + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + // 1.查询 填报的 预警规则 填报类型的 每个区域 每个规则 + List warnings = earlyWarningService.list(Wrappers.lambdaQuery(WflowEarlyWarning.class) + .eq(WflowEarlyWarning::getRuleType, WarningRuleTypeEnum.DECLARED_WARNING.getCode())); + for(WflowEarlyWarning warning : warnings){ + //2. 取出rule的数据 + if(!warning.getIsOpen()){ + log.info(warning.getId() + " 此规则关闭了"); + continue; + } + + String noticeMethod = warning.getNoticeMethod(); + if(StringUtils.isBlank(noticeMethod) || + (!noticeMethod.contains(String.valueOf(CommonEnum.ZWDD.getCode())) && + !noticeMethod.contains(String.valueOf(CommonEnum.MOBILE.getCode())))){ + log.info("通知方式为空或者错误!"); + return; + } + + String rule = warning.getRule(); + if(StringUtils.isNotBlank(rule)){ + JSONArray ruleArray = JSON.parseArray(rule); + if(CollUtil.isNotEmpty(ruleArray)){ + ruleArray.forEach(r -> { + JSONObject rJson = JSON.parseObject(JSON.toJSONString(r)); + Integer time = rJson.getInteger("time"); + Integer biz = rJson.getInteger("biz"); + if(Objects.isNull(time) || Objects.isNull(biz)){ + log.info("规则数据 错误 :{}",rJson); + return; + } + + WarningFlowTypeEnum flowTypeEnum = WarningFlowTypeEnum.getByCode(biz); + if(Objects.isNull(flowTypeEnum)){ + log.info("匹配不到 流程类型"); + return; + } + + //得出 对应待提交的项目状态 + Integer projectStutas = flowTypeEnum.getProjectStutas(); + String areaCode = warning.getAreaCode(); + //测试先用分钟 + //查询 所有这个区域的项目 未提交的项目 + List projects = projectService.list(Wrappers.lambdaQuery(Project.class) + .eq(Project::getAreaCode, areaCode) + .eq(Project::getNewest, Boolean.TRUE) + .eq(Project::getStatus,projectStutas)); + List projectIds = projects.stream().map(Project::getId) + .collect(Collectors.toList()); + projectInstService.list(Wrappers.lambdaQuery(ProjectInst.class) + .in(ProjectInst::getProjectId,projectIds) + .eq(ProjectInst::getInstType,biz)); + }); + } + } + } + + stopWatch.stop(); + log.info("=========== 预警填报超时任务结束 耗时{}s", stopWatch.getTotalTimeSeconds()); + } + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/sys/manage/NoticeManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/sys/manage/NoticeManage.java index a5ff193..b08a020 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/sys/manage/NoticeManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/sys/manage/NoticeManage.java @@ -237,7 +237,7 @@ public class NoticeManage { * @param project * @param msg */ - private Notify assemblyAuditNotify(Long userId, Project project, String msg) { + public Notify assemblyAuditNotify(Long userId, Project project, String msg) { Notify notify = new Notify(); notify.setTitle(AUDIT_WORK_TITLE); notify.setUserId(userId); diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java index 9b91443..8de8b4c 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java @@ -29,8 +29,6 @@ import com.ningdatech.pmapi.common.helper.UserInfoHelper; import com.ningdatech.pmapi.common.model.entity.ExcelExportWriter; import com.ningdatech.pmapi.common.util.ExcelDownUtil; import com.ningdatech.pmapi.irs.sign.IRSAPIRequest; -import com.ningdatech.pmapi.performance.model.dto.ProjectCoreBusinessDTO; -import com.ningdatech.pmapi.performance.model.entity.ProjectCoreBusinessIndicators; import com.ningdatech.pmapi.performance.service.IProjectCoreBusinessIndicatorsService; import com.ningdatech.pmapi.projectdeclared.manage.DefaultDeclaredProjectManage; import com.ningdatech.pmapi.projectlib.enumeration.*; @@ -103,7 +101,6 @@ import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import sun.misc.BASE64Decoder; - import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -143,9 +140,7 @@ public class TodoCenterManage { private final PassHandle passHandle; private final RepositoryService repositoryService; private final IRegionService regionService; - private final ITodoService todoService; - private final IProjectCoreBusinessIndicatorsService projectCoreBusinessIndicatorsService; /** * 待办中心待我处理项目列表查询 @@ -653,7 +648,10 @@ public class TodoCenterManage { List projectInstList = projectInstService.list(Wrappers.lambdaQuery(ProjectInst.class) .in(ProjectInst::getProjectId, projectIdList) .orderByDesc(ProjectInst::getProjectId)); - Map projectInfoMap = projectInstList.stream().collect(Collectors.toMap(ProjectInst::getInstCode, p -> projectsMap.get(p.getProjectId()))); + Map projectInfoMap = projectInstList.stream() + .filter(p -> StringUtils.isNotBlank(p.getInstCode()) && + !TodoCenterConstant.Declared.NULL_INST_CODE.equals(p.getInstCode())) + .collect(Collectors.toMap(ProjectInst::getInstCode, p -> projectsMap.get(p.getProjectId()))); List instCodes = projectInstList.stream().map(ProjectInst::getInstCode).collect(Collectors.toList()); // 查出用户工作流 @@ -724,7 +722,10 @@ public class TodoCenterManage { List projectInstList = projectInstService.list(Wrappers.lambdaQuery(ProjectInst.class) .in(ProjectInst::getProjectId, projectIdList) .orderByDesc(ProjectInst::getProjectId)); - projectInfoMap = projectInstList.stream().collect(Collectors.toMap(ProjectInst::getInstCode, p -> projectsMap.get(p.getProjectId()))); + projectInfoMap = projectInstList.stream() + .filter(p -> StringUtils.isNotBlank(p.getInstCode()) && + !TodoCenterConstant.Declared.NULL_INST_CODE.equals(p.getInstCode())) + .collect(Collectors.toMap(ProjectInst::getInstCode, p -> projectsMap.get(p.getProjectId()))); List instCodes = projectInstList.stream().map(ProjectInst::getInstCode).collect(Collectors.toList()); // 查出用户工作流 @@ -793,7 +794,10 @@ public class TodoCenterManage { List projectInstList = projectInstService.list(Wrappers.lambdaQuery(ProjectInst.class) .in(ProjectInst::getProjectId, projectIdList) .orderByDesc(ProjectInst::getProjectId)); - Map projectInfoMap = projectInstList.stream().collect(Collectors.toMap(ProjectInst::getInstCode, p -> projectsMap.get(p.getProjectId()))); + Map projectInfoMap = projectInstList.stream() + .filter(p -> StringUtils.isNotBlank(p.getInstCode()) && + !TodoCenterConstant.Declared.NULL_INST_CODE.equals(p.getInstCode())) + .collect(Collectors.toMap(ProjectInst::getInstCode, p -> projectsMap.get(p.getProjectId()))); List instCodes = projectInstList.stream().map(ProjectInst::getInstCode).collect(Collectors.toList()); // 查出用户工作流 @@ -862,7 +866,10 @@ public class TodoCenterManage { List projectInstList = projectInstService.list(Wrappers.lambdaQuery(ProjectInst.class) .in(ProjectInst::getProjectId, projectIdList) .orderByDesc(ProjectInst::getProjectId)); - projectInfoMap = projectInstList.stream().collect(Collectors.toMap(ProjectInst::getInstCode, p -> projectsMap.get(p.getProjectId()))); + projectInfoMap = projectInstList.stream() + .filter(p -> StringUtils.isNotBlank(p.getInstCode()) && + !TodoCenterConstant.Declared.NULL_INST_CODE.equals(p.getInstCode())) + .collect(Collectors.toMap(ProjectInst::getInstCode, p -> projectsMap.get(p.getProjectId()))); List instCodes = projectInstList.stream().map(ProjectInst::getInstCode).collect(Collectors.toList()); // 查出用户工作流 @@ -932,7 +939,10 @@ public class TodoCenterManage { List projectInstList = projectInstService.list(Wrappers.lambdaQuery(ProjectInst.class) .in(ProjectInst::getProjectId, projectIdList) .orderByDesc(ProjectInst::getProjectId)); - Map projectInfoMap = projectInstList.stream().collect(Collectors.toMap(ProjectInst::getInstCode, p -> projectsMap.get(p.getProjectId()))); + Map projectInfoMap = projectInstList.stream() + .filter(p -> StringUtils.isNotBlank(p.getInstCode()) && + !TodoCenterConstant.Declared.NULL_INST_CODE.equals(p.getInstCode())) + .collect(Collectors.toMap(ProjectInst::getInstCode, p -> projectsMap.get(p.getProjectId()))); List instCodes = projectInstList.stream().map(ProjectInst::getInstCode).collect(Collectors.toList()); // 查出用户工作流 @@ -1002,7 +1012,10 @@ public class TodoCenterManage { List projectInstList = projectInstService.list(Wrappers.lambdaQuery(ProjectInst.class) .in(ProjectInst::getProjectId, projectIdList) .orderByDesc(ProjectInst::getProjectId)); - projectInfoMap = projectInstList.stream().collect(Collectors.toMap(ProjectInst::getInstCode, p -> projectsMap.get(p.getProjectId()))); + projectInfoMap = projectInstList.stream() + .filter(p -> StringUtils.isNotBlank(p.getInstCode()) && + !TodoCenterConstant.Declared.NULL_INST_CODE.equals(p.getInstCode())) + .collect(Collectors.toMap(ProjectInst::getInstCode, p -> projectsMap.get(p.getProjectId()))); List instCodes = projectInstList.stream().map(ProjectInst::getInstCode).collect(Collectors.toList()); // 分页查出用户工作流 @@ -1102,15 +1115,12 @@ public class TodoCenterManage { project.setUpdateOn(LocalDateTime.now()); projectService.save(project); - oldProject.setIsBackReject(Boolean.TRUE); - projectService.updateById(oldProject); - ProjectInst oldInst = projectInstService.getOne(Wrappers.lambdaUpdate(ProjectInst.class) .eq(ProjectInst::getProjectId, oldProject.getId()) .eq(ProjectInst::getInstCode, oldProject.getInstCode())); String instCode = oldProject.getInstCode(); - oldInst.setInstCode(TodoCenterConstant.Declared.NULL_INST_CODE); + oldInst.setInstCode("EMPTY"); projectInstService.updateById(oldInst); ProjectInst newPi = new ProjectInst();