Browse Source

滞后预警

tags/24090101
CMM 2 weeks ago
parent
commit
b2375df4af
28 changed files with 1005 additions and 550 deletions
  1. +1
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/common/helper/UserInfoHelper.java
  2. +16
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/common/helper/impl/UserInfoHelperImpl.java
  3. +4
    -6
      hz-pm-api/src/main/java/com/hz/pm/api/projectlib/model/enumeration/WarningFlowTypeEnum.java
  4. +16
    -1
      hz-pm-api/src/main/java/com/hz/pm/api/projectlib/service/IPurchaseStatusChangeService.java
  5. +7
    -1
      hz-pm-api/src/main/java/com/hz/pm/api/scheduler/contants/TaskConstant.java
  6. +82
    -123
      hz-pm-api/src/main/java/com/hz/pm/api/scheduler/task/EarlyWarningProjectTask.java
  7. +171
    -334
      hz-pm-api/src/main/java/com/hz/pm/api/scheduler/task/EarlyWarningWithoutSubmitTask.java
  8. +2
    -1
      hz-pm-api/src/main/java/com/hz/pm/api/sys/enumeration/ProjectEarlyWarningStatusEnum.java
  9. +41
    -39
      hz-pm-api/src/main/java/com/hz/pm/api/sys/manage/EarlyWarningManage.java
  10. +2
    -2
      hz-pm-api/src/main/java/com/hz/pm/api/sys/manage/MenuManage.java
  11. +7
    -2
      hz-pm-api/src/main/java/com/hz/pm/api/sys/model/entity/ProjectEarlyWarning.java
  12. +1
    -1
      hz-pm-api/src/main/java/com/hz/pm/api/sys/model/entity/WflowEarlyWarningRecords.java
  13. +2
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/sys/service/IProjectEarlyWarningService.java
  14. +21
    -12
      hz-pm-api/src/main/java/com/hz/pm/api/sys/service/impl/ProjectEarlyWarningServiceImpl.java
  15. +6
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/sys/utils/EarlyWarningUtil.java
  16. +0
    -1
      hz-pm-api/src/main/java/com/hz/pm/api/user/service/IUserInfoService.java
  17. +1
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/user/service/impl/UserInfoServiceImpl.java
  18. +7
    -4
      hz-pm-api/src/main/java/com/hz/pm/api/workbench/controller/WorkbenchController.java
  19. +73
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/workbench/manage/WorkbenchManage.java
  20. +46
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/workbench/model/vo/WorkbenchProjectMonitorEarlyWarnVO.java
  21. +3
    -1
      hz-pm-api/src/main/resources/application-dev.yml
  22. +2
    -0
      hz-pm-api/src/main/resources/application-prod.yml
  23. +3
    -1
      hz-pm-api/src/main/resources/application-test.yml
  24. +2
    -2
      hz-pm-api/src/test/java/com/hz/pm/api/sys/processDef/ProcessDefTest.java
  25. +438
    -0
      hz-pm-api/src/test/java/com/hz/pm/api/warning/DelayWarningTest.java
  26. +46
    -18
      hz-pm-api/src/test/resources/application-dev.yml
  27. +2
    -0
      hz-pm-api/src/test/resources/application-pre.yml
  28. +3
    -1
      hz-pm-api/src/test/resources/application-prod.yml

+ 1
- 0
hz-pm-api/src/main/java/com/hz/pm/api/common/helper/UserInfoHelper.java View File

@@ -50,4 +50,5 @@ public interface UserInfoHelper {

List<UserFullInfoDTO> listUserFullInfoByUnitIdsAndRole(Collection<Long> unitIds, RoleEnum role);

List<UserInfo> getEmployeeCodesByRoleEnum(RoleEnum roleEnum);
}

+ 16
- 0
hz-pm-api/src/main/java/com/hz/pm/api/common/helper/impl/UserInfoHelperImpl.java View File

@@ -167,4 +167,20 @@ public class UserInfoHelperImpl implements UserInfoHelper {
return CollUtils.convert(userInfos,this::convert);
}

@Override
public List<UserInfo> getEmployeeCodesByRoleEnum(RoleEnum roleEnum) {
LambdaQueryWrapper<Role> rQuery = Wrappers.lambdaQuery(Role.class)
.eq(Role::getCode, roleEnum.name())
.last(BizConst.LIMIT_1);
Role role = roleMapper.selectOne(rQuery);
if (role != null) {
LambdaQueryWrapper<UserRole> query = Wrappers.lambdaQuery(UserRole.class)
.eq(UserRole::getRoleId, role.getId());
List<UserRole> userRoles = iUserRoleService.list(query);
List<Long> userIdList = userRoles.stream().map(UserRole::getUserId).collect(Collectors.toList());
return userInfoService.listByIds(userIdList);
}
return Collections.emptyList();
}

}

+ 4
- 6
hz-pm-api/src/main/java/com/hz/pm/api/projectlib/model/enumeration/WarningFlowTypeEnum.java View File

