@@ -50,4 +50,5 @@ public interface UserInfoHelper { | |||
List<UserFullInfoDTO> listUserFullInfoByUnitIdsAndRole(Collection<Long> unitIds, RoleEnum role); | |||
List<UserInfo> getEmployeeCodesByRoleEnum(RoleEnum roleEnum); | |||
} |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
@@ -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); | |||
} | |||
} |
@@ -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 = "终验"; | |||
} | |||
} |
@@ -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()); | |||
} | |||
@@ -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()); | |||
} | |||
} |
@@ -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; | |||
@@ -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; | |||
@@ -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(); | |||
@@ -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; | |||
} |
@@ -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") | |||
@@ -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); | |||
} |
@@ -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); | |||
} | |||
} |
@@ -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 | |||
@@ -42,5 +42,4 @@ public interface IUserInfoService extends IService<UserInfo> { | |||
.eq(UserInfo::getUsername, userName) | |||
.last(BizConst.LIMIT_1)); | |||
} | |||
} |
@@ -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; | |||
/** | |||
@@ -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); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} | |||
} |
@@ -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; | |||
} |
@@ -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 |
@@ -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 |
@@ -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 |
@@ -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(); | |||
@@ -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); | |||
} | |||
} | |||
} | |||
} |
@@ -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 |
@@ -241,3 +241,5 @@ login: | |||
phone-verify-code: | |||
skip: true | |||
url: http://60.188.225.145:8080/login | |||
early-warning-without-submit: | |||
open: true |
@@ -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 |