From 981dabd6fd344a276dc158a9713d3cc0fe9c1e58 Mon Sep 17 00:00:00 2001 From: CMM <2198256324@qq.com> Date: Wed, 4 Sep 2024 10:17:24 +0800 Subject: [PATCH] =?UTF-8?q?=E6=BB=9E=E5=90=8E=E9=A2=84=E8=AD=A6=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../scheduler/task/EarlyWarningProjectTask.java | 2 + .../task/EarlyWarningWithoutSubmitTask.java | 365 +++++++++++++++++---- .../hz/pm/api/sys/manage/EarlyWarningManage.java | 36 ++ .../sys/service/IProjectEarlyWarningService.java | 2 + .../impl/ProjectEarlyWarningServiceImpl.java | 65 ++++ .../com/hz/pm/api/warning/DelayWarningTest.java | 224 ++++++++++--- 6 files changed, 574 insertions(+), 120 deletions(-) diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/scheduler/task/EarlyWarningProjectTask.java b/hz-pm-api/src/main/java/com/hz/pm/api/scheduler/task/EarlyWarningProjectTask.java index 6fd7a9b..aa6d4a7 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/scheduler/task/EarlyWarningProjectTask.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/scheduler/task/EarlyWarningProjectTask.java @@ -32,6 +32,7 @@ import org.apache.commons.lang3.StringUtils; import org.checkerframework.checker.nullness.qual.Nullable; import org.flowable.engine.TaskService; import org.flowable.task.api.Task; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -48,6 +49,7 @@ import java.util.stream.Collectors; @Component @Slf4j @RequiredArgsConstructor +@ConditionalOnExpression("${early-warning-without-submit.open:true}") public class EarlyWarningProjectTask { private final IProjectService projectService; diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/scheduler/task/EarlyWarningWithoutSubmitTask.java b/hz-pm-api/src/main/java/com/hz/pm/api/scheduler/task/EarlyWarningWithoutSubmitTask.java index 3fea589..e5e0678 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/scheduler/task/EarlyWarningWithoutSubmitTask.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/scheduler/task/EarlyWarningWithoutSubmitTask.java @@ -6,7 +6,13 @@ import java.time.temporal.ChronoUnit; import java.util.*; import java.util.stream.Collectors; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.hz.pm.api.common.statemachine.event.TenderStateChangeEvent; +import com.hz.pm.api.projectlib.entity.PurchaseStatusChange; +import com.hz.pm.api.projectlib.service.IPurchaseStatusChangeService; import com.hz.pm.api.sys.model.entity.ProjectEarlyWarning; +import com.hz.pm.api.sys.model.entity.WflowEarlyWarningRecords; +import com.hz.pm.api.sys.service.IEarlyWarningRecordsService; import org.apache.commons.lang3.StringUtils; import org.checkerframework.checker.nullness.qual.Nullable; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; @@ -74,6 +80,8 @@ public class EarlyWarningWithoutSubmitTask { private final IProjectStatusChangeService projectStatusChangeService; private final EnvironmentUtil environmentUtil; private final UserInfoHelper userInfoHelper; + private final IEarlyWarningRecordsService earlyWarningRecordsService; + private final IPurchaseStatusChangeService purchaseStatusChangeService; private ChronoUnit getTimeUnit() { if (environmentUtil.isDevEnv()) { @@ -91,16 +99,60 @@ public class EarlyWarningWithoutSubmitTask { log.info("=========== 滞后预警任务开始 ==========="); StopWatch stopWatch = new StopWatch(); stopWatch.start(); - // 1.查询 填报的 滞后预警规则 填报类型的 每个单位的 每个规则 - Wrapper query = Wrappers.lambdaQuery(WflowEarlyWarning.class) - .eq(WflowEarlyWarning::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode()) - .eq(WflowEarlyWarning::getIsOpen, true); - List warnings = earlyWarningService.list(query); - for (WflowEarlyWarning warning : warnings) { - long mhUnitId = warning.getMhUnitId(); + // 获取项目库所有建设单位不为空的项目 + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(Project.class).isNotNull(Project::getBuildOrgCode); + List projects = projectService.list(queryWrapper); + // 根据项目code分组 获取最新的一条数据 + Map projectMap = projects.stream().collect(Collectors.groupingBy(Project::getProjectCode, Collectors.collectingAndThen( + // 根据创建日期找到最新的记录 + Collectors.maxBy(Comparator.comparing(Project::getCreateOn)), + // 如果没有记录则返回null + optional -> optional.orElse(null) + ))); + List projectList = new ArrayList<>(projectMap.values()); + List projectEarlyWarnings = Lists.newArrayList(); + List earlyWarningRecords = Lists.newArrayList(); + List needRemoved = Lists.newArrayList(); + // 查询当前预警表中 已存在的的滞后预警数据 + Wrapper warningQuery = Wrappers.lambdaQuery(ProjectEarlyWarning.class) + .eq(ProjectEarlyWarning::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode()); + List earlyWarnings = projectEarlyWarningService.list(warningQuery); + Map projectEarlyWarningMap = CollUtils.listToMap(earlyWarnings, c -> c.getProjectCode() + StrPool.DASH + c.getStepName()); + // 遍历项目 获取对应申报单位的滞后预警规则 + for (Project project : projectList) { + String buildOrgCode = project.getBuildOrgCode(); + String projectCode = project.getProjectCode(); + Long mhUnitId = Long.valueOf(buildOrgCode); + List unitIdPaths = mhUnitCache.getUnitIdPaths(mhUnitId); + if (unitIdPaths.isEmpty()) { + log.error("该单位无法进行滞后预警:{}", mhUnitId); + continue; + } + List unitIdPathsStr = CollUtils.convert(unitIdPaths, String::valueOf); + String orderSql = String.format(" order by field(mh_unit_id, %s) desc limit 1", + CollUtils.join(unitIdPaths, w -> "'" + w + "'", StrUtil.COMMA)); + log.info("单位ID路径:{}", unitIdPathsStr); + // 从当前建设单位开始向上获取滞后预警规则 + WflowEarlyWarning warning = earlyWarningService.getOne(Wrappers.lambdaQuery(WflowEarlyWarning.class) + .eq(WflowEarlyWarning::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode()) + .eq(WflowEarlyWarning::getIsOpen, true) + .in(WflowEarlyWarning::getMhUnitId, unitIdPathsStr) + .last(orderSql)); + if (Objects.isNull(warning)){ + log.info("未找到对应单位:{} 的滞后预警规则", mhUnitId); + continue; + } String rule = warning.getRule(); if (StringUtils.isNotBlank(rule)) { JSONArray ruleArray = JSON.parseArray(rule); + // 对JSONArray 根据"biz"字段从小到大排序 + ruleArray.sort((o1, o2) -> { + JSONObject o1Json = JSON.parseObject(JSON.toJSONString(o1)); + JSONObject o2Json = JSON.parseObject(JSON.toJSONString(o2)); + Integer o1Biz = o1Json.getInteger("biz"); + Integer o2Biz = o2Json.getInteger("biz"); + return o1Biz.compareTo(o2Biz); + }); if (CollUtil.isNotEmpty(ruleArray)) { ruleArray.forEach(r -> { JSONObject rJson = JSON.parseObject(JSON.toJSONString(r)); @@ -113,15 +165,16 @@ public class EarlyWarningWithoutSubmitTask { return; } String path = flowType.getPath(); - // 查询 所有这个单位 所配置滞后规则节点 未提交的项目 - Wrapper projectQuery = Wrappers.lambdaQuery(Project.class) - .eq(Project::getBuildOrgCode, mhUnitId) - .eq(Project::getNewest, Boolean.TRUE) - .eq(Project::getStatus, flowType.getProjectStatus().getCode()); - List needNextProjects = projectService.list(projectQuery); - List projectCodes = CollUtils.fieldList(needNextProjects, Project::getProjectCode); Map projectStatusChangeMap = MapUtil.newHashMap(); String stepName = null; + List projectCodes = Lists.newArrayList(); + projectCodes.add(project.getProjectCode()); + // 是否进行采购&合同备案 + boolean isPurchase = false; + // 适配改造是否完成单位确认 + boolean isModified = false; + // 终验申请是否提交 + boolean isFinalInspection = false; switch (flowType) { // 已立项未采购 获取 立项时间 case APPROVED_PROJECT_NOT_PURCHASED:{ @@ -129,6 +182,13 @@ public class EarlyWarningWithoutSubmitTask { if (CollUtil.isNotEmpty(projectCodes)) { Map approvedProjectNotPurchasedMap = projectStatusChangeService.listLastEventMap(projectCodes, ProjectStateChangeEvent.DECLARED_RECORD_PASS); + List events = Lists.newArrayList(); + events.add(ProjectStateChangeEvent.SUBMIT_PURCHASE_CONTRACT_RECORD); + ProjectStatusChange projectStatusChange = projectStatusChangeService.getLastOne(projectCode, events); + // 说明进行了采购&合同信息备案 + if (Objects.nonNull(projectStatusChange)) { + isPurchase = true; + } if (CollUtil.isNotEmpty(approvedProjectNotPurchasedMap)) { projectStatusChangeMap.putAll(approvedProjectNotPurchasedMap); } @@ -144,6 +204,13 @@ public class EarlyWarningWithoutSubmitTask { if (CollUtil.isNotEmpty(purchasedUnmodifiedMap)) { projectStatusChangeMap.putAll(purchasedUnmodifiedMap); } + List events = Lists.newArrayList(); + events.add(TenderStateChangeEvent.SUBMIT_PURCHASE_ORG_CONFIRM); + PurchaseStatusChange purchaseStatusChange = purchaseStatusChangeService.getLastOne(projectCode, events); + // 说明进行了单位确认 + if (Objects.nonNull(purchaseStatusChange)) { + isModified = true; + } } } break; @@ -157,76 +224,238 @@ public class EarlyWarningWithoutSubmitTask { projectStatusChangeMap.putAll(modifiedNotFinalInspectionMap); } } + List events = Lists.newArrayList(); + events.add(ProjectStateChangeEvent.FINAL_ACCEPTANCE_APPLICATION); + ProjectStatusChange projectStatusChange = projectStatusChangeService.getLastOne(projectCode, events); + // 说明提交了终验申请 + if (Objects.nonNull(projectStatusChange)) { + isFinalInspection = true; + } } break; default: log.error("Unexpected value: {}", flowType); } - // 查询当前预警表中 已存在的的滞后预警数据 - Wrapper warningQuery = Wrappers.lambdaQuery(ProjectEarlyWarning.class) - .eq(ProjectEarlyWarning::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode()); - List projectEarlyWarnings = projectEarlyWarningService.list(warningQuery); - Map projectEarlyWarningMap = CollUtils.listToMap(projectEarlyWarnings, c -> c.getProjectCode() + StrPool.DASH + c.getStepName()); - // 按照当前配置的滞后规则 获取需要首页监测预警展示的项目 + // 需要首页监测预警展示的项目 // 获取项目 滞后(历时)时间 HashMap touchTimeMap = MapUtil.newHashMap(); String finalStepName = stepName; - List needRemoved = Lists.newArrayList(); - List needToWaringProjects = needNextProjects.stream() - .filter(p -> { - ProjectStatusChange change = projectStatusChangeMap.get(p.getProjectCode()); - LocalDateTime touchTime = change == null ? null : change.getCreateOn(); - if (touchTime != null) { - touchTimeMap.put(p.getProjectCode() + StrPool.DASH + biz, touchTime); - long duration = getDurationTime(touchTime,LocalDateTime.now(),getTimeUnit()); - if (duration > delayTime) { - // 项目 滞后预警 - projectEarlyWarningService.earlyWarning(p, WarningRuleTypeEnum.DELAY_WARNING.getCode(), com.wflow.enums.WarningNoticeTypeEnum.DELAY.getCode(), finalStepName); - return Boolean.TRUE; - }else { - // 判断是否已经存在对应节点预警 如果有 从预警信息表中移除 - if (projectEarlyWarningMap.containsKey(p.getProjectCode() + StrPool.DASH + finalStepName)) { - ProjectEarlyWarning projectEarlyWarning = projectEarlyWarningMap.get(p.getProjectCode() + StrPool.DASH + finalStepName); - needRemoved.add(projectEarlyWarning); - } - } - } - return Boolean.FALSE; - }).collect(Collectors.toList()); - // 根据当前配置的滞后规则 将不满足规则的历史预警信息从预警信息表中移除 - if (CollUtil.isNotEmpty(needRemoved)){ - projectEarlyWarningService.removeBatchByIds(needRemoved); - } - for (Project needToWaringProject : needToWaringProjects) { - // 目前没有通知 - // 如果去预警通知人 1.超级管理员 2.单位管理员 如果都包含 都要发 - List batchEmployees = Lists.newArrayList(); - if (StringUtils.isNotBlank(notice) && notice.contains(WarningNoticeTypeEnum.SUPER_ADMIN.getCode().toString())) { - // 获取超级管理员用户信息 - List superAdminUsers = userInfoHelper.getEmployeeCodesByRoleEnum(RoleEnum.SUPER_ADMIN); - List superAdminEmployeeCodes = superAdminUsers.stream().map(UserInfo::getEmployeeCode).collect(Collectors.toList()); - batchEmployees.addAll(superAdminEmployeeCodes); - } - if (StringUtils.isNotBlank(notice) && notice.contains(WarningNoticeTypeEnum.UNIT_ADMIN.getCode().toString())) { - // 获取单位管理员用户信息 - List unitAdminUsers = userInfoHelper.getEmployeeCodesByRoleEnum(RoleEnum.COMPANY_MANAGER); - // 过滤出当前项目所属单位的单位管理员 - List unitAdminEmployeeCodes = unitAdminUsers.stream().filter(user -> Objects.equals(user.getMhUnitId().toString(), needToWaringProject.getBuildOrgCode())) - .map(UserInfo::getEmployeeCode).collect(Collectors.toList()); - batchEmployees.addAll(unitAdminEmployeeCodes); + ProjectStatusChange change = projectStatusChangeMap.get(projectCode); + LocalDateTime touchTime = change == null ? null : change.getCreateOn(); + // 是否进行预警 + boolean isTouch = isTouch(flowType, isPurchase, isModified, isFinalInspection); + if (touchTime != null) { + touchTimeMap.put(projectCode + StrPool.DASH + biz, touchTime); + long duration = getDurationTime(touchTime,LocalDateTime.now(),getTimeUnit()); + // 如果对应节点超期 且未提交至下一步 + if (duration > delayTime && isTouch) { + List projectEarlyWarningList = Lists.newArrayList(); + List earlyWarningRecordsList = Lists.newArrayList(); + // 项目 滞后预警 + projectEarlyWarningList = projectEarlyWarningService.earlyWarning(project, WarningRuleTypeEnum.DELAY_WARNING.getCode(), com.wflow.enums.WarningNoticeTypeEnum.DELAY.getCode(), finalStepName, projectEarlyWarningList); + projectEarlyWarnings.addAll(projectEarlyWarningList); + + // 目前没有通知 + // 如果去预警通知人 1.超级管理员 2.单位管理员 如果都包含 都要发 + List batchEmployees = Lists.newArrayList(); + if (StringUtils.isNotBlank(notice) && notice.contains(WarningNoticeTypeEnum.SUPER_ADMIN.getCode().toString())) { + // 获取超级管理员用户信息 + List superAdminUsers = userInfoHelper.getEmployeeCodesByRoleEnum(RoleEnum.SUPER_ADMIN); + List superAdminEmployeeCodes = superAdminUsers.stream().map(UserInfo::getEmployeeCode).collect(Collectors.toList()); + batchEmployees.addAll(superAdminEmployeeCodes); + } + if (StringUtils.isNotBlank(notice) && notice.contains(WarningNoticeTypeEnum.UNIT_ADMIN.getCode().toString())) { + // 获取单位管理员用户信息 + List unitAdminUsers = userInfoHelper.getEmployeeCodesByRoleEnum(RoleEnum.COMPANY_MANAGER); + // 过滤出当前项目所属单位的单位管理员 + List unitAdminEmployeeCodes = unitAdminUsers.stream().filter(user -> Objects.equals(user.getMhUnitId().toString(), project.getBuildOrgCode())) + .map(UserInfo::getEmployeeCode).collect(Collectors.toList()); + batchEmployees.addAll(unitAdminEmployeeCodes); + } + // 保存到预警记录中 + earlyWarningRecordsList = earlyWarningManage.getEarlyWarningDelayRecords(warning.getNoticeMethod(), biz, project, + WarningRuleTypeEnum.DELAY_WARNING.getCode(), ProjectEarlyWarningStatusEnum.DELAY_TIME.getCode(), + path, touchTimeMap, earlyWarningRecordsList); + earlyWarningRecords.addAll(earlyWarningRecordsList); + }else { + // 判断是否已经存在对应节点预警 如果有 从预警信息表中移除 + if (projectEarlyWarningMap.containsKey(project.getProjectCode() + StrPool.DASH + finalStepName)) { + ProjectEarlyWarning projectEarlyWarning = projectEarlyWarningMap.get(projectCode + StrPool.DASH + finalStepName); + needRemoved.add(projectEarlyWarning); + } } - // 保存到预警记录中 - earlyWarningManage.doEarlyWarningDelay(warning.getNoticeMethod(), biz, needToWaringProject, - WarningRuleTypeEnum.DELAY_WARNING.getCode(), ProjectEarlyWarningStatusEnum.DELAY_TIME.getCode(), - path, touchTimeMap); } }); } } } - + // 每个规则按通知节点顺序 更新保存一次 + if (CollUtil.isNotEmpty(needRemoved)){ + projectEarlyWarningService.removeBatchByIds(needRemoved); + } + if (CollUtil.isNotEmpty(projectEarlyWarnings)){ + log.info("需要滞后预警通知的项目数:{}", projectEarlyWarnings.size()); + projectEarlyWarningService.saveOrUpdateBatch(projectEarlyWarnings); + } + if (CollUtil.isNotEmpty(earlyWarningRecords)){ + log.info("需要滞后预警通知记录数:{}", earlyWarningRecords.size()); + earlyWarningRecordsService.saveOrUpdateBatch(earlyWarningRecords); + } stopWatch.stop(); log.info("=========== 滞后预警任务结束 耗时{}s", stopWatch.getTotalTimeSeconds()); + + //log.info("=========== 滞后预警任务开始 ==========="); + //StopWatch stopWatch = new StopWatch(); + //stopWatch.start(); + //// 1.查询 填报的 滞后预警规则 填报类型的 每个单位的 每个规则 + //Wrapper query = Wrappers.lambdaQuery(WflowEarlyWarning.class) + // .eq(WflowEarlyWarning::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode()) + // .eq(WflowEarlyWarning::getIsOpen, true); + //List warnings = earlyWarningService.list(query); + //for (WflowEarlyWarning warning : warnings) { + // long mhUnitId = warning.getMhUnitId(); + // 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 biz = rJson.getInteger("biz"); + // Integer delayTime = rJson.getInteger("delayTime"); + // String notice = rJson.getString("notice"); + // WarningFlowTypeEnum flowType = WarningFlowTypeEnum.getByCode(biz); + // if (Objects.isNull(delayTime) || Objects.isNull(biz) || flowType == null) { + // log.warn("规则数据 错误 :{}", rJson); + // return; + // } + // String path = flowType.getPath(); + // // 查询 所有这个单位 所配置滞后规则节点 未提交的项目 + // Wrapper projectQuery = Wrappers.lambdaQuery(Project.class) + // .eq(Project::getBuildOrgCode, mhUnitId) + // .eq(Project::getNewest, Boolean.TRUE) + // .eq(Project::getStatus, flowType.getProjectStatus().getCode()); + // List needNextProjects = projectService.list(projectQuery); + // List projectCodes = CollUtils.fieldList(needNextProjects, Project::getProjectCode); + // Map projectStatusChangeMap = MapUtil.newHashMap(); + // String stepName = null; + // switch (flowType) { + // // 已立项未采购 获取 立项时间 + // case APPROVED_PROJECT_NOT_PURCHASED:{ + // stepName = TaskConstant.StepName.PURCHASE; + // if (CollUtil.isNotEmpty(projectCodes)) { + // Map approvedProjectNotPurchasedMap = projectStatusChangeService.listLastEventMap(projectCodes, + // ProjectStateChangeEvent.DECLARED_RECORD_PASS); + // if (CollUtil.isNotEmpty(approvedProjectNotPurchasedMap)) { + // projectStatusChangeMap.putAll(approvedProjectNotPurchasedMap); + // } + // } + // } + // break; + // // 已采购未改造完成 获取合同签订时间 + // case PURCHASED_UNMODIFIED:{ + // stepName = TaskConstant.StepName.ADAPT_MODIFY; + // if (CollUtil.isNotEmpty(projectCodes)) { + // Map purchasedUnmodifiedMap = projectStatusChangeService.listLastEventMap(projectCodes, + // ProjectStateChangeEvent.SUBMIT_PURCHASE_CONTRACT_RECORD); + // if (CollUtil.isNotEmpty(purchasedUnmodifiedMap)) { + // projectStatusChangeMap.putAll(purchasedUnmodifiedMap); + // } + // } + // } + // break; + // // 已改造完成未终验 获取单位确认时间 + // case MODIFIED_NOT_FINAL_INSPECTION:{ + // stepName = TaskConstant.StepName.FINAL; + // if (CollUtil.isNotEmpty(projectCodes)) { + // Map modifiedNotFinalInspectionMap = projectStatusChangeService.listLastEventMap(projectCodes, + // ProjectStateChangeEvent.SUBMIT_PURCHASE_ORG_CONFIRM); + // if (CollUtil.isNotEmpty(modifiedNotFinalInspectionMap)) { + // projectStatusChangeMap.putAll(modifiedNotFinalInspectionMap); + // } + // } + // } + // break; + // default: + // log.error("Unexpected value: {}", flowType); + // } + // // 查询当前预警表中 已存在的的滞后预警数据 + // Wrapper warningQuery = Wrappers.lambdaQuery(ProjectEarlyWarning.class) + // .eq(ProjectEarlyWarning::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode()); + // List projectEarlyWarnings = projectEarlyWarningService.list(warningQuery); + // Map projectEarlyWarningMap = CollUtils.listToMap(projectEarlyWarnings, c -> c.getProjectCode() + StrPool.DASH + c.getStepName()); + // // 按照当前配置的滞后规则 获取需要首页监测预警展示的项目 + // // 获取项目 滞后(历时)时间 + // HashMap touchTimeMap = MapUtil.newHashMap(); + // String finalStepName = stepName; + // List needRemoved = Lists.newArrayList(); + // List needToWaringProjects = needNextProjects.stream() + // .filter(p -> { + // ProjectStatusChange change = projectStatusChangeMap.get(p.getProjectCode()); + // LocalDateTime touchTime = change == null ? null : change.getCreateOn(); + // if (touchTime != null) { + // touchTimeMap.put(p.getProjectCode() + StrPool.DASH + biz, touchTime); + // long duration = getDurationTime(touchTime,LocalDateTime.now(),getTimeUnit()); + // if (duration > delayTime) { + // // 项目 滞后预警 + // projectEarlyWarningService.earlyWarning(p, WarningRuleTypeEnum.DELAY_WARNING.getCode(), com.wflow.enums.WarningNoticeTypeEnum.DELAY.getCode(), finalStepName); + // return Boolean.TRUE; + // }else { + // // 判断是否已经存在对应节点预警 如果有 从预警信息表中移除 + // if (projectEarlyWarningMap.containsKey(p.getProjectCode() + StrPool.DASH + finalStepName)) { + // ProjectEarlyWarning projectEarlyWarning = projectEarlyWarningMap.get(p.getProjectCode() + StrPool.DASH + finalStepName); + // needRemoved.add(projectEarlyWarning); + // } + // } + // } + // return Boolean.FALSE; + // }).collect(Collectors.toList()); + // // 根据当前配置的滞后规则 将不满足规则的历史预警信息从预警信息表中移除 + // if (CollUtil.isNotEmpty(needRemoved)){ + // projectEarlyWarningService.removeBatchByIds(needRemoved); + // } + // for (Project needToWaringProject : needToWaringProjects) { + // // 目前没有通知 + // // 如果去预警通知人 1.超级管理员 2.单位管理员 如果都包含 都要发 + // List batchEmployees = Lists.newArrayList(); + // if (StringUtils.isNotBlank(notice) && notice.contains(WarningNoticeTypeEnum.SUPER_ADMIN.getCode().toString())) { + // // 获取超级管理员用户信息 + // List superAdminUsers = userInfoHelper.getEmployeeCodesByRoleEnum(RoleEnum.SUPER_ADMIN); + // List superAdminEmployeeCodes = superAdminUsers.stream().map(UserInfo::getEmployeeCode).collect(Collectors.toList()); + // batchEmployees.addAll(superAdminEmployeeCodes); + // } + // if (StringUtils.isNotBlank(notice) && notice.contains(WarningNoticeTypeEnum.UNIT_ADMIN.getCode().toString())) { + // // 获取单位管理员用户信息 + // List unitAdminUsers = userInfoHelper.getEmployeeCodesByRoleEnum(RoleEnum.COMPANY_MANAGER); + // // 过滤出当前项目所属单位的单位管理员 + // List unitAdminEmployeeCodes = unitAdminUsers.stream().filter(user -> Objects.equals(user.getMhUnitId().toString(), needToWaringProject.getBuildOrgCode())) + // .map(UserInfo::getEmployeeCode).collect(Collectors.toList()); + // batchEmployees.addAll(unitAdminEmployeeCodes); + // } + // // 保存到预警记录中 + // earlyWarningManage.doEarlyWarningDelay(warning.getNoticeMethod(), biz, needToWaringProject, + // WarningRuleTypeEnum.DELAY_WARNING.getCode(), ProjectEarlyWarningStatusEnum.DELAY_TIME.getCode(), + // path, touchTimeMap); + // } + // }); + // } + // } + //} + // + //stopWatch.stop(); + //log.info("=========== 滞后预警任务结束 耗时{}s", stopWatch.getTotalTimeSeconds()); + } + + private boolean isTouch(WarningFlowTypeEnum flowType, Boolean isPurchase, Boolean isModified, Boolean isFinalInspection) { + switch (flowType) { + case APPROVED_PROJECT_NOT_PURCHASED: + return !isPurchase; + case MODIFIED_NOT_FINAL_INSPECTION: + return !isModified && !isFinalInspection; + case PURCHASED_UNMODIFIED: + return isPurchase && !isModified; + default: + return false; + } } private long getDurationTime(LocalDateTime touchTime, LocalDateTime now, ChronoUnit timeUnit) { diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/sys/manage/EarlyWarningManage.java b/hz-pm-api/src/main/java/com/hz/pm/api/sys/manage/EarlyWarningManage.java index c1449e8..03f967f 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/sys/manage/EarlyWarningManage.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/sys/manage/EarlyWarningManage.java @@ -25,6 +25,7 @@ import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.util.HashMap; +import java.util.List; import java.util.Objects; /** @@ -169,6 +170,41 @@ public class EarlyWarningManage { earlyWarningRecordsService.saveOrUpdate(records); } + public List getEarlyWarningDelayRecords(String noticeMethod, Integer biz, Project project, + Integer ruleType, Integer noticeType, String path, + HashMap touchTimeMap, List earlyWarningRecords) { + // 1.存入 预警记录 + WflowEarlyWarningRecords records = new WflowEarlyWarningRecords(); + String projectCode = project.getProjectCode(); + WflowEarlyWarningRecords old = earlyWarningRecordsService.getOne(Wrappers.lambdaQuery(WflowEarlyWarningRecords.class) + .eq(WflowEarlyWarningRecords::getProjectCode, projectCode) + .eq(WflowEarlyWarningRecords::getBiz, biz) + .last(BizConst.LIMIT_1)); + if (Objects.nonNull(old)){ + records.setId(old.getId()); + }else { + records.setCreateOn(LocalDateTime.now()); + } + LocalDateTime startTime = touchTimeMap.get(projectCode + StrPool.DASH + biz); + records.setRuleType(ruleType); + records.setAreaCode(project.getAreaCode()); + records.setBuildOrgCode(project.getBuildOrgCode()); + records.setBuildOrgName(project.getBuildOrgName()); + records.setWarningTime(LocalDateTime.now()); + records.setInstStart(startTime); + records.setInstType(biz); + records.setNoticeMethod(noticeMethod); + records.setProjectName(project.getProjectName()); + records.setProjectId(project.getId()); + records.setProjectCode(project.getProjectCode()); + records.setProjectStatus(project.getStatus()); + records.setNoticeType(noticeType); + records.setPath(path); + records.setBiz(biz); + earlyWarningRecords.add(records); + return earlyWarningRecords; + } + /** * 催办 * diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/sys/service/IProjectEarlyWarningService.java b/hz-pm-api/src/main/java/com/hz/pm/api/sys/service/IProjectEarlyWarningService.java index 881fe18..ee72911 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/sys/service/IProjectEarlyWarningService.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/sys/service/IProjectEarlyWarningService.java @@ -18,4 +18,6 @@ public interface IProjectEarlyWarningService extends IService noticeTypes); Boolean earlyWarning(Project project, Integer ruleType, Integer noticeType, String stepName); + + List earlyWarning(Project project, Integer ruleType, Integer noticeType, String stepName,List projectEarlyWarningList); } diff --git a/hz-pm-api/src/main/java/com/hz/pm/api/sys/service/impl/ProjectEarlyWarningServiceImpl.java b/hz-pm-api/src/main/java/com/hz/pm/api/sys/service/impl/ProjectEarlyWarningServiceImpl.java index 93bc803..f580e3d 100644 --- a/hz-pm-api/src/main/java/com/hz/pm/api/sys/service/impl/ProjectEarlyWarningServiceImpl.java +++ b/hz-pm-api/src/main/java/com/hz/pm/api/sys/service/impl/ProjectEarlyWarningServiceImpl.java @@ -17,6 +17,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.time.LocalDateTime; +import java.util.Collections; import java.util.List; import java.util.Objects; @@ -68,6 +69,11 @@ public class ProjectEarlyWarningServiceImpl extends ServiceImpl earlyWarning(Project project, Integer ruleType, Integer noticeType, String stepName, List projectEarlyWarningList) { + return doEarlyWarning(project, ruleType, noticeType, stepName, projectEarlyWarningList); + } + private Boolean doEarlyWarning(Project project, Integer ruleType, Integer noticeType, String stepName) { if(Objects.isNull(project) || Objects.isNull(ruleType)){ return Boolean.FALSE; @@ -125,4 +131,63 @@ public class ProjectEarlyWarningServiceImpl extends ServiceImpl doEarlyWarning(Project project, Integer ruleType, Integer noticeType, String stepName, List projectEarlyWarningList) { + if(Objects.isNull(project) || Objects.isNull(ruleType)){ + return Collections.emptyList(); + } + String projectCode = project.getProjectCode(); + ProjectEarlyWarning old = getOne(Wrappers.lambdaQuery(ProjectEarlyWarning.class) + .eq(ProjectEarlyWarning::getProjectCode, projectCode) + .last(BizConst.LIMIT_1)); + ProjectEarlyWarning warning = new ProjectEarlyWarning(); + if(Objects.nonNull(old)){ + warning.setId(old.getId()); + }else{ + warning.setBuildOrgCode(project.getBuildOrgCode()); + warning.setAreaCode(project.getAreaCode()); + warning.setCreateOn(LocalDateTime.now()); + warning.setProjectCode(projectCode); + } + + switch (WarningRuleTypeEnum.checkByCode(ruleType)){ + case DELAY_WARNING: + warning.setDelayWarning(Boolean.TRUE); + break; + case DECLARED_WARNING: + warning.setDeclaredWarning(Boolean.TRUE); + break; + case PROCESS_WARNING: + warning.setProcessWarning(Boolean.TRUE); + break; + default: + return Collections.emptyList(); + } + + warning.setRuleType(ruleType); + if(Objects.isNull(noticeType)){ + warning.setStatus(ProjectEarlyWarningStatusEnum.OVER_TIME.name()); + }else{ + switch (WarningNoticeTypeEnum.match(noticeType)){ + case OVER: + warning.setStatus(ProjectEarlyWarningStatusEnum.OVER_TIME.name()); + break; + case ADVENT: + warning.setStatus(ProjectEarlyWarningStatusEnum.ADVENT_TIME.name()); + break; + case DELAY: + warning.setStatus(ProjectEarlyWarningStatusEnum.DELAY_TIME.name()); + break; + default: + warning.setStatus(ProjectEarlyWarningStatusEnum.OVER_TIME.name()); + break; + } + } + + warning.setNoticeType(noticeType); + warning.setNormal(Boolean.FALSE); + warning.setStepName(stepName); + projectEarlyWarningList.add(warning); + return projectEarlyWarningList; + } } diff --git a/hz-pm-api/src/test/java/com/hz/pm/api/warning/DelayWarningTest.java b/hz-pm-api/src/test/java/com/hz/pm/api/warning/DelayWarningTest.java index 8942192..b502b7b 100644 --- a/hz-pm-api/src/test/java/com/hz/pm/api/warning/DelayWarningTest.java +++ b/hz-pm-api/src/test/java/com/hz/pm/api/warning/DelayWarningTest.java @@ -5,12 +5,15 @@ import javax.annotation.Resource; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.StopWatch; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import com.hz.pm.api.common.enumeration.ProjectProcessType; import com.hz.pm.api.common.helper.UserInfoHelper; import com.hz.pm.api.common.model.constant.BizConst; import com.hz.pm.api.common.statemachine.event.ProjectStateChangeEvent; @@ -39,11 +42,14 @@ import com.hz.pm.api.user.service.IUserInfoService; import com.ningdatech.basic.util.CollUtils; import com.ningdatech.basic.util.StrPool; import com.wflow.bean.entity.WflowEarlyWarning; +import com.wflow.bean.entity.WflowModels; import com.wflow.enums.WarningRuleTypeEnum; import com.wflow.service.IEarlyWarningService; +import com.wflow.workflow.service.ProcessModelService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; +import org.checkerframework.checker.nullness.qual.Nullable; import org.flowable.engine.TaskService; import org.flowable.task.api.Task; import org.junit.Test; @@ -89,6 +95,10 @@ public class DelayWarningTest extends AppTests { private TaskService taskService; @Autowired private IPurchaseStatusChangeService purchaseStatusChangeService; + @Autowired + private MhUnitCache mhUnitCache; + @Autowired + private ProcessModelService processModelService; private ChronoUnit getTimeUnit() { if (environmentUtil.isDevEnv()) { @@ -100,20 +110,63 @@ public class DelayWarningTest extends AppTests { @Test public void one(){ - log.info("=========== 滞后预警任务开始 ==========="); StopWatch stopWatch = new StopWatch(); stopWatch.start(); - // 1.查询 填报的 滞后预警规则 填报类型的 每个单位的 每个规则 - Wrapper query = Wrappers.lambdaQuery(WflowEarlyWarning.class) - .eq(WflowEarlyWarning::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode()) - .eq(WflowEarlyWarning::getIsOpen, true); - List warnings = earlyWarningService.list(query); - for (WflowEarlyWarning warning : warnings) { - long mhUnitId = warning.getMhUnitId(); + // 获取项目库所有建设单位不为空的项目 + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(Project.class).isNotNull(Project::getBuildOrgCode); + List projects = projectService.list(queryWrapper); + // 根据项目code分组 获取最新的一条数据 + Map projectMap = projects.stream().collect(Collectors.groupingBy(Project::getProjectCode, Collectors.collectingAndThen( + // 根据创建日期找到最新的记录 + Collectors.maxBy(Comparator.comparing(Project::getCreateOn)), + // 如果没有记录则返回null + optional -> optional.orElse(null) + ))); + List projectList = new ArrayList<>(projectMap.values()); + List projectEarlyWarnings = Lists.newArrayList(); + List earlyWarningRecords = Lists.newArrayList(); + List needRemoved = Lists.newArrayList(); + // 查询当前预警表中 已存在的的滞后预警数据 + Wrapper warningQuery = Wrappers.lambdaQuery(ProjectEarlyWarning.class) + .eq(ProjectEarlyWarning::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode()); + List earlyWarnings = projectEarlyWarningService.list(warningQuery); + Map projectEarlyWarningMap = CollUtils.listToMap(earlyWarnings, c -> c.getProjectCode() + StrPool.DASH + c.getStepName()); + // 遍历项目 获取对应申报单位的滞后预警规则 + for (Project project : projectList) { + String buildOrgCode = project.getBuildOrgCode(); + String projectCode = project.getProjectCode(); + Long mhUnitId = Long.valueOf(buildOrgCode); + List unitIdPaths = mhUnitCache.getUnitIdPaths(mhUnitId); + if (unitIdPaths.isEmpty()) { + log.error("该单位无法进行滞后预警:{}", mhUnitId); + continue; + } + List unitIdPathsStr = CollUtils.convert(unitIdPaths, String::valueOf); + String orderSql = String.format(" order by field(mh_unit_id, %s) desc limit 1", + CollUtils.join(unitIdPaths, w -> "'" + w + "'", StrUtil.COMMA)); + log.info("单位ID路径:{}", unitIdPathsStr); + // 从当前建设单位开始向上获取滞后预警规则 + WflowEarlyWarning warning = earlyWarningService.getOne(Wrappers.lambdaQuery(WflowEarlyWarning.class) + .eq(WflowEarlyWarning::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode()) + .eq(WflowEarlyWarning::getIsOpen, true) + .in(WflowEarlyWarning::getMhUnitId, unitIdPathsStr) + .last(orderSql)); + if (Objects.isNull(warning)){ + log.info("未找到对应单位:{} 的滞后预警规则", mhUnitId); + continue; + } String rule = warning.getRule(); if (StringUtils.isNotBlank(rule)) { JSONArray ruleArray = JSON.parseArray(rule); + // 对JSONArray 根据"biz"字段从小到大排序 + ruleArray.sort((o1, o2) -> { + JSONObject o1Json = JSON.parseObject(JSON.toJSONString(o1)); + JSONObject o2Json = JSON.parseObject(JSON.toJSONString(o2)); + Integer o1Biz = o1Json.getInteger("biz"); + Integer o2Biz = o2Json.getInteger("biz"); + return o1Biz.compareTo(o2Biz); + }); if (CollUtil.isNotEmpty(ruleArray)) { ruleArray.forEach(r -> { JSONObject rJson = JSON.parseObject(JSON.toJSONString(r)); @@ -126,15 +179,16 @@ public class DelayWarningTest extends AppTests { return; } String path = flowType.getPath(); - // 查询 所有这个单位 所配置滞后规则节点 未提交的项目 - Wrapper projectQuery = Wrappers.lambdaQuery(Project.class) - .eq(Project::getBuildOrgCode, mhUnitId) - .eq(Project::getNewest, Boolean.TRUE) - .eq(Project::getStatus, flowType.getProjectStatus().getCode()); - List needNextProjects = projectService.list(projectQuery); - List projectCodes = CollUtils.fieldList(needNextProjects, Project::getProjectCode); Map projectStatusChangeMap = MapUtil.newHashMap(); String stepName = null; + List projectCodes = Lists.newArrayList(); + projectCodes.add(project.getProjectCode()); + // 是否进行采购&合同备案 + boolean isPurchase = false; + // 适配改造是否完成单位确认 + boolean isModified = false; + // 终验申请是否提交 + boolean isFinalInspection = false; switch (flowType) { // 已立项未采购 获取 立项时间 case APPROVED_PROJECT_NOT_PURCHASED:{ @@ -142,6 +196,13 @@ public class DelayWarningTest extends AppTests { if (CollUtil.isNotEmpty(projectCodes)) { Map approvedProjectNotPurchasedMap = projectStatusChangeService.listLastEventMap(projectCodes, ProjectStateChangeEvent.DECLARED_RECORD_PASS); + List events = Lists.newArrayList(); + events.add(ProjectStateChangeEvent.SUBMIT_PURCHASE_CONTRACT_RECORD); + ProjectStatusChange projectStatusChange = projectStatusChangeService.getLastOne(projectCode, events); + // 说明进行了采购&合同信息备案 + if (Objects.nonNull(projectStatusChange)) { + isPurchase = true; + } if (CollUtil.isNotEmpty(approvedProjectNotPurchasedMap)) { projectStatusChangeMap.putAll(approvedProjectNotPurchasedMap); } @@ -157,6 +218,13 @@ public class DelayWarningTest extends AppTests { if (CollUtil.isNotEmpty(purchasedUnmodifiedMap)) { projectStatusChangeMap.putAll(purchasedUnmodifiedMap); } + List events = Lists.newArrayList(); + events.add(TenderStateChangeEvent.SUBMIT_PURCHASE_ORG_CONFIRM); + PurchaseStatusChange purchaseStatusChange = purchaseStatusChangeService.getLastOne(projectCode, events); + // 说明进行了单位确认 + if (Objects.nonNull(purchaseStatusChange)) { + isModified = true; + } } } break; @@ -170,6 +238,13 @@ public class DelayWarningTest extends AppTests { projectStatusChangeMap.putAll(modifiedNotFinalInspectionMap); } } + List events = Lists.newArrayList(); + events.add(ProjectStateChangeEvent.FINAL_ACCEPTANCE_APPLICATION); + ProjectStatusChange projectStatusChange = projectStatusChangeService.getLastOne(projectCode, events); + // 说明提交了终验申请 + if (Objects.nonNull(projectStatusChange)) { + isFinalInspection = true; + } } break; default: @@ -179,54 +254,84 @@ public class DelayWarningTest extends AppTests { // 获取项目 滞后(历时)时间 HashMap touchTimeMap = MapUtil.newHashMap(); String finalStepName = stepName; - List needToWaringProjects = needNextProjects.stream() - .filter(p -> { - ProjectStatusChange change = projectStatusChangeMap.get(p.getProjectCode()); - LocalDateTime touchTime = change == null ? null : change.getCreateOn(); - if (touchTime != null) { - touchTimeMap.put(p.getProjectCode() + StrPool.DASH + biz, touchTime); - long duration = getDurationTime(touchTime,LocalDateTime.now(),getTimeUnit()); - if (duration > delayTime) { - // 项目 滞后预警 - projectEarlyWarningService.earlyWarning(p, WarningRuleTypeEnum.DELAY_WARNING.getCode(), com.wflow.enums.WarningNoticeTypeEnum.DELAY.getCode(), finalStepName); - return Boolean.TRUE; - } - } - return Boolean.FALSE; - }).collect(Collectors.toList()); + ProjectStatusChange change = projectStatusChangeMap.get(projectCode); + LocalDateTime touchTime = change == null ? null : change.getCreateOn(); + // 是否进行预警 + boolean isTouch = isTouch(flowType, isPurchase, isModified, isFinalInspection); + if (touchTime != null) { + touchTimeMap.put(projectCode + StrPool.DASH + biz, touchTime); + long duration = getDurationTime(touchTime,LocalDateTime.now(),getTimeUnit()); + // 如果对应节点超期 且未提交至下一步 + if (duration > delayTime && isTouch) { + List projectEarlyWarningList = Lists.newArrayList(); + List earlyWarningRecordsList = Lists.newArrayList(); + // 项目 滞后预警 + projectEarlyWarningList = projectEarlyWarningService.earlyWarning(project, WarningRuleTypeEnum.DELAY_WARNING.getCode(), com.wflow.enums.WarningNoticeTypeEnum.DELAY.getCode(), finalStepName, projectEarlyWarningList); + projectEarlyWarnings.addAll(projectEarlyWarningList); - for (Project needToWaringProject : needToWaringProjects) { - // 目前没有通知 - // 如果去预警通知人 1.超级管理员 2.单位管理员 如果都包含 都要发 - List batchEmployees = Lists.newArrayList(); - if (StringUtils.isNotBlank(notice) && notice.contains(WarningNoticeTypeEnum.SUPER_ADMIN.getCode().toString())) { - // 获取超级管理员用户信息 - List superAdminUsers = userInfoHelper.getEmployeeCodesByRoleEnum(RoleEnum.SUPER_ADMIN); - List superAdminEmployeeCodes = superAdminUsers.stream().map(UserInfo::getEmployeeCode).collect(Collectors.toList()); - batchEmployees.addAll(superAdminEmployeeCodes); - } - if (StringUtils.isNotBlank(notice) && notice.contains(WarningNoticeTypeEnum.UNIT_ADMIN.getCode().toString())) { - // 获取单位管理员用户信息 - List unitAdminUsers = userInfoHelper.getEmployeeCodesByRoleEnum(RoleEnum.COMPANY_MANAGER); - // 过滤出当前项目所属单位的单位管理员 - List unitAdminEmployeeCodes = unitAdminUsers.stream().filter(user -> Objects.equals(user.getMhUnitId().toString(), needToWaringProject.getBuildOrgCode())) - .map(UserInfo::getEmployeeCode).collect(Collectors.toList()); - batchEmployees.addAll(unitAdminEmployeeCodes); + // 目前没有通知 + // 如果去预警通知人 1.超级管理员 2.单位管理员 如果都包含 都要发 + List batchEmployees = Lists.newArrayList(); + if (StringUtils.isNotBlank(notice) && notice.contains(WarningNoticeTypeEnum.SUPER_ADMIN.getCode().toString())) { + // 获取超级管理员用户信息 + List superAdminUsers = userInfoHelper.getEmployeeCodesByRoleEnum(RoleEnum.SUPER_ADMIN); + List superAdminEmployeeCodes = superAdminUsers.stream().map(UserInfo::getEmployeeCode).collect(Collectors.toList()); + batchEmployees.addAll(superAdminEmployeeCodes); + } + if (StringUtils.isNotBlank(notice) && notice.contains(WarningNoticeTypeEnum.UNIT_ADMIN.getCode().toString())) { + // 获取单位管理员用户信息 + List unitAdminUsers = userInfoHelper.getEmployeeCodesByRoleEnum(RoleEnum.COMPANY_MANAGER); + // 过滤出当前项目所属单位的单位管理员 + List unitAdminEmployeeCodes = unitAdminUsers.stream().filter(user -> Objects.equals(user.getMhUnitId().toString(), project.getBuildOrgCode())) + .map(UserInfo::getEmployeeCode).collect(Collectors.toList()); + batchEmployees.addAll(unitAdminEmployeeCodes); + } + // 保存到预警记录中 + earlyWarningRecordsList = earlyWarningManage.getEarlyWarningDelayRecords(warning.getNoticeMethod(), biz, project, + WarningRuleTypeEnum.DELAY_WARNING.getCode(), ProjectEarlyWarningStatusEnum.DELAY_TIME.getCode(), + path, touchTimeMap, earlyWarningRecordsList); + earlyWarningRecords.addAll(earlyWarningRecordsList); + }else { + // 判断是否已经存在对应节点预警 如果有 从预警信息表中移除 + if (projectEarlyWarningMap.containsKey(project.getProjectCode() + StrPool.DASH + finalStepName)) { + ProjectEarlyWarning projectEarlyWarning = projectEarlyWarningMap.get(projectCode + StrPool.DASH + finalStepName); + needRemoved.add(projectEarlyWarning); + } } - // 保存到预警记录中 - earlyWarningManage.doEarlyWarningDelay(warning.getNoticeMethod(), biz, needToWaringProject, - WarningRuleTypeEnum.DELAY_WARNING.getCode(), ProjectEarlyWarningStatusEnum.DELAY_TIME.getCode(), - path, touchTimeMap); } }); } } } - + // 每个规则按通知节点顺序 更新保存一次 + if (CollUtil.isNotEmpty(needRemoved)){ + projectEarlyWarningService.removeBatchByIds(needRemoved); + } + if (CollUtil.isNotEmpty(projectEarlyWarnings)){ + log.info("需要滞后预警通知的项目数:{}", projectEarlyWarnings.size()); + projectEarlyWarningService.saveOrUpdateBatch(projectEarlyWarnings); + } + if (CollUtil.isNotEmpty(earlyWarningRecords)){ + log.info("需要滞后预警通知记录数:{}", earlyWarningRecords.size()); + earlyWarningRecordsService.saveOrUpdateBatch(earlyWarningRecords); + } stopWatch.stop(); log.info("=========== 滞后预警任务结束 耗时{}s", stopWatch.getTotalTimeSeconds()); } + private boolean isTouch(WarningFlowTypeEnum flowType, Boolean isPurchase, Boolean isModified, Boolean isFinalInspection) { + switch (flowType) { + case APPROVED_PROJECT_NOT_PURCHASED: + return !isPurchase; + case MODIFIED_NOT_FINAL_INSPECTION: + return !isModified && !isFinalInspection; + case PURCHASED_UNMODIFIED: + return isPurchase && !isModified; + default: + return false; + } + } + @Test public void two(){ log.info("=========== 预警项目状态校验任务开始 ==========="); @@ -264,6 +369,21 @@ public class DelayWarningTest extends AppTests { log.info("=========== 预警项目状态校验任务结束 耗时{}s", stopWatch.getTotalTimeSeconds()); } + @Test + public void three(){ + List unitIdPaths = mhUnitCache.getUnitIdPaths(32L); + System.out.println(unitIdPaths); + List unitIdPathsStr = CollUtils.convert(unitIdPaths, String::valueOf); + String orderSql = String.format(" order by field(region_code, %s) desc limit 1", + CollUtils.join(unitIdPaths, w -> "'" + w + "'", StrUtil.COMMA)); + System.out.println("单位ID路径:" + unitIdPathsStr); + WflowModels one = processModelService.getOne(Wrappers.lambdaQuery(WflowModels.class) + .eq(WflowModels::getProcessType, ProjectProcessType.PROJECT_RECORD_APPROVAL_PROCESS.getCode()) + .in(WflowModels::getRegionCode, unitIdPathsStr) + .last(orderSql)); + System.out.println(one); + } + private long getDurationTime(LocalDateTime touchTime, LocalDateTime now, ChronoUnit timeUnit) { return timeUnit.between(touchTime, now); }