@@ -22,16 +22,14 @@ public enum WarningFlowTypeEnum {
/**
* 预警填报类型枚举
*/
FUNDS_ISSUED_NOT_ESTABLISHED_PROJECT(1, "已资金下达未立项", ProjectStatus.DECLARED_APPROVED_TO_BE_RECORD, "project/declareManage/projectManages/projectFiling"),
APPROVED_PROJECT_BIT_NOT_OPEN(2, "已立项未开标", ProjectStatus.PROJECT_APPROVED, "project/declareManage/projectManages/purchaseResults"),
BIT_OPENED_NOT_PURCHASED(3, "已开标未采购", ProjectStatus.TO_BE_PURCHASED, "project/declareManage/projectManages/purchaseResults"),
PURCHASED_UNMODIFIED(4, "已采购未改造完成", ProjectStatus.ON_ADAPTING, "project/declareManage/projectManages/adaptiveTransformation"),
MODIFIED_NOT_FINAL_INSPECTION(5, "已改造完成未终验", ProjectStatus.ON_PILOT_RUNNING, "project/declareManage/projectManages/finalInspectionDeclare");
APPROVED_PROJECT_NOT_PURCHASED(1, "已立项未采购", ProjectStatus.TO_BE_PURCHASED, "project/declareManage/projectManages/purchaseResults"),
PURCHASED_UNMODIFIED(2, "已采购未改造完成", ProjectStatus.ON_ADAPTING, "project/declareManage/projectManages/adaptiveTransformation"),
MODIFIED_NOT_FINAL_INSPECTION(3, "已改造完成未终验", ProjectStatus.ON_PILOT_RUNNING, "project/declareManage/projectManages/finalInspectionDeclare");

private Integer code;
private String desc;

//对应的 待提交时的项目状态
// 对应的 待提交时的项目状态
private ProjectStatus projectStatus;

private String path;


+ 16
- 1
hz-pm-api/src/main/java/com/hz/pm/api/projectlib/service/IPurchaseStatusChangeService.java View File

@@ -1,7 +1,15 @@
package com.hz.pm.api.projectlib.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hz.pm.api.common.model.constant.BizConst;
import com.hz.pm.api.common.statemachine.event.ProjectStateChangeEvent;
import com.hz.pm.api.common.statemachine.event.TenderStateChangeEvent;
import com.hz.pm.api.projectlib.entity.PurchaseStatusChange;
import com.baomidou.mybatisplus.extension.service.IService;
import com.hz.pm.api.projectlib.model.entity.ProjectStatusChange;

import java.util.Collection;

/**
* <p>
@@ -12,5 +20,12 @@ import com.baomidou.mybatisplus.extension.service.IService;
* @since 2024-04-01
*/
public interface IPurchaseStatusChangeService extends IService<PurchaseStatusChange> {

default PurchaseStatusChange getLastOne(String projectCode, Collection<TenderStateChangeEvent> events) {
LambdaQueryWrapper<PurchaseStatusChange> pscQuery = Wrappers.lambdaQuery(PurchaseStatusChange.class)
.eq(PurchaseStatusChange::getProjectCode, projectCode)
.in(PurchaseStatusChange::getEvent, events)
.orderByDesc(PurchaseStatusChange::getCreateOn)
.last(BizConst.LIMIT_1);
return getOne(pscQuery);
}
}

hz-pm-api/src/main/java/com/hz/pm/api/scheduler/contants/TaskContant.java → hz-pm-api/src/main/java/com/hz/pm/api/scheduler/contants/TaskConstant.java View File

@@ -8,7 +8,7 @@ import com.hz.pm.api.common.enumeration.ProjectProcessType;
* @Description
* @Date 2023/1/18 11:00
*/
public interface TaskContant {
public interface TaskConstant {

class Wflow {

@@ -24,4 +24,10 @@ public interface TaskContant {
public static final String END_STEP = "流程结束";
}

class StepName {
public static final String PURCHASE = "采购";
public static final String ADAPT_MODIFY = "适配改造";
public static final String FINAL = "终验";
}

}

+ 82
- 123
hz-pm-api/src/main/java/com/hz/pm/api/scheduler/task/EarlyWarningProjectTask.java View File

@@ -2,16 +2,23 @@ package com.hz.pm.api.scheduler.task;

import cn.hutool.core.collection.CollUtil;
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.model.constant.BizConst;
import com.hz.pm.api.common.statemachine.event.ProjectStateChangeEvent;
import com.hz.pm.api.common.statemachine.event.TenderStateChangeEvent;
import com.hz.pm.api.projectlib.entity.PurchaseStatusChange;
import com.hz.pm.api.projectlib.model.entity.Project;
import com.hz.pm.api.projectlib.model.entity.ProjectRenewalFundDeclaration;
import com.hz.pm.api.projectlib.model.entity.ProjectStatusChange;
import com.hz.pm.api.projectlib.model.enumeration.ProjectRenewalApprovalStatusEnum;
import com.hz.pm.api.projectlib.model.enumeration.WarningFlowTypeEnum;
import com.hz.pm.api.projectlib.model.enumeration.WarningOperationTypeEnum;
import com.hz.pm.api.projectlib.model.enumeration.status.ProjectStatus;
import com.hz.pm.api.projectlib.service.IProjectRenewalFundDeclarationService;
import com.hz.pm.api.projectlib.service.IProjectService;
import com.hz.pm.api.projectlib.service.IProjectStatusChangeService;
import com.hz.pm.api.projectlib.service.IPurchaseStatusChangeService;
import com.hz.pm.api.sys.enumeration.ProjectEarlyWarningStatusEnum;
import com.hz.pm.api.sys.model.entity.ProjectEarlyWarning;
import com.hz.pm.api.sys.model.entity.WflowEarlyWarningRecords;
@@ -21,16 +28,14 @@ import com.wflow.enums.WarningRuleTypeEnum;
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.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@@ -47,8 +52,9 @@ public class EarlyWarningProjectTask {
private final IProjectService projectService;
private final IProjectEarlyWarningService projectEarlyWarningService;
private final IEarlyWarningRecordsService earlyWarningRecordsService;
private final IProjectRenewalFundDeclarationService renewalFundDeclarationService;
private final TaskService taskService;
private final IProjectStatusChangeService projectStatusChangeService;
private final IPurchaseStatusChangeService purchaseStatusChangeService;

@Scheduled(fixedDelay = 5, initialDelay = 5, timeUnit = TimeUnit.MINUTES)
public void doEarlyWarningDeclared() {
@@ -63,37 +69,8 @@ public class EarlyWarningProjectTask {
Map<String, Project> projectMap = projects.stream().filter(p -> projectSet.add(p.getProjectCode()))
.collect(Collectors.toMap(Project::getProjectCode, p -> p));
List<ProjectEarlyWarning> warnings = projectEarlyWarningService.list();
List<String> warningProjectCodes = warnings.stream().map(ProjectEarlyWarning::getProjectCode)
.collect(Collectors.toList());

//1.先补全 异常项目管理中 不存在的项目
List<ProjectEarlyWarning> toAdd = projects.stream()
.filter(p -> {
if (CollUtil.isEmpty(warningProjectCodes)) {
return Boolean.TRUE;
}
if (!warningProjectCodes.contains(p.getProjectCode())) {
return Boolean.TRUE;
}
return Boolean.FALSE;
})
.map(p -> {
ProjectEarlyWarning earlyWarning = new ProjectEarlyWarning();
earlyWarning.setAreaCode(p.getAreaCode());
earlyWarning.setBuildOrgCode(p.getBuildOrgCode());
earlyWarning.setProjectCode(p.getProjectCode());
earlyWarning.setCreateOn(LocalDateTime.now());
earlyWarning.setStatus(ProjectEarlyWarningStatusEnum.NORMAL.name());
earlyWarning.setRuleType(null);
return earlyWarning;
})
.collect(Collectors.toList());

if (CollUtil.isNotEmpty(toAdd)) {
projectEarlyWarningService.saveBatch(toAdd);
}

//2.删除 已经不存在的项目
// 删除 已经不存在的项目
List<ProjectEarlyWarning> toRemove = warnings.stream()
.filter(w -> !projectMap.containsKey(w.getProjectCode()))
.collect(Collectors.toList());
@@ -103,7 +80,7 @@ public class EarlyWarningProjectTask {
projectEarlyWarningService.removeBatchByIds(removeIds);
}

//3.去查询 各个报警 是否已经正常
// 去查询 各个报警 是否已经正常
List<ProjectEarlyWarning> trueWarnings = warnings.stream().filter(w -> Objects.nonNull(w.getNormal()) && !w.getNormal()).collect(Collectors.toList());
if (CollUtil.isEmpty(trueWarnings)) {
return;
@@ -111,118 +88,63 @@ public class EarlyWarningProjectTask {
checkNormal(trueWarnings);
}

//3.去查询 各个报警 是否已经正常
// 3.去查询 各个报警 是否已经正常
private void checkNormal(List<ProjectEarlyWarning> trueWarnings) {
//3.1 预警预警 如果正常了 要改会正常
// 3.1 流程预警 如果正常了 要改会正常
List<ProjectEarlyWarning> processWarning = trueWarnings.stream().filter(w -> Objects.nonNull(w.getProcessWarning())
&& w.getProcessWarning())
.collect(Collectors.toList());
checkProcessWarning(processWarning);

//3.2 填报预警 如果正常了 要改会正常
// 3.2 填报预警 如果正常了 要改会正常
List<ProjectEarlyWarning> declaredWarning = trueWarnings.stream().filter(w ->
Objects.nonNull(w.getDeclaredWarning())
&& w.getDeclaredWarning())
.collect(Collectors.toList());
checkDeclaredWarning(declaredWarning);

//3.3 实施预警 如果正常了 要改会正常
List<ProjectEarlyWarning> operationWarning = trueWarnings.stream().filter(w ->
Objects.nonNull(w.getOperationWarning())
&& w.getOperationWarning())
.collect(Collectors.toList());
checkOperationWarning(operationWarning);

//3.4 续建资金预警 如果正常了 要改回正常
List<ProjectEarlyWarning> renewalFundWarning = trueWarnings.stream().filter(w ->
Objects.nonNull(w.getRenewalFundWarning())
&& w.getRenewalFundWarning())
// 3.3 滞后预警 如果正常了 要改会正常
List<ProjectEarlyWarning> delayWarning = trueWarnings.stream().filter(w ->
Objects.nonNull(w.getDelayWarning())
&& w.getDelayWarning())
.collect(Collectors.toList());
checkRenewalFundWarning(renewalFundWarning);
checkDelayWarning(delayWarning);
}

private void checkRenewalFundWarning(List<ProjectEarlyWarning> renewalFundWarnings) {
if (CollUtil.isEmpty(renewalFundWarnings)) {
private void checkDelayWarning(List<ProjectEarlyWarning> delayWarning) {
if (CollUtil.isEmpty(delayWarning)) {
return;
}

for (ProjectEarlyWarning renewalFundWarning : renewalFundWarnings) {
String projectCode = renewalFundWarning.getProjectCode();
for (ProjectEarlyWarning delay : delayWarning) {
String projectCode = delay.getProjectCode();
Project project = projectService.getProjectByCode(projectCode);
if (Objects.isNull(project)) {
continue;
}

WflowEarlyWarningRecords record = earlyWarningRecordsService.getOne(Wrappers.lambdaQuery(WflowEarlyWarningRecords.class)
.eq(WflowEarlyWarningRecords::getProjectCode, projectCode)
.eq(WflowEarlyWarningRecords::getRuleType, WarningRuleTypeEnum.OPERATION_WARNING.getCode())
.orderByDesc(WflowEarlyWarningRecords::getWarningTime)
.last(BizConst.LIMIT_1));
if (Objects.isNull(record)) {
continue;
}
//借用了NODEID 其实 是续建id
String nodeId = record.getNodeId();
ProjectRenewalFundDeclaration renewalFund = renewalFundDeclarationService.getById(nodeId);
if (Objects.isNull(renewalFund)) {
continue;
}
String approvalStatus = renewalFund.getApprovalStatus();
ProjectRenewalApprovalStatusEnum match = ProjectRenewalApprovalStatusEnum
.match(approvalStatus);
if (Objects.nonNull(match)) {
//如果是已经审批
if (match.name().equals(ProjectRenewalApprovalStatusEnum.PASS.name())) {
renewalFundWarning.setRenewalFundWarning(Boolean.FALSE);
//其它三种 都没有 说明已经正常了
if (!renewalFundWarning.getProcessWarning() &&
!renewalFundWarning.getDeclaredWarning() &&
!renewalFundWarning.getOperationWarning()) {
renewalFundWarning.setNormal(Boolean.TRUE);
renewalFundWarning.setStatus(ProjectEarlyWarningStatusEnum.NORMAL.name());
}
projectEarlyWarningService.updateById(renewalFundWarning);
}
}
}
}

private void checkOperationWarning(List<ProjectEarlyWarning> operationWarnings) {
if (CollUtil.isEmpty(operationWarnings)) {
return;
}

for (ProjectEarlyWarning operationWarning : operationWarnings) {
String projectCode = operationWarning.getProjectCode();
Project project = projectService.getProjectByCode(projectCode);
if (Objects.isNull(project)) {
continue;
}
WflowEarlyWarningRecords record = earlyWarningRecordsService.getOne(Wrappers.lambdaQuery(WflowEarlyWarningRecords.class)
.eq(WflowEarlyWarningRecords::getProjectCode, projectCode)
.eq(WflowEarlyWarningRecords::getRuleType, WarningRuleTypeEnum.OPERATION_WARNING.getCode())
.eq(WflowEarlyWarningRecords::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode())
.orderByDesc(WflowEarlyWarningRecords::getWarningTime)
.last(BizConst.LIMIT_1));
if (Objects.isNull(record)) {
continue;
}
Integer biz = record.getBiz();
WarningOperationTypeEnum operationTypeEnum = WarningOperationTypeEnum.getByCode(biz);
if (Objects.isNull(operationTypeEnum)) {
WarningFlowTypeEnum flowTypeEnum = WarningFlowTypeEnum.getByCode(biz);
if (Objects.isNull(flowTypeEnum)) {
continue;
}
Integer projectStutas = operationTypeEnum.getProjectStutas();
//已经不是这个状态了 说明已经被提交了
if (!projectStutas.equals(project.getStatus())) {
operationWarning.setOperationWarning(Boolean.FALSE);
//其它三种 都没有 说明已经正常了
if (!operationWarning.getProcessWarning() &&
!operationWarning.getDeclaredWarning() &&
!operationWarning.getRenewalFundWarning()) {
operationWarning.setNormal(Boolean.TRUE);
operationWarning.setStatus(ProjectEarlyWarningStatusEnum.NORMAL.name());
ProjectStatus projectStatus = flowTypeEnum.getProjectStatus();
// 已经不是这个状态了 说明已经被提交了
if (!projectStatus.eq(project.getStatus())) {
checkCommited(delay, flowTypeEnum, projectCode);
// 其它几种 都没有 说明已经正常了
if (!delay.getProcessWarning() &&
!delay.getDeclaredWarning()) {
delay.setNormal(Boolean.TRUE);
delay.setStatus(ProjectEarlyWarningStatusEnum.NORMAL.name());
}
projectEarlyWarningService.updateById(operationWarning);
projectEarlyWarningService.updateById(delay);
}
}
}
@@ -251,13 +173,12 @@ public class EarlyWarningProjectTask {
continue;
}
ProjectStatus projectStatus = flowTypeEnum.getProjectStatus();
//已经不是这个状态了 说明已经被提交了
// 已经不是这个状态了 根据选择的节点判断是否完成了提交
if (!projectStatus.eq(project.getStatus())) {
declaredWarning.setDeclaredWarning(Boolean.FALSE);
//其它三种 都没有 说明已经正常了
checkCommited(declaredWarning, flowTypeEnum, projectCode);
// 其它几种 都没有 说明已经正常了
if (!declaredWarning.getProcessWarning() &&
!declaredWarning.getOperationWarning() &&
!declaredWarning.getRenewalFundWarning()) {
!declaredWarning.getDelayWarning()) {
declaredWarning.setNormal(Boolean.TRUE);
declaredWarning.setStatus(ProjectEarlyWarningStatusEnum.NORMAL.name());
}
@@ -266,6 +187,45 @@ public class EarlyWarningProjectTask {
}
}

private void checkCommited(ProjectEarlyWarning warning, WarningFlowTypeEnum flowTypeEnum, String projectCode) {
switch (flowTypeEnum){
// 已立项未采购 当用户采购&合同备案完成 说明进度正常
case APPROVED_PROJECT_NOT_PURCHASED: {
List<ProjectStateChangeEvent> events = Lists.newArrayList();
events.add(ProjectStateChangeEvent.SUBMIT_PURCHASE_CONTRACT_RECORD);
ProjectStatusChange projectStatusChange = projectStatusChangeService.getLastOne(projectCode, events);
// 说明进行了采购&合同信息备案
if (Objects.nonNull(projectStatusChange)) {
warning.setDeclaredWarning(Boolean.FALSE);
}
}
break;
// 已采购未改造完成 当用户适配改造完成已完成单位确认 说明进度正常
case MODIFIED_NOT_FINAL_INSPECTION:{
List<TenderStateChangeEvent> events = Lists.newArrayList();
events.add(TenderStateChangeEvent.SUBMIT_PURCHASE_ORG_CONFIRM);
PurchaseStatusChange purchaseStatusChange = purchaseStatusChangeService.getLastOne(projectCode, events);
// 说明进行了单位确认
if (Objects.nonNull(purchaseStatusChange)) {
warning.setDeclaredWarning(Boolean.FALSE);
}

}
break;
// 已改造完成未终验 当用户提交终验申请 说明进度正常
case PURCHASED_UNMODIFIED:{
List<ProjectStateChangeEvent> events = Lists.newArrayList();
events.add(ProjectStateChangeEvent.FINAL_ACCEPTANCE_APPLICATION);
ProjectStatusChange projectStatusChange = projectStatusChangeService.getLastOne(projectCode, events);
// 说明提交了终验申请
if (Objects.nonNull(projectStatusChange)) {
warning.setDeclaredWarning(Boolean.FALSE);
}
}
break;
}
}

/**
* 流程 查看 是否已经处理过
*
@@ -296,8 +256,7 @@ public class EarlyWarningProjectTask {
processWarning.setProcessWarning(Boolean.FALSE);
//其它三种 都没有 说明已经正常了
if (!processWarning.getDeclaredWarning() &&
!processWarning.getOperationWarning() &&
!processWarning.getRenewalFundWarning()) {
!processWarning.getDelayWarning()) {
processWarning.setNormal(Boolean.TRUE);
processWarning.setStatus(ProjectEarlyWarningStatusEnum.NORMAL.name());
}


+ 171
- 334
hz-pm-api/src/main/java/com/hz/pm/api/scheduler/task/EarlyWarningWithoutSubmitTask.java View File

@@ -1,9 +1,18 @@
package com.hz.pm.api.scheduler.task;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

import com.hz.pm.api.sys.model.entity.ProjectEarlyWarning;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
@@ -11,22 +20,20 @@ import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.hz.pm.api.common.enumeration.CommonEnum;
import com.hz.pm.api.common.helper.UserInfoHelper;
import com.hz.pm.api.common.statemachine.event.ProjectStateChangeEvent;
import com.hz.pm.api.common.util.EnvironmentUtil;
import com.hz.pm.api.common.util.StrUtils;
import com.hz.pm.api.projectdeclared.model.entity.Operation;
import com.hz.pm.api.projectdeclared.service.IOperationService;
import com.hz.pm.api.projectlib.model.entity.Project;
import com.hz.pm.api.projectlib.model.entity.ProjectRenewalFundDeclaration;
import com.hz.pm.api.projectlib.model.entity.ProjectStatusChange;
import com.hz.pm.api.projectlib.model.enumeration.ProjectRenewalApprovalStatusEnum;
import com.hz.pm.api.projectlib.model.enumeration.WarningFlowTypeEnum;
import com.hz.pm.api.projectlib.model.enumeration.WarningNoticeTypeEnum;
import com.hz.pm.api.projectlib.model.enumeration.WarningOperationTypeEnum;
import com.hz.pm.api.projectlib.service.IProjectRenewalFundDeclarationService;
import com.hz.pm.api.projectlib.service.IProjectService;
import com.hz.pm.api.projectlib.service.IProjectStatusChangeService;
import com.hz.pm.api.scheduler.contants.TaskConstant;
import com.hz.pm.api.sys.enumeration.ProjectEarlyWarningStatusEnum;
import com.hz.pm.api.sys.manage.EarlyWarningManage;
import com.hz.pm.api.sys.manage.RoleManage;
import com.hz.pm.api.sys.service.IProjectEarlyWarningService;
@@ -39,21 +46,13 @@ import com.ningdatech.basic.util.StrPool;
import com.wflow.bean.entity.WflowEarlyWarning;
import com.wflow.enums.WarningRuleTypeEnum;
import com.wflow.service.IEarlyWarningService;

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 lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.net.UnknownHostException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @author ZPF
@@ -63,20 +62,18 @@ import java.util.stream.Collectors;
@Slf4j
@Component
@RequiredArgsConstructor
@ConditionalOnExpression("${early-warning-without-submit.open:false}")
@ConditionalOnExpression("${early-warning-without-submit.open:true}")
public class EarlyWarningWithoutSubmitTask {

private final IEarlyWarningService earlyWarningService;
private final IProjectService projectService;
private final EarlyWarningManage earlyWarningManage;
private final IOperationService operationService;
private final IUserInfoService userInfoService;
private final IProjectRenewalFundDeclarationService renewalFundDeclarationService;
private final RoleManage roleManage;
private final IProjectEarlyWarningService projectEarlyWarningService;
private final MhUnitCache mhUnitCache;
private final IProjectStatusChangeService projectStatusChangeService;
private final EnvironmentUtil environmentUtil;
private final UserInfoHelper userInfoHelper;

private ChronoUnit getTimeUnit() {
if (environmentUtil.isDevEnv()) {
@@ -87,9 +84,153 @@ public class EarlyWarningWithoutSubmitTask {
}

/**
* 滞后预警 每两分钟执行一次
*/
@Scheduled(cron = "${early-warning-without-submit-delay-warning.cron:0 0/2 * * * ?}")
public void doEarlyWarningDelayed() {
log.info("=========== 滞后预警任务开始 ===========");
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// 1.查询 填报的 滞后预警规则 填报类型的 每个单位的 每个规则
Wrapper<WflowEarlyWarning> query = Wrappers.lambdaQuery(WflowEarlyWarning.class)
.eq(WflowEarlyWarning::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode())
.eq(WflowEarlyWarning::getIsOpen, true);
List<WflowEarlyWarning> 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<Project> projectQuery = Wrappers.lambdaQuery(Project.class)
.eq(Project::getBuildOrgCode, mhUnitId)
.eq(Project::getNewest, Boolean.TRUE)
.eq(Project::getStatus, flowType.getProjectStatus().getCode());
List<Project> needNextProjects = projectService.list(projectQuery);
List<String> projectCodes = CollUtils.fieldList(needNextProjects, Project::getProjectCode);
Map<String, ProjectStatusChange> projectStatusChangeMap = MapUtil.newHashMap();
String stepName = null;
switch (flowType) {
// 已立项未采购 获取 立项时间
case APPROVED_PROJECT_NOT_PURCHASED:{
Map<String, ProjectStatusChange> approvedProjectNotPurchasedMap = projectStatusChangeService.listLastEventMap(projectCodes,
ProjectStateChangeEvent.DECLARED_RECORD_PASS);
if (CollUtil.isNotEmpty(approvedProjectNotPurchasedMap)){
projectStatusChangeMap.putAll(approvedProjectNotPurchasedMap);
stepName = TaskConstant.StepName.PURCHASE;
}
}
break;
// 已采购未改造完成 获取合同签订时间
case PURCHASED_UNMODIFIED:{
Map<String, ProjectStatusChange> purchasedUnmodifiedMap = projectStatusChangeService.listLastEventMap(projectCodes,
ProjectStateChangeEvent.SUBMIT_PURCHASE_CONTRACT_RECORD);
if (CollUtil.isNotEmpty(purchasedUnmodifiedMap)){
projectStatusChangeMap.putAll(purchasedUnmodifiedMap);
stepName = TaskConstant.StepName.ADAPT_MODIFY;
}
}
break;
// 已改造完成未终验 获取单位确认时间
case MODIFIED_NOT_FINAL_INSPECTION:{
Map<String, ProjectStatusChange> modifiedNotFinalInspectionMap = projectStatusChangeService.listLastEventMap(projectCodes,
ProjectStateChangeEvent.SUBMIT_PURCHASE_ORG_CONFIRM);
if (CollUtil.isNotEmpty(modifiedNotFinalInspectionMap)){
projectStatusChangeMap.putAll(modifiedNotFinalInspectionMap);
stepName = TaskConstant.StepName.FINAL;
}
}
break;
default:
log.error("Unexpected value: {}", flowType);
}
// 查询当前预警表中 已存在的的滞后预警数据
Wrapper<ProjectEarlyWarning> warningQuery = Wrappers.lambdaQuery(ProjectEarlyWarning.class)
.eq(ProjectEarlyWarning::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode());
List<ProjectEarlyWarning> projectEarlyWarnings = projectEarlyWarningService.list(warningQuery);
Map<String, ProjectEarlyWarning> projectEarlyWarningMap = CollUtils.listToMap(projectEarlyWarnings, c -> c.getProjectCode() + StrPool.DASH + c.getStepName());
// 按照当前配置的滞后规则 获取需要首页监测预警展示的项目
// 获取项目 滞后(历时)时间
HashMap<String, LocalDateTime> touchTimeMap = MapUtil.newHashMap();
String finalStepName = stepName;
List<ProjectEarlyWarning> needRemoved = Lists.newArrayList();
List<Project> 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<String> batchEmployees = Lists.newArrayList();
if (StringUtils.isNotBlank(notice) && notice.contains(WarningNoticeTypeEnum.SUPER_ADMIN.getCode().toString())) {
// 获取超级管理员用户信息
List<UserInfo> superAdminUsers = userInfoHelper.getEmployeeCodesByRoleEnum(RoleEnum.SUPER_ADMIN);
List<String> superAdminEmployeeCodes = superAdminUsers.stream().map(UserInfo::getEmployeeCode).collect(Collectors.toList());
batchEmployees.addAll(superAdminEmployeeCodes);
}
if (StringUtils.isNotBlank(notice) && notice.contains(WarningNoticeTypeEnum.UNIT_ADMIN.getCode().toString())) {
// 获取单位管理员用户信息
List<UserInfo> unitAdminUsers = userInfoHelper.getEmployeeCodesByRoleEnum(RoleEnum.COMPANY_MANAGER);
// 过滤出当前项目所属单位的单位管理员
List<String> 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 long getDurationTime(LocalDateTime touchTime, LocalDateTime now, ChronoUnit timeUnit) {
return timeUnit.between(touchTime, now);
}

/**
* 填报预警
*/
@Scheduled(cron = "${early-warning-without-submit.cron:0 0/5 * * * ?}")
//@Scheduled(cron = "${early-warning-without-submit.cron:0 0/5 * * * ?}")
public void doEarlyWarningDeclared() {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
@@ -121,7 +262,7 @@ public class EarlyWarningWithoutSubmitTask {
return;
}
String path = flowType.getPath();
//查询 所有这个区域的项目 未提交的项目
//查询 所有这个单位 未提交的项目
Wrapper<Project> projectQuery = Wrappers.lambdaQuery(Project.class)
.eq(Project::getBuildOrgCode, mhUnitId)
.eq(Project::getNewest, Boolean.TRUE)
@@ -131,20 +272,8 @@ public class EarlyWarningWithoutSubmitTask {
List<String> projectCodes = CollUtils.fieldList(needNextProjects, Project::getProjectCode);
Map<String, ProjectStatusChange> projectStatusChangeMap;
switch (flowType) {
// 已资金下达未立项
case FUNDS_ISSUED_NOT_ESTABLISHED_PROJECT:{
projectStatusChangeMap = projectStatusChangeService.listLastEventMap(projectCodes,
ProjectStateChangeEvent.ANNUAL_PLAN_PASS);
}
break;
// 已立项未开标
case APPROVED_PROJECT_BIT_NOT_OPEN:{
projectStatusChangeMap = projectStatusChangeService.listLastEventMap(projectCodes,
ProjectStateChangeEvent.DECLARED_RECORD_PASS);
}
break;
// 已开标未采购
case BIT_OPENED_NOT_PURCHASED:{
// 已立项未采购
case APPROVED_PROJECT_NOT_PURCHASED:{
projectStatusChangeMap = projectStatusChangeService.listLastEventMap(projectCodes,
ProjectStateChangeEvent.SUBMIT_PURCHASE_NOTICE);
}
@@ -251,296 +380,4 @@ public class EarlyWarningWithoutSubmitTask {
log.info("=========== 预警填报超时任务结束 耗时{}s", stopWatch.getTotalTimeSeconds());
}

//@Scheduled(cron = "10 0/2 * * * ?")
public void doEarlyWarningOperation() throws UnknownHostException {
log.info("=========== 预警实施超时任务开始 ========");
StopWatch stopWatch = new StopWatch();
stopWatch.start();

// 1.查询 填报的 预警规则 填报类型的 每个区域 每个规则
List<WflowEarlyWarning> warnings = earlyWarningService.list(Wrappers.lambdaQuery(WflowEarlyWarning.class)
.eq(WflowEarlyWarning::getRuleType, WarningRuleTypeEnum.OPERATION_WARNING.getCode()));
for (WflowEarlyWarning warning : warnings) {
//2. 取出rule的数据
if (Boolean.FALSE.equals(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 noticeContent = warning.getNoticeContent();
String adventContent = warning.getAdventContent();
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 adventTime = rJson.getInteger("adventTime");
Integer biz = rJson.getInteger("biz");
String notice = rJson.getString("notice");
if ((Objects.isNull(time) && Objects.isNull(adventTime)) || Objects.isNull(biz)) {
log.info("规则数据 错误 :{}", rJson);
return;
}

WarningOperationTypeEnum operationTypeEnum = WarningOperationTypeEnum.getByCode(biz);
if (Objects.isNull(operationTypeEnum)) {
log.info("匹配不到 业务类型");
return;
}

//得出 对应待提交的项目状态
Integer projectStatus = operationTypeEnum.getProjectStutas();
String path = operationTypeEnum.getPath();
String areaCode = warning.getAreaCode();
//测试先用分钟
//查询 所有这个区域的项目 未提交的项目
List<Project> needNextProjects = projectService.list(Wrappers.lambdaQuery(Project.class)
.eq(Project::getAreaCode, areaCode)
.eq(Project::getNewest, Boolean.TRUE)
.eq(Project::getStatus, projectStatus));
if (needNextProjects.isEmpty()) {
return;
}
List<String> projectCodes = needNextProjects.stream().map(Project::getProjectCode).collect(Collectors.toList());

List<Operation> operations = operationService.list(Wrappers.lambdaQuery(Operation.class)
.in(Operation::getProjectCode, projectCodes));

Map<String, Operation> operationMap = operations.stream().collect(Collectors.toMap(Operation::getProjectCode, o -> o));
Map<String, List<Integer>> noticeMap = Maps.newHashMap();
//需要发通知的项目
List<Project> needToWaringProjects = needNextProjects.stream()
.filter(p -> {
//判断 实施信息中 初验和终验的时间
if (!operationMap.containsKey(p.getProjectCode())) {
return Boolean.FALSE;
}
Operation operation = operationMap.get(p.getProjectCode());

List<Integer> noticeTypes = Lists.newArrayList();
if (WarningOperationTypeEnum.CHUYAN.eq(biz)) {
//初验
if (Objects.nonNull(time) && Duration.between(operation.getInitialInspectionDate(), LocalDateTime.now()).toMinutes() >= time * 60 && //time * 60
Duration.between(operation.getInitialInspectionDate(), LocalDateTime.now()).toMinutes() <= time * 60 + 1) { //time * 60
noticeTypes.add(com.wflow.enums.WarningNoticeTypeEnum.OVER.getCode());
}
if (Objects.nonNull(adventTime) && Duration.between(operation.getInitialInspectionDate(), LocalDateTime.now()).toMinutes() >= adventTime * 60 && //time * 60
Duration.between(operation.getInitialInspectionDate(), LocalDateTime.now()).toMinutes() <= adventTime * 60 + 1) {
noticeTypes.add(com.wflow.enums.WarningNoticeTypeEnum.ADVENT.getCode());
}
} else if (WarningOperationTypeEnum.ZHONGYAN.eq(biz)) {
//终验
if (Objects.nonNull(time) && Duration.between(operation.getFinalInspectionDate(), LocalDateTime.now()).toMinutes() >= time * 60 && //time * 60
Duration.between(operation.getFinalInspectionDate(), LocalDateTime.now()).toMinutes() <= time * 60 + 1) { //time * 60
noticeTypes.add(com.wflow.enums.WarningNoticeTypeEnum.OVER.getCode());
}
if (Objects.nonNull(adventTime) && Duration.between(operation.getFinalInspectionDate(), LocalDateTime.now()).toMinutes() >= adventTime * 60 && //time * 60
Duration.between(operation.getFinalInspectionDate(), LocalDateTime.now()).toMinutes() <= adventTime * 60 + 1) { //time * 60
noticeTypes.add(com.wflow.enums.WarningNoticeTypeEnum.ADVENT.getCode());
}
}
if (CollUtil.isNotEmpty(noticeTypes)) {
noticeMap.put(p.getProjectCode(), noticeTypes);
//项目 运维预警
projectEarlyWarningService.earlyWarning(p,
WarningRuleTypeEnum.OPERATION_WARNING.getCode(), noticeTypes);
return Boolean.TRUE;
}
return Boolean.FALSE;
})
.collect(Collectors.toList());

if (StringUtils.isBlank(noticeMethod) ||
(!noticeMethod.contains(String.valueOf(CommonEnum.ZWDD.getCode())) &&
!noticeMethod.contains(String.valueOf(CommonEnum.MOBILE.getCode())))) {
log.info("通知方式为空或者错误!");
return;
}

for (Project needToWaringProject : needToWaringProjects) {
//去预警通知
List<String> batchEmployees = Lists.newArrayList();

if (StringUtils.isBlank(notice)) {
String sponsor = needToWaringProject.getSponsor();
batchEmployees.add(sponsor);
} else {
//去预警通知人 1.超级管理员 2.单位管理员 如果都包含 都要发

if (notice.contains(WarningNoticeTypeEnum.SUPER_ADMIN.getCode().toString())) {
String employeeCode = null;
String username = needToWaringProject.getContactName();
String mobile = needToWaringProject.getContactPhone();
if (StrUtil.isAllNotBlank(username, mobile)) {
UserInfo user = userInfoService.getByUserNameAndMobile(username, mobile);
if (Objects.nonNull(user)) {
employeeCode = user.getEmployeeCode();
}
if (Objects.nonNull(employeeCode)) {
batchEmployees.add(employeeCode);
}
}
}
if (notice.contains(WarningNoticeTypeEnum.UNIT_ADMIN.getCode().toString())) {
String employeeCode = null;
String username = needToWaringProject.getResponsibleMan();
String mobile = needToWaringProject.getResponsibleManMobile();
if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(mobile)) {
UserInfo user = userInfoService.getByUserNameAndMobile(username, mobile);
if (Objects.nonNull(user)) {
employeeCode = user.getEmployeeCode();
}
if (Objects.nonNull(employeeCode)) {
batchEmployees.add(employeeCode);
}
}
}
}

if (noticeMap.containsKey(needToWaringProject.getProjectCode())) {
List<Integer> noticeTypes = noticeMap.get(needToWaringProject.getProjectCode());
for (Integer noticeType : noticeTypes) {
for (String employeeCode : batchEmployees) {
earlyWarningManage.doEarlyWarning(noticeMethod, Objects.nonNull(noticeType) && noticeType.equals(1) ? noticeContent : adventContent,
adventTime, time, biz,
needToWaringProject.getUpdateOn(), Long.valueOf(employeeCode), needToWaringProject,
WarningRuleTypeEnum.OPERATION_WARNING.getCode(), noticeType, path,
String.join(StrPool.COMMA, batchEmployees), null);
}
}
}

}
});
}
}
}

stopWatch.stop();
log.info("=========== 预警实施超时任务结束 耗时{}s", stopWatch.getTotalTimeSeconds());
}

/**
* 续建项目资金 超时未审批定时器
*
* @throws UnknownHostException
*/
//@Scheduled(cron = "20 0/2 * * * ?")
public void doEarlyWarningRenewalFund() throws UnknownHostException {
log.info("=========== 预警续建资金项目 超时任务开始 ========");
StopWatch stopWatch = new StopWatch();
stopWatch.start();

// 1.查询 填报的 预警规则 填报类型的 每个区域 续建项目资金审批
List<WflowEarlyWarning> warnings = earlyWarningService.list(Wrappers.lambdaQuery(WflowEarlyWarning.class)
.eq(WflowEarlyWarning::getRuleType, WarningRuleTypeEnum.RENEWAL_FUND.getCode()));
for (WflowEarlyWarning warning : warnings) {
//2. 取出rule的数据
if (Boolean.FALSE.equals(warning.getIsOpen())) {
log.info(warning.getId() + " 此规则关闭了");
continue;
}

String noticeMethod = warning.getNoticeMethod();
String noticeContent = warning.getNoticeContent();
String adventContent = warning.getAdventContent();
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 adventTime = rJson.getInteger("adventTime");
if (Objects.isNull(time) && Objects.isNull(adventTime)) {
log.info("规则数据 错误 :{}", rJson);
return;
}

//得出 对应待提交的续建项目区域信息
String areaCode = warning.getAreaCode();
//测试先用分钟
//查询 所有这个区域的项目 未提交的项目
List<ProjectRenewalFundDeclaration> needNextProjects = renewalFundDeclarationService.list(Wrappers.lambdaQuery(ProjectRenewalFundDeclaration.class)
.eq(ProjectRenewalFundDeclaration::getRegionCode, areaCode)
.eq(ProjectRenewalFundDeclaration::getDeleted, Boolean.FALSE)
.eq(ProjectRenewalFundDeclaration::getApprovalStatus, ProjectRenewalApprovalStatusEnum.PENDING.name()));

Map<String, List<Integer>> noticeTypeMap = Maps.newHashMap();
//需要发通知的项目
List<ProjectRenewalFundDeclaration> needToWaringProjects = needNextProjects.stream()
.filter(p -> {
//超时未审批
List<Integer> noticeTypes = Lists.newArrayList();
if (Objects.nonNull(time) && Duration.between(p.getCreateOn(), LocalDateTime.now()).toMinutes() >= time * 60 && //time * 60
Duration.between(p.getCreateOn(), LocalDateTime.now()).toMinutes() <= time * 60 + 1) { //time * 60
noticeTypes.add(com.wflow.enums.WarningNoticeTypeEnum.OVER.getCode());
}
if (Objects.nonNull(adventTime) && Duration.between(p.getCreateOn(), LocalDateTime.now()).toMinutes() >= adventTime * 60 && //time * 60
Duration.between(p.getCreateOn(), LocalDateTime.now()).toMinutes() <= adventTime * 60 + 1) { //time * 60
noticeTypes.add(com.wflow.enums.WarningNoticeTypeEnum.ADVENT.getCode());
}
if (CollUtil.isNotEmpty(noticeTypes)) {
noticeTypeMap.put(p.getProjectCode(), noticeTypes);
//项目 运维预警
projectEarlyWarningService.earlyWarning(p.getProjectCode(),
WarningRuleTypeEnum.OPERATION_WARNING.getCode(), noticeTypes);
return Boolean.TRUE;
}
return Boolean.FALSE;
})
.collect(Collectors.toList());

if (StringUtils.isBlank(noticeMethod) ||
(!noticeMethod.contains(String.valueOf(CommonEnum.ZWDD.getCode())) &&
!noticeMethod.contains(String.valueOf(CommonEnum.MOBILE.getCode())))) {
log.info("通知方式为空或者错误!");
return;
}

for (ProjectRenewalFundDeclaration needToWaringProject : needToWaringProjects) {
String path = "projectStoreManage/renewalProjectAsscess?projectRenewalId=" + needToWaringProject.getId();
Project project = projectService.getProjectByCode(needToWaringProject.getProjectCode());
//去预警通知 发给区管
List<UserInfo> users = roleManage.getUsersByRoleType(RoleEnum.REGION_MANAGER.name());
String employeesStr = users.stream().map(UserInfo::getEmployeeCode)
.collect(Collectors.joining(StrPool.COMMA));
for (UserInfo user : users) {
if (noticeTypeMap.containsKey(needToWaringProject.getProjectCode())) {
List<Integer> noticeTypes = noticeTypeMap.get(needToWaringProject.getProjectCode());
for (Integer noticeType : noticeTypes) {
earlyWarningManage.doEarlyWarning(noticeMethod, Objects.nonNull(noticeType) && noticeType.equals(1) ? noticeContent : adventContent,
adventTime, time, null,
needToWaringProject.getUpdateOn(), Long.valueOf(user.getEmployeeCode()), project,
WarningRuleTypeEnum.RENEWAL_FUND.getCode(), noticeType, path, employeesStr, needToWaringProject.getId().toString());
}
}

}
}
});
}
}
}

stopWatch.stop();
log.info("=========== 预警续建资金项目 超时任务结束 耗时{}s", stopWatch.getTotalTimeSeconds());
}
}

+ 2
- 1
hz-pm-api/src/main/java/com/hz/pm/api/sys/enumeration/ProjectEarlyWarningStatusEnum.java View File

@@ -20,7 +20,8 @@ public enum ProjectEarlyWarningStatusEnum {
*/
NORMAL(1, "正常"),
OVER_TIME(2, "超期"),
ADVENT_TIME(3, "临期");
ADVENT_TIME(3, "临期"),
DELAY_TIME(4,"滞后");

private final Integer code;
private final String desc;


+ 41
- 39
hz-pm-api/src/main/java/com/hz/pm/api/sys/manage/EarlyWarningManage.java View File

@@ -1,16 +1,20 @@
package com.hz.pm.api.sys.manage;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hz.pm.api.common.helper.UserInfoHelper;
import com.hz.pm.api.common.model.constant.BizConst;
import com.hz.pm.api.projectlib.model.entity.Project;
import com.hz.pm.api.projectlib.model.enumeration.InstTypeEnum;
import com.hz.pm.api.projectlib.model.enumeration.WarningFlowTypeEnum;
import com.hz.pm.api.projectlib.model.enumeration.WarningOperationTypeEnum;
import com.hz.pm.api.staging.enums.MsgTypeEnum;
import com.hz.pm.api.sys.model.entity.Notify;
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 com.hz.pm.api.sys.service.INotifyService;
import com.hz.pm.api.user.security.model.UserFullInfoDTO;
import com.ningdatech.basic.util.StrPool;
import com.wflow.enums.WarningNoticeTypeEnum;
import com.wflow.enums.WarningRuleTypeEnum;
import lombok.AllArgsConstructor;
@@ -20,6 +24,7 @@ import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Objects;

/**
@@ -83,7 +88,7 @@ public class EarlyWarningManage {
}
records.setRuleType(WarningRuleTypeEnum.DECLARED_WARNING.getCode());
break;
case OPERATION_WARNING:
case DELAY_WARNING:
if (Objects.isNull(noticeType)) {
content = convertContent(noticeContent, project.getProjectName(),
WarningOperationTypeEnum.getByCode(biz), overTimeout);
@@ -94,18 +99,7 @@ public class EarlyWarningManage {
content = convertContent(noticeContent, project.getProjectName(),
WarningOperationTypeEnum.getByCode(biz), overTimeout);
}
records.setRuleType(WarningRuleTypeEnum.OPERATION_WARNING.getCode());
break;
case RENEWAL_FUND:
if (Objects.isNull(noticeType)) {
content = convertContent(noticeContent, project.getProjectName(), overTimeout);
} else if (noticeType.equals(WarningNoticeTypeEnum.ADVENT.getCode())) {
content = convertAdventContent(noticeContent, project.getProjectName(), adventTimeout, overTimeout);
} else {
content = convertContent(noticeContent, project.getProjectName(), overTimeout);
}

records.setRuleType(WarningRuleTypeEnum.RENEWAL_FUND.getCode());
records.setRuleType(WarningRuleTypeEnum.DELAY_WARNING.getCode());
break;
default:
log.warn("匹配不到 规则类型");
@@ -141,6 +135,40 @@ public class EarlyWarningManage {
notifyService.save(notify);
}

public void doEarlyWarningDelay(String noticeMethod, Integer biz, Project project,
Integer ruleType, Integer noticeType, String path,
HashMap<String, LocalDateTime> touchTimeMap) {
// 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);
earlyWarningRecordsService.saveOrUpdate(records);
}

/**
* 催办
*
@@ -189,32 +217,6 @@ public class EarlyWarningManage {
}
records.setRuleType(WarningRuleTypeEnum.DECLARED_WARNING.getCode());
break;
case OPERATION_WARNING:
records = new WflowEarlyWarningRecords();
if (Objects.isNull(noticeType)) {
content = convertContent(noticeContent, project.getProjectName(),
WarningOperationTypeEnum.getByCode(biz), overTimeout);
} else if (noticeType.equals(WarningNoticeTypeEnum.ADVENT.getCode())) {
content = convertAdventContent(noticeContent, project.getProjectName(),
WarningOperationTypeEnum.getByCode(biz), adventTimeout, overTimeout);
} else {
content = convertContent(noticeContent, project.getProjectName(),
WarningOperationTypeEnum.getByCode(biz), overTimeout);
}
records.setRuleType(WarningRuleTypeEnum.OPERATION_WARNING.getCode());
break;
case RENEWAL_FUND:
records = new WflowEarlyWarningRecords();
if (Objects.isNull(noticeType)) {
content = convertContent(noticeContent, project.getProjectName(), overTimeout);
} else if (noticeType.equals(WarningNoticeTypeEnum.ADVENT.getCode())) {
content = convertAdventContent(noticeContent, project.getProjectName(), adventTimeout, overTimeout);
} else {
content = convertContent(noticeContent, project.getProjectName(), overTimeout);
}

records.setRuleType(WarningRuleTypeEnum.RENEWAL_FUND.getCode());
break;
default:
log.info("匹配不到 规则类型");
return;


+ 2
- 2
hz-pm-api/src/main/java/com/hz/pm/api/sys/manage/MenuManage.java View File

@@ -13,7 +13,7 @@ import com.hz.pm.api.common.enumeration.ProjectProcessType;
import com.hz.pm.api.common.helper.RegionCacheHelper;
import com.hz.pm.api.common.model.entity.MenuTreeEntity;
import com.hz.pm.api.common.util.TreeUtil;
import com.hz.pm.api.scheduler.contants.TaskContant;
import com.hz.pm.api.scheduler.contants.TaskConstant;
import com.hz.pm.api.sys.model.dto.RegionDTO;
import com.hz.pm.api.sys.model.entity.Menu;
import com.hz.pm.api.sys.model.vo.MenuRoleVO;
@@ -94,7 +94,7 @@ public class MenuManage {
for(RegionDTO region : regions){
log.info("当前初始化的是 【{}】 流程配置",region.getRegionName());

Integer[] processTypeList = TaskContant.Wflow.APPLY_PROCESS_TYPE_LIST;
Integer[] processTypeList = TaskConstant.Wflow.APPLY_PROCESS_TYPE_LIST;
for(Integer processType : processTypeList){
String formName = ProjectProcessType.getDesc(processType);
WflowModelHistorysInsertDto models = new WflowModelHistorysInsertDto();


+ 7
- 2
hz-pm-api/src/main/java/com/hz/pm/api/sys/model/entity/ProjectEarlyWarning.java View File

@@ -51,14 +51,19 @@ public class ProjectEarlyWarning implements Serializable {
private Boolean operationWarning;
@ApiModelProperty(value = "续建资金预警是否异常")
private Boolean renewalFundWarning;
@ApiModelProperty(value = "滞后预警是否异常")
private Boolean delayWarning;
@ApiModelProperty(value = "是否正常")
private Boolean normal;

@ApiModelProperty(value = "规则类型 1.流程预警规则 2.填报预警规则 3.实施监督 4.续建资金项目")
@ApiModelProperty(value = "规则类型 1.滞后预警规则 2.填报预警规则 3.流程预警规则")
private Integer ruleType;
@ApiModelProperty(value = "1超期 2临期")
@ApiModelProperty(value = "1超期 2临期 3滞后")
private Integer noticeType;

private LocalDateTime createOn;

@ApiModelProperty(value = "滞后环节名称")
private String stepName;

}

+ 1
- 1
hz-pm-api/src/main/java/com/hz/pm/api/sys/model/entity/WflowEarlyWarningRecords.java View File

@@ -113,7 +113,7 @@ public class WflowEarlyWarningRecords implements Serializable {
/**
* 规则
*/
@ApiModelProperty(value = "规则类型 1.流程预警规则 2.填报预警规则 3.实施监督 4.续建资金项目")
@ApiModelProperty(value = "规则类型 1.滞后预警规则 2.填报预警规则 3.流程预警规则")
private Integer ruleType;

@ApiModelProperty(value = "业务biz")


+ 2
- 0
hz-pm-api/src/main/java/com/hz/pm/api/sys/service/IProjectEarlyWarningService.java View File

@@ -16,4 +16,6 @@ public interface IProjectEarlyWarningService extends IService<ProjectEarlyWarnin
Boolean earlyWarning(Project project, Integer ruleType, List<Integer> noticeTypes);

Boolean earlyWarning(String projectCode, Integer code, List<Integer> noticeTypes);

Boolean earlyWarning(Project project, Integer ruleType, Integer noticeType, String stepName);
}

+ 21
- 12
hz-pm-api/src/main/java/com/hz/pm/api/sys/service/impl/ProjectEarlyWarningServiceImpl.java View File

@@ -16,6 +16,7 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

@@ -38,19 +39,19 @@ public class ProjectEarlyWarningServiceImpl extends ServiceImpl<ProjectEarlyWarn

@Override
public Boolean earlyWarning(Project project, Integer ruleType, Integer noticeType) {
return doEarlyWarning(project, ruleType, noticeType);
return doEarlyWarning(project, ruleType, noticeType, null);
}

@Override
public Boolean earlyWarning(Project project, Integer ruleType, List<Integer> noticeTypes) {
if(CollUtil.isNotEmpty(noticeTypes)){
if(noticeTypes.contains(WarningNoticeTypeEnum.OVER.getCode())){
return doEarlyWarning(project, ruleType,WarningNoticeTypeEnum.OVER.getCode());
return doEarlyWarning(project, ruleType,WarningNoticeTypeEnum.OVER.getCode(),null);
}else{
return doEarlyWarning(project, ruleType,WarningNoticeTypeEnum.ADVENT.getCode());
return doEarlyWarning(project, ruleType,WarningNoticeTypeEnum.ADVENT.getCode(),null);
}
}
return doEarlyWarning(project, ruleType, null);
return doEarlyWarning(project, ruleType, null,null);
}

@Override
@@ -62,7 +63,12 @@ public class ProjectEarlyWarningServiceImpl extends ServiceImpl<ProjectEarlyWarn
return earlyWarning(project,ruleType,noticeTypes);
}

private Boolean doEarlyWarning(Project project, Integer ruleType, Integer noticeType) {
@Override
public Boolean earlyWarning(Project project, Integer ruleType, Integer noticeType, String stepName) {
return doEarlyWarning(project, ruleType, noticeType, stepName);
}

private Boolean doEarlyWarning(Project project, Integer ruleType, Integer noticeType, String stepName) {
if(Objects.isNull(project) || Objects.isNull(ruleType)){
return Boolean.FALSE;
}
@@ -76,20 +82,19 @@ public class ProjectEarlyWarningServiceImpl extends ServiceImpl<ProjectEarlyWarn
}else{
warning.setBuildOrgCode(project.getBuildOrgCode());
warning.setAreaCode(project.getAreaCode());
warning.setCreateOn(LocalDateTime.now());
warning.setProjectCode(projectCode);
}

switch (WarningRuleTypeEnum.checkByCode(ruleType)){
case PROCESS_WARNING:
warning.setProcessWarning(Boolean.TRUE);
case DELAY_WARNING:
warning.setDelayWarning(Boolean.TRUE);
break;
case DECLARED_WARNING:
warning.setDeclaredWarning(Boolean.TRUE);
break;
case OPERATION_WARNING:
warning.setOperationWarning(Boolean.TRUE);
break;
case RENEWAL_FUND:
warning.setRenewalFundWarning(Boolean.TRUE);
case PROCESS_WARNING:
warning.setProcessWarning(Boolean.TRUE);
break;
default:
return Boolean.FALSE;
@@ -106,6 +111,9 @@ public class ProjectEarlyWarningServiceImpl extends ServiceImpl<ProjectEarlyWarn
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;
@@ -114,6 +122,7 @@ public class ProjectEarlyWarningServiceImpl extends ServiceImpl<ProjectEarlyWarn

warning.setNoticeType(noticeType);
warning.setNormal(Boolean.FALSE);
warning.setStepName(stepName);
return saveOrUpdate(warning);
}
}

+ 6
- 0
hz-pm-api/src/main/java/com/hz/pm/api/sys/utils/EarlyWarningUtil.java View File

@@ -2,9 +2,15 @@ package com.hz.pm.api.sys.utils;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hz.pm.api.projectlib.model.entity.Project;
import com.hz.pm.api.sys.model.entity.ProjectEarlyWarning;
import com.hz.pm.api.sys.model.entity.WflowEarlyWarningRecords;
import com.hz.pm.api.user.helper.MhUnitCache;
import com.hz.pm.api.user.security.model.UserFullInfoDTO;
import com.hz.pm.api.user.security.model.UserInfoDetails;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
* @Classname EarlyWarningUtil


+ 0
- 1
hz-pm-api/src/main/java/com/hz/pm/api/user/service/IUserInfoService.java View File

@@ -42,5 +42,4 @@ public interface IUserInfoService extends IService<UserInfo> {
.eq(UserInfo::getUsername, userName)
.last(BizConst.LIMIT_1));
}

}

+ 1
- 0
hz-pm-api/src/main/java/com/hz/pm/api/user/service/impl/UserInfoServiceImpl.java View File

@@ -11,6 +11,7 @@ import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**


+ 7
- 4
hz-pm-api/src/main/java/com/hz/pm/api/workbench/controller/WorkbenchController.java View File

@@ -5,10 +5,7 @@ import com.hz.pm.api.projectlib.model.vo.SystemReplaceInfoVO;
import com.hz.pm.api.workbench.manage.WorkbenchManage;
import com.hz.pm.api.workbench.model.WorkbenchProjectLibReq;
import com.hz.pm.api.workbench.model.WorkbenchReq;
import com.hz.pm.api.workbench.model.vo.ProjectProcessStatVO;
import com.hz.pm.api.workbench.model.vo.ProjectTotalViewVO;
import com.hz.pm.api.workbench.model.vo.WorkbenchProjectEarlyWarnVO;
import com.hz.pm.api.workbench.model.vo.WorkbenchVO;
import com.hz.pm.api.workbench.model.vo.*;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.log.annotation.WebLog;
import io.swagger.annotations.Api;
@@ -84,4 +81,10 @@ public class WorkbenchController {
return workbenchManage.projectEarlyWarnings(req);
}

@GetMapping("/projectMonitorEarlyWarnings")
@ApiOperation("项目监测预警")
public List<WorkbenchProjectMonitorEarlyWarnVO> projectMonitorEarlyWarnings(WorkbenchReq req) {
return workbenchManage.projectMonitorEarlyWarnings(req);
}

}

+ 73
- 0
hz-pm-api/src/main/java/com/hz/pm/api/workbench/manage/WorkbenchManage.java View File

@@ -47,6 +47,7 @@ import com.hz.pm.api.sys.model.entity.WflowEarlyWarningRecords;
import com.hz.pm.api.sys.model.vo.ProjectEarlyWarningVO;
import com.hz.pm.api.sys.service.IEarlyWarningRecordsService;
import com.hz.pm.api.sys.service.IProjectEarlyWarningService;
import com.hz.pm.api.sys.utils.EarlyWarningUtil;
import com.hz.pm.api.todocenter.manage.TodoCenterManage;
import com.hz.pm.api.todocenter.model.req.ToBeProcessedReq;
import com.hz.pm.api.todocenter.model.vo.ResToBeProcessedVO;
@@ -54,6 +55,7 @@ import com.hz.pm.api.todocenter.model.vo.TodoCenterStatisticsVO;
import com.hz.pm.api.todocenter.model.vo.TodoVO;
import com.hz.pm.api.user.helper.MhUnitCache;
import com.hz.pm.api.user.security.model.UserFullInfoDTO;
import com.hz.pm.api.user.security.model.UserInfoDetails;
import com.hz.pm.api.user.util.LoginUserUtil;
import com.hz.pm.api.workbench.converter.WorkbenchConverter;
import com.hz.pm.api.workbench.model.WorkbenchProcessNode;
@@ -795,4 +797,75 @@ public class WorkbenchManage {
return earlyWarningStat;
}

public List<WorkbenchProjectMonitorEarlyWarnVO> projectMonitorEarlyWarnings(WorkbenchReq req) {
UserInfoDetails userInfoDetails = LoginUserUtil.loginUserDetail();
// 从预警表中查询当前登录用户所能查看的项目
LambdaQueryWrapper<ProjectEarlyWarning> queryWrapper = Wrappers.lambdaQuery(ProjectEarlyWarning.class);
buildPermissionWarningWrapper(queryWrapper,userInfoDetails);
// 查询状态非正常的预警信息
queryWrapper.eq(ProjectEarlyWarning::getNormal,Boolean.FALSE);
queryWrapper.ne(ProjectEarlyWarning::getStatus, ProjectEarlyWarningStatusEnum.NORMAL);
if (req.getUnitStrip() != null) {
String unitStripSql = String.format("select 1 from nd_project np where " +
"np.project_code = nd_project_early_warning.project_code " +
" and np.newest = 1 and np.unit_strip = %d", req.getUnitStrip());
queryWrapper.exists(unitStripSql);
}
if (req.getProjectYear() != null) {
LocalDate startDate = LocalDate.of(req.getProjectYear(), 1, 1);
LocalDate endDate = LocalDate.now().plusDays(1);
queryWrapper.between(ProjectEarlyWarning::getCreateOn, startDate, endDate);
}

List<ProjectEarlyWarning> records = projectEarlyWarningService.list(queryWrapper);
if (CollUtil.isNotEmpty(records)) {
List<String> projectCodes = CollUtils.fieldList(records, ProjectEarlyWarning::getProjectCode);

Wrapper<WflowEarlyWarningRecords> wewQuery = Wrappers.lambdaQuery(WflowEarlyWarningRecords.class)
.in(WflowEarlyWarningRecords::getProjectCode, projectCodes)
.orderByDesc(WflowEarlyWarningRecords::getWarningTime);
List<WflowEarlyWarningRecords> warningRecords = earlyWarningRecordsService.list(wewQuery);
Set<String> projectCodeSet = Sets.newHashSet();
Map<String, WflowEarlyWarningRecords> warningMap = warningRecords.stream()
.filter(w -> projectCodeSet.add(w.getProjectCode()))
.collect(Collectors.toMap(WflowEarlyWarningRecords::getProjectCode, w -> w));

return records.stream().map(o -> {
WorkbenchProjectMonitorEarlyWarnVO vo = new WorkbenchProjectMonitorEarlyWarnVO();
vo.setStepName(o.getStepName());
//取最新一条预警信息
if (warningMap.containsKey(o.getProjectCode())) {
WflowEarlyWarningRecords wew = warningMap.get(o.getProjectCode());
vo.setBuildOrgCode(wew.getBuildOrgCode());
vo.setBuildOrgName(wew.getBuildOrgName());
vo.setInstStart(wew.getInstStart());
vo.setProjectId(wew.getProjectId());
vo.setProjectCode(wew.getProjectCode());
vo.setProjectName(wew.getProjectName());
vo.setRecordId(wew.getId());
}
return vo;
}).filter(w -> Objects.nonNull(w.getInstStart()))
// 根据预警开始时间自然排序 时间小的在前 历时时间最长
.sorted(Comparator.comparing(WorkbenchProjectMonitorEarlyWarnVO::getInstStart))
.collect(Collectors.toList());
}
return Collections.emptyList();
}

private void buildPermissionWarningWrapper(LambdaQueryWrapper<ProjectEarlyWarning> wrapper, UserInfoDetails user) {
//如果是超管的话
if (user.hasSuperAdmin() || user.hasRegionAdmin()) {
// 可以看所有
}
// 如果是单位管理员 查看本单位及下属单位
else if (user.hasOrgAdmin()) {
List<String> viewChildIdsRecursion = mhUnitCache.getViewChildIdsRecursion(user.getMhUnitId())
.stream().map(String::valueOf).collect(Collectors.toList());
wrapper.in(ProjectEarlyWarning::getBuildOrgCode, viewChildIdsRecursion);
} else {
// 否则都只能看自己单位的
wrapper.eq(ProjectEarlyWarning::getBuildOrgCode, user.getMhUnitIdStr());
}
}
}

+ 46
- 0
hz-pm-api/src/main/java/com/hz/pm/api/workbench/model/vo/WorkbenchProjectMonitorEarlyWarnVO.java View File

@@ -0,0 +1,46 @@
package com.hz.pm.api.workbench.model.vo;

import java.time.LocalDateTime;
import java.util.List;

import com.hz.pm.api.sys.model.vo.ProjectEarlyWarningVO;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
* <p>
* ProjectEarlyWarning
* </p>
*
* @author WendyYang
* @since 00:28 2024/8/28
*/
@Data
public class WorkbenchProjectMonitorEarlyWarnVO {

@ApiModelProperty(value = "预警ID")
private Long recordId;

@ApiModelProperty(value = "建设单位code")
private String buildOrgCode;

@ApiModelProperty("建设单位名称")
private String buildOrgName;

@ApiModelProperty("项目ID")
private Long projectId;

@ApiModelProperty("21位项目编号")
private String projectCode;

@ApiModelProperty("项目名称")
private String projectName;

@ApiModelProperty("环节名称")
private String stepName;

@ApiModelProperty("预警开始时间")
private LocalDateTime instStart;

}

+ 3
- 1
hz-pm-api/src/main/resources/application-dev.yml View File

@@ -224,4 +224,6 @@ thread-pool-util:
thread-name-prefix: request-executor-
scheduler:
core-pool-size: 2
thread-name-prefix: scheduler-executor-
thread-name-prefix: scheduler-executor-
early-warning-without-submit:
open: true

+ 2
- 0
hz-pm-api/src/main/resources/application-prod.yml View File

@@ -248,3 +248,5 @@ wflow-thread-pool-util:
queue-capacity: 300
keep-alive-seconds: 120
max-pool-size: 8
early-warning-without-submit:
open: true

+ 3
- 1
hz-pm-api/src/main/resources/application-test.yml View File

@@ -266,4 +266,6 @@ agent-login:
proxy:
secret-key: tqkwiqojg5j4eiypr3rb8w7nb4noa8b2
hz-pm:
interfaceKey: hz_meeting_expert_info
interfaceKey: hz_meeting_expert_info
early-warning-without-submit:
open: true

+ 2
- 2
hz-pm-api/src/test/java/com/hz/pm/api/sys/processDef/ProcessDefTest.java View File

@@ -9,7 +9,7 @@ import com.hz.pm.api.AppTests;
import com.hz.pm.api.common.model.constant.RegionConst;
import com.hz.pm.api.common.enumeration.ProjectProcessType;
import com.hz.pm.api.common.helper.RegionCacheHelper;
import com.hz.pm.api.scheduler.contants.TaskContant;
import com.hz.pm.api.scheduler.contants.TaskConstant;
import com.hz.pm.api.sys.model.dto.RegionDTO;
import com.wflow.bean.dto.WflowModelHistorysInsertDto;
import com.wflow.workflow.bean.process.ProcessNode;
@@ -68,7 +68,7 @@ public class ProcessDefTest extends AppTests {
for(RegionDTO region : regions){
log.info("当前初始化的是 【{}】 流程配置",region.getRegionName());

Integer[] processTypeList = TaskContant.Wflow.APPLY_PROCESS_TYPE_LIST;
Integer[] processTypeList = TaskConstant.Wflow.APPLY_PROCESS_TYPE_LIST;
for(Integer processType : processTypeList){
String formName = ProjectProcessType.getDesc(processType);
WflowModelHistorysInsertDto models = new WflowModelHistorysInsertDto();


+ 438
- 0
hz-pm-api/src/test/java/com/hz/pm/api/warning/DelayWarningTest.java View File

@@ -0,0 +1,438 @@
package com.hz.pm.api.warning;

import javax.annotation.Resource;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
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.helper.UserInfoHelper;
import com.hz.pm.api.common.model.constant.BizConst;
import com.hz.pm.api.common.statemachine.event.ProjectStateChangeEvent;
import com.hz.pm.api.common.statemachine.event.TenderStateChangeEvent;
import com.hz.pm.api.common.util.EnvironmentUtil;
import com.hz.pm.api.projectlib.entity.PurchaseStatusChange;
import com.hz.pm.api.projectlib.model.entity.Project;
import com.hz.pm.api.projectlib.model.entity.ProjectStatusChange;
import com.hz.pm.api.projectlib.model.enumeration.WarningFlowTypeEnum;
import com.hz.pm.api.projectlib.model.enumeration.WarningNoticeTypeEnum;
import com.hz.pm.api.projectlib.model.enumeration.status.ProjectStatus;
import com.hz.pm.api.projectlib.service.IProjectService;
import com.hz.pm.api.projectlib.service.IProjectStatusChangeService;
import com.hz.pm.api.projectlib.service.IPurchaseStatusChangeService;
import com.hz.pm.api.scheduler.contants.TaskConstant;
import com.hz.pm.api.sys.enumeration.ProjectEarlyWarningStatusEnum;
import com.hz.pm.api.sys.manage.EarlyWarningManage;
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 com.hz.pm.api.sys.service.IProjectEarlyWarningService;
import com.hz.pm.api.user.helper.MhUnitCache;
import com.hz.pm.api.user.model.entity.UserInfo;
import com.hz.pm.api.user.model.enumeration.RoleEnum;
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.enums.WarningRuleTypeEnum;
import com.wflow.service.IEarlyWarningService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.junit.Test;

import com.alibaba.fastjson.JSON;
import com.hz.pm.api.AppTests;
import com.hz.pm.api.projectdeclared.model.entity.ProjectDraft;
import com.hz.pm.api.projectdeclared.service.IProjectDraftService;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

/**
* @Classname DraftTest
* @Description
* @Date 2023/2/7 10:56
* @Author PoffyZhang
*/
@Slf4j
public class DelayWarningTest extends AppTests {

@Autowired
private IEarlyWarningService earlyWarningService;
@Autowired
private IProjectService projectService;
@Autowired
private EarlyWarningManage earlyWarningManage;
@Autowired
private IProjectEarlyWarningService projectEarlyWarningService;
@Autowired
private IProjectStatusChangeService projectStatusChangeService;
@Autowired
private UserInfoHelper userInfoHelper;
@Autowired
private EnvironmentUtil environmentUtil;
@Autowired
private IEarlyWarningRecordsService earlyWarningRecordsService;
@Autowired
private TaskService taskService;
@Autowired
private IPurchaseStatusChangeService purchaseStatusChangeService;

private ChronoUnit getTimeUnit() {
if (environmentUtil.isDevEnv()) {
return ChronoUnit.MINUTES;
} else {
return ChronoUnit.DAYS;
}
}

@Test
public void one(){

log.info("=========== 滞后预警任务开始 ===========");
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// 1.查询 填报的 滞后预警规则 填报类型的 每个单位的 每个规则
Wrapper<WflowEarlyWarning> query = Wrappers.lambdaQuery(WflowEarlyWarning.class)
.eq(WflowEarlyWarning::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode())
.eq(WflowEarlyWarning::getIsOpen, true);
List<WflowEarlyWarning> 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<Project> projectQuery = Wrappers.lambdaQuery(Project.class)
.eq(Project::getBuildOrgCode, mhUnitId)
.eq(Project::getNewest, Boolean.TRUE)
.eq(Project::getStatus, flowType.getProjectStatus().getCode());
List<Project> needNextProjects = projectService.list(projectQuery);
List<String> projectCodes = CollUtils.fieldList(needNextProjects, Project::getProjectCode);
Map<String, ProjectStatusChange> projectStatusChangeMap = MapUtil.newHashMap();
String stepName = null;
switch (flowType) {
// 已立项未采购 获取 立项时间
case APPROVED_PROJECT_NOT_PURCHASED:{
Map<String, ProjectStatusChange> approvedProjectNotPurchasedMap = projectStatusChangeService.listLastEventMap(projectCodes,
ProjectStateChangeEvent.DECLARED_RECORD_PASS);
if (CollUtil.isNotEmpty(approvedProjectNotPurchasedMap)){
projectStatusChangeMap.putAll(approvedProjectNotPurchasedMap);
stepName = TaskConstant.StepName.PURCHASE;
}
}
break;
// 已采购未改造完成 获取合同签订时间
case PURCHASED_UNMODIFIED:{
Map<String, ProjectStatusChange> purchasedUnmodifiedMap = projectStatusChangeService.listLastEventMap(projectCodes,
ProjectStateChangeEvent.SUBMIT_PURCHASE_CONTRACT_RECORD);
if (CollUtil.isNotEmpty(purchasedUnmodifiedMap)){
projectStatusChangeMap.putAll(purchasedUnmodifiedMap);
stepName = TaskConstant.StepName.ADAPT_MODIFY;
}
}
break;
// 已改造完成未终验 获取单位确认时间
case MODIFIED_NOT_FINAL_INSPECTION:{
Map<String, ProjectStatusChange> modifiedNotFinalInspectionMap = projectStatusChangeService.listLastEventMap(projectCodes,
ProjectStateChangeEvent.SUBMIT_PURCHASE_ORG_CONFIRM);
if (CollUtil.isNotEmpty(modifiedNotFinalInspectionMap)){
projectStatusChangeMap.putAll(modifiedNotFinalInspectionMap);
stepName = TaskConstant.StepName.FINAL;
}
}
break;
default:
log.error("Unexpected value: {}", flowType);
}
// 需要首页监测预警展示的项目
// 获取项目 滞后(历时)时间
HashMap<String, LocalDateTime> touchTimeMap = MapUtil.newHashMap();
String finalStepName = stepName;
List<Project> 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());

for (Project needToWaringProject : needToWaringProjects) {
// 目前没有通知
// 如果去预警通知人 1.超级管理员 2.单位管理员 如果都包含 都要发
List<String> batchEmployees = Lists.newArrayList();
if (StringUtils.isNotBlank(notice) && notice.contains(WarningNoticeTypeEnum.SUPER_ADMIN.getCode().toString())) {
// 获取超级管理员用户信息
List<UserInfo> superAdminUsers = userInfoHelper.getEmployeeCodesByRoleEnum(RoleEnum.SUPER_ADMIN);
List<String> superAdminEmployeeCodes = superAdminUsers.stream().map(UserInfo::getEmployeeCode).collect(Collectors.toList());
batchEmployees.addAll(superAdminEmployeeCodes);
}
if (StringUtils.isNotBlank(notice) && notice.contains(WarningNoticeTypeEnum.UNIT_ADMIN.getCode().toString())) {
// 获取单位管理员用户信息
List<UserInfo> unitAdminUsers = userInfoHelper.getEmployeeCodesByRoleEnum(RoleEnum.COMPANY_MANAGER);
// 过滤出当前项目所属单位的单位管理员
List<String> 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());
}

@Test
public void two(){
List<Project> projects = projectService.list(Wrappers.lambdaQuery(Project.class)
.eq(Project::getNewest, Boolean.TRUE));

if (CollUtil.isEmpty(projects)) {
return;
}

Set<String> projectSet = Sets.newHashSet();
Map<String, Project> projectMap = projects.stream().filter(p -> projectSet.add(p.getProjectCode()))
.collect(Collectors.toMap(Project::getProjectCode, p -> p));
List<ProjectEarlyWarning> warnings = projectEarlyWarningService.list();

// 删除 已经不存在的项目
List<ProjectEarlyWarning> toRemove = warnings.stream()
.filter(w -> !projectMap.containsKey(w.getProjectCode()))
.collect(Collectors.toList());
if (CollUtil.isNotEmpty(toRemove)) {
List<Long> removeIds = toRemove.stream().map(ProjectEarlyWarning::getId)
.collect(Collectors.toList());
projectEarlyWarningService.removeBatchByIds(removeIds);
}

// 去查询 各个报警 是否已经正常
List<ProjectEarlyWarning> trueWarnings = warnings.stream().filter(w -> Objects.nonNull(w.getNormal()) && !w.getNormal()).collect(Collectors.toList());
if (CollUtil.isEmpty(trueWarnings)) {
return;
}
checkNormal(trueWarnings);
}

private long getDurationTime(LocalDateTime touchTime, LocalDateTime now, ChronoUnit timeUnit) {
return timeUnit.between(touchTime, now);
}

// 3.去查询 各个报警 是否已经正常
private void checkNormal(List<ProjectEarlyWarning> trueWarnings) {
// 3.1 流程预警 如果正常了 要改会正常
List<ProjectEarlyWarning> processWarning = trueWarnings.stream().filter(w -> Objects.nonNull(w.getProcessWarning())
&& w.getProcessWarning())
.collect(Collectors.toList());
checkProcessWarning(processWarning);

// 3.2 填报预警 如果正常了 要改会正常
List<ProjectEarlyWarning> declaredWarning = trueWarnings.stream().filter(w ->
Objects.nonNull(w.getDeclaredWarning())
&& w.getDeclaredWarning())
.collect(Collectors.toList());
checkDeclaredWarning(declaredWarning);

// 3.3 滞后预警 如果正常了 要改会正常
List<ProjectEarlyWarning> delayWarning = trueWarnings.stream().filter(w ->
Objects.nonNull(w.getDelayWarning())
&& w.getDelayWarning())
.collect(Collectors.toList());
checkDelayWarning(delayWarning);
}

private void checkDelayWarning(List<ProjectEarlyWarning> delayWarning) {
if (CollUtil.isEmpty(delayWarning)) {
return;
}
for (ProjectEarlyWarning delay : delayWarning) {
String projectCode = delay.getProjectCode();
Project project = projectService.getProjectByCode(projectCode);
if (Objects.isNull(project)) {
continue;
}
WflowEarlyWarningRecords record = earlyWarningRecordsService.getOne(Wrappers.lambdaQuery(WflowEarlyWarningRecords.class)
.eq(WflowEarlyWarningRecords::getProjectCode, projectCode)
.eq(WflowEarlyWarningRecords::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode())
.orderByDesc(WflowEarlyWarningRecords::getWarningTime)
.last(BizConst.LIMIT_1));
if (Objects.isNull(record)) {
continue;
}
Integer biz = record.getBiz();
WarningFlowTypeEnum flowTypeEnum = WarningFlowTypeEnum.getByCode(biz);
if (Objects.isNull(flowTypeEnum)) {
continue;
}
ProjectStatus projectStatus = flowTypeEnum.getProjectStatus();
// 已经不是这个状态了 说明已经被提交了
if (!projectStatus.eq(project.getStatus())) {
checkCommited(delay, flowTypeEnum, projectCode);
// 其它几种 都没有 说明已经正常了
if (!delay.getProcessWarning() &&
!delay.getDeclaredWarning()) {
delay.setNormal(Boolean.TRUE);
delay.setStatus(ProjectEarlyWarningStatusEnum.NORMAL.name());
}
projectEarlyWarningService.updateById(delay);
}
}
}

private void checkDeclaredWarning(List<ProjectEarlyWarning> declaredWarnings) {
if (CollUtil.isEmpty(declaredWarnings)) {
return;
}
for (ProjectEarlyWarning declaredWarning : declaredWarnings) {
String projectCode = declaredWarning.getProjectCode();
Project project = projectService.getProjectByCode(projectCode);
if (Objects.isNull(project)) {
continue;
}
WflowEarlyWarningRecords record = earlyWarningRecordsService.getOne(Wrappers.lambdaQuery(WflowEarlyWarningRecords.class)
.eq(WflowEarlyWarningRecords::getProjectCode, projectCode)
.eq(WflowEarlyWarningRecords::getRuleType, WarningRuleTypeEnum.DECLARED_WARNING.getCode())
.orderByDesc(WflowEarlyWarningRecords::getWarningTime)
.last(BizConst.LIMIT_1));
if (Objects.isNull(record)) {
continue;
}
Integer biz = record.getBiz();
WarningFlowTypeEnum flowTypeEnum = WarningFlowTypeEnum.getByCode(biz);
if (Objects.isNull(flowTypeEnum)) {
continue;
}
ProjectStatus projectStatus = flowTypeEnum.getProjectStatus();
// 已经不是这个状态了 根据选择的节点判断是否完成了提交
if (!projectStatus.eq(project.getStatus())) {
checkCommited(declaredWarning, flowTypeEnum, projectCode);
// 其它几种 都没有 说明已经正常了
if (!declaredWarning.getProcessWarning() &&
!declaredWarning.getDelayWarning()) {
declaredWarning.setNormal(Boolean.TRUE);
declaredWarning.setStatus(ProjectEarlyWarningStatusEnum.NORMAL.name());
}
projectEarlyWarningService.updateById(declaredWarning);
}
}
}

private void checkCommited(ProjectEarlyWarning warning, WarningFlowTypeEnum flowTypeEnum, String projectCode) {
switch (flowTypeEnum){
// 已立项未采购 当用户采购&合同备案完成 说明进度正常
case APPROVED_PROJECT_NOT_PURCHASED: {
List<ProjectStateChangeEvent> events = Lists.newArrayList();
events.add(ProjectStateChangeEvent.SUBMIT_PURCHASE_CONTRACT_RECORD);
ProjectStatusChange projectStatusChange = projectStatusChangeService.getLastOne(projectCode, events);
// 说明进行了采购&合同信息备案
if (Objects.nonNull(projectStatusChange)) {
warning.setDeclaredWarning(Boolean.FALSE);
}
}
break;
// 已采购未改造完成 当用户适配改造完成已完成单位确认 说明进度正常
case MODIFIED_NOT_FINAL_INSPECTION:{
List<TenderStateChangeEvent> events = Lists.newArrayList();
events.add(TenderStateChangeEvent.SUBMIT_PURCHASE_ORG_CONFIRM);
PurchaseStatusChange purchaseStatusChange = purchaseStatusChangeService.getLastOne(projectCode, events);
// 说明进行了单位确认
if (Objects.nonNull(purchaseStatusChange)) {
warning.setDeclaredWarning(Boolean.FALSE);
}

}
break;
// 已改造完成未终验 当用户提交终验申请 说明进度正常
case PURCHASED_UNMODIFIED:{
List<ProjectStateChangeEvent> events = Lists.newArrayList();
events.add(ProjectStateChangeEvent.FINAL_ACCEPTANCE_APPLICATION);
ProjectStatusChange projectStatusChange = projectStatusChangeService.getLastOne(projectCode, events);
// 说明提交了终验申请
if (Objects.nonNull(projectStatusChange)) {
warning.setDeclaredWarning(Boolean.FALSE);
}
}
break;
}
}

/**
* 流程 查看 是否已经处理过
*
* @param processWarnings
*/
private void checkProcessWarning(List<ProjectEarlyWarning> processWarnings) {
if (CollUtil.isEmpty(processWarnings)) {
return;
}
for (ProjectEarlyWarning processWarning : processWarnings) {
String projectCode = processWarning.getProjectCode();
WflowEarlyWarningRecords record = earlyWarningRecordsService.getOne(Wrappers.lambdaQuery(WflowEarlyWarningRecords.class)
.eq(WflowEarlyWarningRecords::getProjectCode, projectCode)
.orderByDesc(WflowEarlyWarningRecords::getWarningTime)
.last(BizConst.LIMIT_1));
if (Objects.isNull(record)) {
continue;
}
String nodeId = record.getNodeId();
if (StringUtils.isBlank(nodeId)) {
continue;
}
List<Task> tasks = taskService.createTaskQuery()
.taskDefinitionKey(nodeId)
.list();
if (CollUtil.isEmpty(tasks)) {
//说明 已经审批通过了
processWarning.setProcessWarning(Boolean.FALSE);
//其它三种 都没有 说明已经正常了
if (!processWarning.getDeclaredWarning() &&
!processWarning.getDelayWarning()) {
processWarning.setNormal(Boolean.TRUE);
processWarning.setStatus(ProjectEarlyWarningStatusEnum.NORMAL.name());
}
projectEarlyWarningService.updateById(processWarning);
}
}

}

}

+ 46
- 18
hz-pm-api/src/test/resources/application-dev.yml View File

@@ -16,7 +16,7 @@ spring:
timeout: 5000
host: 47.98.125.47
port: 26379
database: 5
database: 7
password: Ndkj1234
jedis:
pool:
@@ -153,17 +153,6 @@ sa-token:
# 是否输出操作日志
is-log: false

yxt:
# wsdl-url: http://115.239.137.23:9501/ws/v1?wsdl
wsdl-url: classpath:/wsdl.xml
#账号
user-code: hzndkj
#密码
password: hzndkj@2021
#音信通开关
sms-enable: true
tel-enable: true

login:
phone-verify-code:
skip: true
@@ -176,26 +165,65 @@ sync-mh-user:
sync-mh-company:
open: false
mh:
zwdd-work-notice:
sso:
client-id: ningda-74a5e5da-3bc3-414a-b9e6-004b7d87e310
client-secret: ningda-df746ce4-0c79-4242-b3c7-90ff8630c9742c6727cd-3ae7-48ae-87ad-2b39188ebabd
sso:
zwdd-work-notice:
client-id: ningda-74a5e5da-3bc3-414a-b9e6-004b7d87e310
client-secret: ningda-df746ce4-0c79-4242-b3c7-90ff8630c9742c6727cd-3ae7-48ae-87ad-2b39188ebabd
api-host: https://hzszxc.hzswb.cn:8443/mh-gateway/auth-single
api-host: https://hzszxc.hzswb.cn:8443/test/mh-gateway/auth-single
expert-qr-code-url: https://jiema.wwei.cn/uploads/2023/12/28/658d7a3f15f06.jpg
file:
down-url: https://weixin.hzszxc.hzswb.cn:8443/test/mh-gateway/oss/oss/previewFileLogin
detail-url: https://weixin.hzszxc.hzswb.cn:8443/test/mh-gateway/oss/ossfile/getFileInfoList
upload-url: https://weixin.hzszxc.hzswb.cn:8443/test/mh-gateway/oss/oss/uploadFileSkipLogin
file-preview:
public-host: http://ztzz2.hzswb.cn/yl

auth-code:
secret-key: nqkmzqojg5j4eiypr3rb8s7nb4noa8b2
agent-login:
proxy:
secret-key: nqkwiqojg7g4eiypr3rb8s7nb4noa8b2
# 短信服务地址
sms-send:
host: http://10.54.38.13:8081/mh-gateway/auth-single
# 电话服务地址
sms-client:
host: http://10.54.38.13:8081/mh-gateway/auth-single
open: false

mobile-call:
host: http://183.158.240.86:18181/blue_esl_api
host: http://183.158.240.86:18181/blue_esl_api

# 提醒任务
reminder-task:
declared-record:
open: false
cron: 0 30 8 * * ?
hz-pm:
interfaceKey: hz_meeting_expert_info

web:
login:
url: http://hzpm.ningdatech.com
api:
url: http://hzpm.ningdatech.com/hzpm

expert-invite:
skip-send-call: true
skip-send-sms: true

mh-system-replace-sync:
open: false

thread-pool-util:
request:
core-pool-size: 2
max-pool-size: 4
queue-capacity: 100
keep-alive-seconds: 120
thread-name-prefix: request-executor-
scheduler:
core-pool-size: 2
thread-name-prefix: scheduler-executor-
early-warning-without-submit:
open: true

+ 2
- 0
hz-pm-api/src/test/resources/application-pre.yml View File

@@ -241,3 +241,5 @@ login:
phone-verify-code:
skip: true
url: http://60.188.225.145:8080/login
early-warning-without-submit:
open: true

+ 3
- 1
hz-pm-api/src/test/resources/application-prod.yml View File

@@ -247,4 +247,6 @@ mh:
sso:
client-id: ningda-74a5e5da-3bc3-414a-b9e6-004b7d87e310
client-secret: ningda-df746ce4-0c79-4242-b3c7-90ff8630c9742c6727cd-3ae7-48ae-87ad-2b39188ebabd
api-host: http://10.54.38.13:8081/mh-gateway/auth-single
api-host: http://10.54.38.13:8081/mh-gateway/auth-single
early-warning-without-submit:
open: true

Loading…
Cancel
Save