Browse Source

滞后预警任务修改

tags/24090601
CMM 2 weeks ago
parent
commit
981dabd6fd
6 changed files with 574 additions and 120 deletions
  1. +2
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/scheduler/task/EarlyWarningProjectTask.java
  2. +297
    -68
      hz-pm-api/src/main/java/com/hz/pm/api/scheduler/task/EarlyWarningWithoutSubmitTask.java
  3. +36
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/sys/manage/EarlyWarningManage.java
  4. +2
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/sys/service/IProjectEarlyWarningService.java
  5. +65
    -0
      hz-pm-api/src/main/java/com/hz/pm/api/sys/service/impl/ProjectEarlyWarningServiceImpl.java
  6. +172
    -52
      hz-pm-api/src/test/java/com/hz/pm/api/warning/DelayWarningTest.java

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

@@ -32,6 +32,7 @@ import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@@ -48,6 +49,7 @@ import java.util.stream.Collectors;
@Component
@Slf4j
@RequiredArgsConstructor
@ConditionalOnExpression("${early-warning-without-submit.open:true}")
public class EarlyWarningProjectTask {

private final IProjectService projectService;


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

@@ -6,7 +6,13 @@ import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.hz.pm.api.common.statemachine.event.TenderStateChangeEvent;
import com.hz.pm.api.projectlib.entity.PurchaseStatusChange;
import com.hz.pm.api.projectlib.service.IPurchaseStatusChangeService;
import com.hz.pm.api.sys.model.entity.ProjectEarlyWarning;
import com.hz.pm.api.sys.model.entity.WflowEarlyWarningRecords;
import com.hz.pm.api.sys.service.IEarlyWarningRecordsService;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
@@ -74,6 +80,8 @@ public class EarlyWarningWithoutSubmitTask {
private final IProjectStatusChangeService projectStatusChangeService;
private final EnvironmentUtil environmentUtil;
private final UserInfoHelper userInfoHelper;
private final IEarlyWarningRecordsService earlyWarningRecordsService;
private final IPurchaseStatusChangeService purchaseStatusChangeService;

private ChronoUnit getTimeUnit() {
if (environmentUtil.isDevEnv()) {
@@ -91,16 +99,60 @@ public class EarlyWarningWithoutSubmitTask {
log.info("=========== 滞后预警任务开始 ===========");
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// 1.查询 填报的 滞后预警规则 填报类型的 每个单位的 每个规则
Wrapper<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();
// 获取项目库所有建设单位不为空的项目
LambdaQueryWrapper<Project> queryWrapper = Wrappers.lambdaQuery(Project.class).isNotNull(Project::getBuildOrgCode);
List<Project> projects = projectService.list(queryWrapper);
// 根据项目code分组 获取最新的一条数据
Map<String, Project> projectMap = projects.stream().collect(Collectors.groupingBy(Project::getProjectCode, Collectors.collectingAndThen(
// 根据创建日期找到最新的记录
Collectors.maxBy(Comparator.comparing(Project::getCreateOn)),
// 如果没有记录则返回null
optional -> optional.orElse(null)
)));
List<Project> projectList = new ArrayList<>(projectMap.values());
List<ProjectEarlyWarning> projectEarlyWarnings = Lists.newArrayList();
List<WflowEarlyWarningRecords> earlyWarningRecords = Lists.newArrayList();
List<ProjectEarlyWarning> needRemoved = Lists.newArrayList();
// 查询当前预警表中 已存在的的滞后预警数据
Wrapper<ProjectEarlyWarning> warningQuery = Wrappers.lambdaQuery(ProjectEarlyWarning.class)
.eq(ProjectEarlyWarning::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode());
List<ProjectEarlyWarning> earlyWarnings = projectEarlyWarningService.list(warningQuery);
Map<String, ProjectEarlyWarning> projectEarlyWarningMap = CollUtils.listToMap(earlyWarnings, c -> c.getProjectCode() + StrPool.DASH + c.getStepName());
// 遍历项目 获取对应申报单位的滞后预警规则
for (Project project : projectList) {
String buildOrgCode = project.getBuildOrgCode();
String projectCode = project.getProjectCode();
Long mhUnitId = Long.valueOf(buildOrgCode);
List<Long> unitIdPaths = mhUnitCache.getUnitIdPaths(mhUnitId);
if (unitIdPaths.isEmpty()) {
log.error("该单位无法进行滞后预警:{}", mhUnitId);
continue;
}
List<String> unitIdPathsStr = CollUtils.convert(unitIdPaths, String::valueOf);
String orderSql = String.format(" order by field(mh_unit_id, %s) desc limit 1",
CollUtils.join(unitIdPaths, w -> "'" + w + "'", StrUtil.COMMA));
log.info("单位ID路径:{}", unitIdPathsStr);
// 从当前建设单位开始向上获取滞后预警规则
WflowEarlyWarning warning = earlyWarningService.getOne(Wrappers.lambdaQuery(WflowEarlyWarning.class)
.eq(WflowEarlyWarning::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode())
.eq(WflowEarlyWarning::getIsOpen, true)
.in(WflowEarlyWarning::getMhUnitId, unitIdPathsStr)
.last(orderSql));
if (Objects.isNull(warning)){
log.info("未找到对应单位:{} 的滞后预警规则", mhUnitId);
continue;
}
String rule = warning.getRule();
if (StringUtils.isNotBlank(rule)) {
JSONArray ruleArray = JSON.parseArray(rule);
// 对JSONArray 根据"biz"字段从小到大排序
ruleArray.sort((o1, o2) -> {
JSONObject o1Json = JSON.parseObject(JSON.toJSONString(o1));
JSONObject o2Json = JSON.parseObject(JSON.toJSONString(o2));
Integer o1Biz = o1Json.getInteger("biz");
Integer o2Biz = o2Json.getInteger("biz");
return o1Biz.compareTo(o2Biz);
});
if (CollUtil.isNotEmpty(ruleArray)) {
ruleArray.forEach(r -> {
JSONObject rJson = JSON.parseObject(JSON.toJSONString(r));
@@ -113,15 +165,16 @@ public class EarlyWarningWithoutSubmitTask {
return;
}
String path = flowType.getPath();
// 查询 所有这个单位 所配置滞后规则节点 未提交的项目
Wrapper<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;
List<String> projectCodes = Lists.newArrayList();
projectCodes.add(project.getProjectCode());
// 是否进行采购&合同备案
boolean isPurchase = false;
// 适配改造是否完成单位确认
boolean isModified = false;
// 终验申请是否提交
boolean isFinalInspection = false;
switch (flowType) {
// 已立项未采购 获取 立项时间
case APPROVED_PROJECT_NOT_PURCHASED:{
@@ -129,6 +182,13 @@ public class EarlyWarningWithoutSubmitTask {
if (CollUtil.isNotEmpty(projectCodes)) {
Map<String, ProjectStatusChange> approvedProjectNotPurchasedMap = projectStatusChangeService.listLastEventMap(projectCodes,
ProjectStateChangeEvent.DECLARED_RECORD_PASS);
List<ProjectStateChangeEvent> events = Lists.newArrayList();
events.add(ProjectStateChangeEvent.SUBMIT_PURCHASE_CONTRACT_RECORD);
ProjectStatusChange projectStatusChange = projectStatusChangeService.getLastOne(projectCode, events);
// 说明进行了采购&合同信息备案
if (Objects.nonNull(projectStatusChange)) {
isPurchase = true;
}
if (CollUtil.isNotEmpty(approvedProjectNotPurchasedMap)) {
projectStatusChangeMap.putAll(approvedProjectNotPurchasedMap);
}
@@ -144,6 +204,13 @@ public class EarlyWarningWithoutSubmitTask {
if (CollUtil.isNotEmpty(purchasedUnmodifiedMap)) {
projectStatusChangeMap.putAll(purchasedUnmodifiedMap);
}
List<TenderStateChangeEvent> events = Lists.newArrayList();
events.add(TenderStateChangeEvent.SUBMIT_PURCHASE_ORG_CONFIRM);
PurchaseStatusChange purchaseStatusChange = purchaseStatusChangeService.getLastOne(projectCode, events);
// 说明进行了单位确认
if (Objects.nonNull(purchaseStatusChange)) {
isModified = true;
}
}
}
break;
@@ -157,76 +224,238 @@ public class EarlyWarningWithoutSubmitTask {
projectStatusChangeMap.putAll(modifiedNotFinalInspectionMap);
}
}
List<ProjectStateChangeEvent> events = Lists.newArrayList();
events.add(ProjectStateChangeEvent.FINAL_ACCEPTANCE_APPLICATION);
ProjectStatusChange projectStatusChange = projectStatusChangeService.getLastOne(projectCode, events);
// 说明提交了终验申请
if (Objects.nonNull(projectStatusChange)) {
isFinalInspection = true;
}
}
break;
default:
log.error("Unexpected value: {}", flowType);
}
// 查询当前预警表中 已存在的的滞后预警数据
Wrapper<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);
ProjectStatusChange change = projectStatusChangeMap.get(projectCode);
LocalDateTime touchTime = change == null ? null : change.getCreateOn();
// 是否进行预警
boolean isTouch = isTouch(flowType, isPurchase, isModified, isFinalInspection);
if (touchTime != null) {
touchTimeMap.put(projectCode + StrPool.DASH + biz, touchTime);
long duration = getDurationTime(touchTime,LocalDateTime.now(),getTimeUnit());
// 如果对应节点超期 且未提交至下一步
if (duration > delayTime && isTouch) {
List<ProjectEarlyWarning> projectEarlyWarningList = Lists.newArrayList();
List<WflowEarlyWarningRecords> earlyWarningRecordsList = Lists.newArrayList();
// 项目 滞后预警
projectEarlyWarningList = projectEarlyWarningService.earlyWarning(project, WarningRuleTypeEnum.DELAY_WARNING.getCode(), com.wflow.enums.WarningNoticeTypeEnum.DELAY.getCode(), finalStepName, projectEarlyWarningList);
projectEarlyWarnings.addAll(projectEarlyWarningList);
// 目前没有通知
// 如果去预警通知人 1.超级管理员 2.单位管理员 如果都包含 都要发
List<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(), project.getBuildOrgCode()))
.map(UserInfo::getEmployeeCode).collect(Collectors.toList());
batchEmployees.addAll(unitAdminEmployeeCodes);
}
// 保存到预警记录中
earlyWarningRecordsList = earlyWarningManage.getEarlyWarningDelayRecords(warning.getNoticeMethod(), biz, project,
WarningRuleTypeEnum.DELAY_WARNING.getCode(), ProjectEarlyWarningStatusEnum.DELAY_TIME.getCode(),
path, touchTimeMap, earlyWarningRecordsList);
earlyWarningRecords.addAll(earlyWarningRecordsList);
}else {
// 判断是否已经存在对应节点预警 如果有 从预警信息表中移除
if (projectEarlyWarningMap.containsKey(project.getProjectCode() + StrPool.DASH + finalStepName)) {
ProjectEarlyWarning projectEarlyWarning = projectEarlyWarningMap.get(projectCode + StrPool.DASH + finalStepName);
needRemoved.add(projectEarlyWarning);
}
}
// 保存到预警记录中
earlyWarningManage.doEarlyWarningDelay(warning.getNoticeMethod(), biz, needToWaringProject,
WarningRuleTypeEnum.DELAY_WARNING.getCode(), ProjectEarlyWarningStatusEnum.DELAY_TIME.getCode(),
path, touchTimeMap);
}
});
}
}
}

// 每个规则按通知节点顺序 更新保存一次
if (CollUtil.isNotEmpty(needRemoved)){
projectEarlyWarningService.removeBatchByIds(needRemoved);
}
if (CollUtil.isNotEmpty(projectEarlyWarnings)){
log.info("需要滞后预警通知的项目数:{}", projectEarlyWarnings.size());
projectEarlyWarningService.saveOrUpdateBatch(projectEarlyWarnings);
}
if (CollUtil.isNotEmpty(earlyWarningRecords)){
log.info("需要滞后预警通知记录数:{}", earlyWarningRecords.size());
earlyWarningRecordsService.saveOrUpdateBatch(earlyWarningRecords);
}
stopWatch.stop();
log.info("=========== 滞后预警任务结束 耗时{}s", stopWatch.getTotalTimeSeconds());

//log.info("=========== 滞后预警任务开始 ===========");
//StopWatch stopWatch = new StopWatch();
//stopWatch.start();
//// 1.查询 填报的 滞后预警规则 填报类型的 每个单位的 每个规则
//Wrapper<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:{
// stepName = TaskConstant.StepName.PURCHASE;
// if (CollUtil.isNotEmpty(projectCodes)) {
// Map<String, ProjectStatusChange> approvedProjectNotPurchasedMap = projectStatusChangeService.listLastEventMap(projectCodes,
// ProjectStateChangeEvent.DECLARED_RECORD_PASS);
// if (CollUtil.isNotEmpty(approvedProjectNotPurchasedMap)) {
// projectStatusChangeMap.putAll(approvedProjectNotPurchasedMap);
// }
// }
// }
// break;
// // 已采购未改造完成 获取合同签订时间
// case PURCHASED_UNMODIFIED:{
// stepName = TaskConstant.StepName.ADAPT_MODIFY;
// if (CollUtil.isNotEmpty(projectCodes)) {
// Map<String, ProjectStatusChange> purchasedUnmodifiedMap = projectStatusChangeService.listLastEventMap(projectCodes,
// ProjectStateChangeEvent.SUBMIT_PURCHASE_CONTRACT_RECORD);
// if (CollUtil.isNotEmpty(purchasedUnmodifiedMap)) {
// projectStatusChangeMap.putAll(purchasedUnmodifiedMap);
// }
// }
// }
// break;
// // 已改造完成未终验 获取单位确认时间
// case MODIFIED_NOT_FINAL_INSPECTION:{
// stepName = TaskConstant.StepName.FINAL;
// if (CollUtil.isNotEmpty(projectCodes)) {
// Map<String, ProjectStatusChange> modifiedNotFinalInspectionMap = projectStatusChangeService.listLastEventMap(projectCodes,
// ProjectStateChangeEvent.SUBMIT_PURCHASE_ORG_CONFIRM);
// if (CollUtil.isNotEmpty(modifiedNotFinalInspectionMap)) {
// projectStatusChangeMap.putAll(modifiedNotFinalInspectionMap);
// }
// }
// }
// 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 boolean isTouch(WarningFlowTypeEnum flowType, Boolean isPurchase, Boolean isModified, Boolean isFinalInspection) {
switch (flowType) {
case APPROVED_PROJECT_NOT_PURCHASED:
return !isPurchase;
case MODIFIED_NOT_FINAL_INSPECTION:
return !isModified && !isFinalInspection;
case PURCHASED_UNMODIFIED:
return isPurchase && !isModified;
default:
return false;
}
}

private long getDurationTime(LocalDateTime touchTime, LocalDateTime now, ChronoUnit timeUnit) {


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

@@ -25,6 +25,7 @@ import org.springframework.transaction.annotation.Transactional;

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

/**
@@ -169,6 +170,41 @@ public class EarlyWarningManage {
earlyWarningRecordsService.saveOrUpdate(records);
}

public List<WflowEarlyWarningRecords> getEarlyWarningDelayRecords(String noticeMethod, Integer biz, Project project,
Integer ruleType, Integer noticeType, String path,
HashMap<String, LocalDateTime> touchTimeMap, List<WflowEarlyWarningRecords> earlyWarningRecords) {
// 1.存入 预警记录
WflowEarlyWarningRecords records = new WflowEarlyWarningRecords();
String projectCode = project.getProjectCode();
WflowEarlyWarningRecords old = earlyWarningRecordsService.getOne(Wrappers.lambdaQuery(WflowEarlyWarningRecords.class)
.eq(WflowEarlyWarningRecords::getProjectCode, projectCode)
.eq(WflowEarlyWarningRecords::getBiz, biz)
.last(BizConst.LIMIT_1));
if (Objects.nonNull(old)){
records.setId(old.getId());
}else {
records.setCreateOn(LocalDateTime.now());
}
LocalDateTime startTime = touchTimeMap.get(projectCode + StrPool.DASH + biz);
records.setRuleType(ruleType);
records.setAreaCode(project.getAreaCode());
records.setBuildOrgCode(project.getBuildOrgCode());
records.setBuildOrgName(project.getBuildOrgName());
records.setWarningTime(LocalDateTime.now());
records.setInstStart(startTime);
records.setInstType(biz);
records.setNoticeMethod(noticeMethod);
records.setProjectName(project.getProjectName());
records.setProjectId(project.getId());
records.setProjectCode(project.getProjectCode());
records.setProjectStatus(project.getStatus());
records.setNoticeType(noticeType);
records.setPath(path);
records.setBiz(biz);
earlyWarningRecords.add(records);
return earlyWarningRecords;
}

/**
* 催办
*


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

@@ -18,4 +18,6 @@ public interface IProjectEarlyWarningService extends IService<ProjectEarlyWarnin
Boolean earlyWarning(String projectCode, Integer code, List<Integer> noticeTypes);

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

List<ProjectEarlyWarning> earlyWarning(Project project, Integer ruleType, Integer noticeType, String stepName,List<ProjectEarlyWarning> projectEarlyWarningList);
}

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

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

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

@@ -68,6 +69,11 @@ public class ProjectEarlyWarningServiceImpl extends ServiceImpl<ProjectEarlyWarn
return doEarlyWarning(project, ruleType, noticeType, stepName);
}

@Override
public List<ProjectEarlyWarning> earlyWarning(Project project, Integer ruleType, Integer noticeType, String stepName, List<ProjectEarlyWarning> projectEarlyWarningList) {
return doEarlyWarning(project, ruleType, noticeType, stepName, projectEarlyWarningList);
}

private Boolean doEarlyWarning(Project project, Integer ruleType, Integer noticeType, String stepName) {
if(Objects.isNull(project) || Objects.isNull(ruleType)){
return Boolean.FALSE;
@@ -125,4 +131,63 @@ public class ProjectEarlyWarningServiceImpl extends ServiceImpl<ProjectEarlyWarn
warning.setStepName(stepName);
return saveOrUpdate(warning);
}

private List<ProjectEarlyWarning> doEarlyWarning(Project project, Integer ruleType, Integer noticeType, String stepName, List<ProjectEarlyWarning> projectEarlyWarningList) {
if(Objects.isNull(project) || Objects.isNull(ruleType)){
return Collections.emptyList();
}
String projectCode = project.getProjectCode();
ProjectEarlyWarning old = getOne(Wrappers.lambdaQuery(ProjectEarlyWarning.class)
.eq(ProjectEarlyWarning::getProjectCode, projectCode)
.last(BizConst.LIMIT_1));
ProjectEarlyWarning warning = new ProjectEarlyWarning();
if(Objects.nonNull(old)){
warning.setId(old.getId());
}else{
warning.setBuildOrgCode(project.getBuildOrgCode());
warning.setAreaCode(project.getAreaCode());
warning.setCreateOn(LocalDateTime.now());
warning.setProjectCode(projectCode);
}

switch (WarningRuleTypeEnum.checkByCode(ruleType)){
case DELAY_WARNING:
warning.setDelayWarning(Boolean.TRUE);
break;
case DECLARED_WARNING:
warning.setDeclaredWarning(Boolean.TRUE);
break;
case PROCESS_WARNING:
warning.setProcessWarning(Boolean.TRUE);
break;
default:
return Collections.emptyList();
}

warning.setRuleType(ruleType);
if(Objects.isNull(noticeType)){
warning.setStatus(ProjectEarlyWarningStatusEnum.OVER_TIME.name());
}else{
switch (WarningNoticeTypeEnum.match(noticeType)){
case OVER:
warning.setStatus(ProjectEarlyWarningStatusEnum.OVER_TIME.name());
break;
case ADVENT:
warning.setStatus(ProjectEarlyWarningStatusEnum.ADVENT_TIME.name());
break;
case DELAY:
warning.setStatus(ProjectEarlyWarningStatusEnum.DELAY_TIME.name());
break;
default:
warning.setStatus(ProjectEarlyWarningStatusEnum.OVER_TIME.name());
break;
}
}

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

+ 172
- 52
hz-pm-api/src/test/java/com/hz/pm/api/warning/DelayWarningTest.java View File

@@ -5,12 +5,15 @@ import javax.annotation.Resource;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.hz.pm.api.common.enumeration.ProjectProcessType;
import com.hz.pm.api.common.helper.UserInfoHelper;
import com.hz.pm.api.common.model.constant.BizConst;
import com.hz.pm.api.common.statemachine.event.ProjectStateChangeEvent;
@@ -39,11 +42,14 @@ import com.hz.pm.api.user.service.IUserInfoService;
import com.ningdatech.basic.util.CollUtils;
import com.ningdatech.basic.util.StrPool;
import com.wflow.bean.entity.WflowEarlyWarning;
import com.wflow.bean.entity.WflowModels;
import com.wflow.enums.WarningRuleTypeEnum;
import com.wflow.service.IEarlyWarningService;
import com.wflow.workflow.service.ProcessModelService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.junit.Test;
@@ -89,6 +95,10 @@ public class DelayWarningTest extends AppTests {
private TaskService taskService;
@Autowired
private IPurchaseStatusChangeService purchaseStatusChangeService;
@Autowired
private MhUnitCache mhUnitCache;
@Autowired
private ProcessModelService processModelService;

private ChronoUnit getTimeUnit() {
if (environmentUtil.isDevEnv()) {
@@ -100,20 +110,63 @@ public class DelayWarningTest extends AppTests {

@Test
public void one(){

log.info("=========== 滞后预警任务开始 ===========");
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// 1.查询 填报的 滞后预警规则 填报类型的 每个单位的 每个规则
Wrapper<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();
// 获取项目库所有建设单位不为空的项目
LambdaQueryWrapper<Project> queryWrapper = Wrappers.lambdaQuery(Project.class).isNotNull(Project::getBuildOrgCode);
List<Project> projects = projectService.list(queryWrapper);
// 根据项目code分组 获取最新的一条数据
Map<String, Project> projectMap = projects.stream().collect(Collectors.groupingBy(Project::getProjectCode, Collectors.collectingAndThen(
// 根据创建日期找到最新的记录
Collectors.maxBy(Comparator.comparing(Project::getCreateOn)),
// 如果没有记录则返回null
optional -> optional.orElse(null)
)));
List<Project> projectList = new ArrayList<>(projectMap.values());
List<ProjectEarlyWarning> projectEarlyWarnings = Lists.newArrayList();
List<WflowEarlyWarningRecords> earlyWarningRecords = Lists.newArrayList();
List<ProjectEarlyWarning> needRemoved = Lists.newArrayList();
// 查询当前预警表中 已存在的的滞后预警数据
Wrapper<ProjectEarlyWarning> warningQuery = Wrappers.lambdaQuery(ProjectEarlyWarning.class)
.eq(ProjectEarlyWarning::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode());
List<ProjectEarlyWarning> earlyWarnings = projectEarlyWarningService.list(warningQuery);
Map<String, ProjectEarlyWarning> projectEarlyWarningMap = CollUtils.listToMap(earlyWarnings, c -> c.getProjectCode() + StrPool.DASH + c.getStepName());
// 遍历项目 获取对应申报单位的滞后预警规则
for (Project project : projectList) {
String buildOrgCode = project.getBuildOrgCode();
String projectCode = project.getProjectCode();
Long mhUnitId = Long.valueOf(buildOrgCode);
List<Long> unitIdPaths = mhUnitCache.getUnitIdPaths(mhUnitId);
if (unitIdPaths.isEmpty()) {
log.error("该单位无法进行滞后预警:{}", mhUnitId);
continue;
}
List<String> unitIdPathsStr = CollUtils.convert(unitIdPaths, String::valueOf);
String orderSql = String.format(" order by field(mh_unit_id, %s) desc limit 1",
CollUtils.join(unitIdPaths, w -> "'" + w + "'", StrUtil.COMMA));
log.info("单位ID路径:{}", unitIdPathsStr);
// 从当前建设单位开始向上获取滞后预警规则
WflowEarlyWarning warning = earlyWarningService.getOne(Wrappers.lambdaQuery(WflowEarlyWarning.class)
.eq(WflowEarlyWarning::getRuleType, WarningRuleTypeEnum.DELAY_WARNING.getCode())
.eq(WflowEarlyWarning::getIsOpen, true)
.in(WflowEarlyWarning::getMhUnitId, unitIdPathsStr)
.last(orderSql));
if (Objects.isNull(warning)){
log.info("未找到对应单位:{} 的滞后预警规则", mhUnitId);
continue;
}
String rule = warning.getRule();
if (StringUtils.isNotBlank(rule)) {
JSONArray ruleArray = JSON.parseArray(rule);
// 对JSONArray 根据"biz"字段从小到大排序
ruleArray.sort((o1, o2) -> {
JSONObject o1Json = JSON.parseObject(JSON.toJSONString(o1));
JSONObject o2Json = JSON.parseObject(JSON.toJSONString(o2));
Integer o1Biz = o1Json.getInteger("biz");
Integer o2Biz = o2Json.getInteger("biz");
return o1Biz.compareTo(o2Biz);
});
if (CollUtil.isNotEmpty(ruleArray)) {
ruleArray.forEach(r -> {
JSONObject rJson = JSON.parseObject(JSON.toJSONString(r));
@@ -126,15 +179,16 @@ public class DelayWarningTest extends AppTests {
return;
}
String path = flowType.getPath();
// 查询 所有这个单位 所配置滞后规则节点 未提交的项目
Wrapper<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;
List<String> projectCodes = Lists.newArrayList();
projectCodes.add(project.getProjectCode());
// 是否进行采购&合同备案
boolean isPurchase = false;
// 适配改造是否完成单位确认
boolean isModified = false;
// 终验申请是否提交
boolean isFinalInspection = false;
switch (flowType) {
// 已立项未采购 获取 立项时间
case APPROVED_PROJECT_NOT_PURCHASED:{
@@ -142,6 +196,13 @@ public class DelayWarningTest extends AppTests {
if (CollUtil.isNotEmpty(projectCodes)) {
Map<String, ProjectStatusChange> approvedProjectNotPurchasedMap = projectStatusChangeService.listLastEventMap(projectCodes,
ProjectStateChangeEvent.DECLARED_RECORD_PASS);
List<ProjectStateChangeEvent> events = Lists.newArrayList();
events.add(ProjectStateChangeEvent.SUBMIT_PURCHASE_CONTRACT_RECORD);
ProjectStatusChange projectStatusChange = projectStatusChangeService.getLastOne(projectCode, events);
// 说明进行了采购&合同信息备案
if (Objects.nonNull(projectStatusChange)) {
isPurchase = true;
}
if (CollUtil.isNotEmpty(approvedProjectNotPurchasedMap)) {
projectStatusChangeMap.putAll(approvedProjectNotPurchasedMap);
}
@@ -157,6 +218,13 @@ public class DelayWarningTest extends AppTests {
if (CollUtil.isNotEmpty(purchasedUnmodifiedMap)) {
projectStatusChangeMap.putAll(purchasedUnmodifiedMap);
}
List<TenderStateChangeEvent> events = Lists.newArrayList();
events.add(TenderStateChangeEvent.SUBMIT_PURCHASE_ORG_CONFIRM);
PurchaseStatusChange purchaseStatusChange = purchaseStatusChangeService.getLastOne(projectCode, events);
// 说明进行了单位确认
if (Objects.nonNull(purchaseStatusChange)) {
isModified = true;
}
}
}
break;
@@ -170,6 +238,13 @@ public class DelayWarningTest extends AppTests {
projectStatusChangeMap.putAll(modifiedNotFinalInspectionMap);
}
}
List<ProjectStateChangeEvent> events = Lists.newArrayList();
events.add(ProjectStateChangeEvent.FINAL_ACCEPTANCE_APPLICATION);
ProjectStatusChange projectStatusChange = projectStatusChangeService.getLastOne(projectCode, events);
// 说明提交了终验申请
if (Objects.nonNull(projectStatusChange)) {
isFinalInspection = true;
}
}
break;
default:
@@ -179,54 +254,84 @@ public class DelayWarningTest extends AppTests {
// 获取项目 滞后(历时)时间
HashMap<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());
ProjectStatusChange change = projectStatusChangeMap.get(projectCode);
LocalDateTime touchTime = change == null ? null : change.getCreateOn();
// 是否进行预警
boolean isTouch = isTouch(flowType, isPurchase, isModified, isFinalInspection);
if (touchTime != null) {
touchTimeMap.put(projectCode + StrPool.DASH + biz, touchTime);
long duration = getDurationTime(touchTime,LocalDateTime.now(),getTimeUnit());
// 如果对应节点超期 且未提交至下一步
if (duration > delayTime && isTouch) {
List<ProjectEarlyWarning> projectEarlyWarningList = Lists.newArrayList();
List<WflowEarlyWarningRecords> earlyWarningRecordsList = Lists.newArrayList();
// 项目 滞后预警
projectEarlyWarningList = projectEarlyWarningService.earlyWarning(project, WarningRuleTypeEnum.DELAY_WARNING.getCode(), com.wflow.enums.WarningNoticeTypeEnum.DELAY.getCode(), finalStepName, projectEarlyWarningList);
projectEarlyWarnings.addAll(projectEarlyWarningList);

for (Project needToWaringProject : needToWaringProjects) {
// 目前没有通知
// 如果去预警通知人 1.超级管理员 2.单位管理员 如果都包含 都要发
List<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);
// 目前没有通知
// 如果去预警通知人 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(), project.getBuildOrgCode()))
.map(UserInfo::getEmployeeCode).collect(Collectors.toList());
batchEmployees.addAll(unitAdminEmployeeCodes);
}
// 保存到预警记录中
earlyWarningRecordsList = earlyWarningManage.getEarlyWarningDelayRecords(warning.getNoticeMethod(), biz, project,
WarningRuleTypeEnum.DELAY_WARNING.getCode(), ProjectEarlyWarningStatusEnum.DELAY_TIME.getCode(),
path, touchTimeMap, earlyWarningRecordsList);
earlyWarningRecords.addAll(earlyWarningRecordsList);
}else {
// 判断是否已经存在对应节点预警 如果有 从预警信息表中移除
if (projectEarlyWarningMap.containsKey(project.getProjectCode() + StrPool.DASH + finalStepName)) {
ProjectEarlyWarning projectEarlyWarning = projectEarlyWarningMap.get(projectCode + StrPool.DASH + finalStepName);
needRemoved.add(projectEarlyWarning);
}
}
// 保存到预警记录中
earlyWarningManage.doEarlyWarningDelay(warning.getNoticeMethod(), biz, needToWaringProject,
WarningRuleTypeEnum.DELAY_WARNING.getCode(), ProjectEarlyWarningStatusEnum.DELAY_TIME.getCode(),
path, touchTimeMap);
}
});
}
}
}

// 每个规则按通知节点顺序 更新保存一次
if (CollUtil.isNotEmpty(needRemoved)){
projectEarlyWarningService.removeBatchByIds(needRemoved);
}
if (CollUtil.isNotEmpty(projectEarlyWarnings)){
log.info("需要滞后预警通知的项目数:{}", projectEarlyWarnings.size());
projectEarlyWarningService.saveOrUpdateBatch(projectEarlyWarnings);
}
if (CollUtil.isNotEmpty(earlyWarningRecords)){
log.info("需要滞后预警通知记录数:{}", earlyWarningRecords.size());
earlyWarningRecordsService.saveOrUpdateBatch(earlyWarningRecords);
}
stopWatch.stop();
log.info("=========== 滞后预警任务结束 耗时{}s", stopWatch.getTotalTimeSeconds());
}

private boolean isTouch(WarningFlowTypeEnum flowType, Boolean isPurchase, Boolean isModified, Boolean isFinalInspection) {
switch (flowType) {
case APPROVED_PROJECT_NOT_PURCHASED:
return !isPurchase;
case MODIFIED_NOT_FINAL_INSPECTION:
return !isModified && !isFinalInspection;
case PURCHASED_UNMODIFIED:
return isPurchase && !isModified;
default:
return false;
}
}

@Test
public void two(){
log.info("=========== 预警项目状态校验任务开始 ===========");
@@ -264,6 +369,21 @@ public class DelayWarningTest extends AppTests {
log.info("=========== 预警项目状态校验任务结束 耗时{}s", stopWatch.getTotalTimeSeconds());
}

@Test
public void three(){
List<Long> unitIdPaths = mhUnitCache.getUnitIdPaths(32L);
System.out.println(unitIdPaths);
List<String> unitIdPathsStr = CollUtils.convert(unitIdPaths, String::valueOf);
String orderSql = String.format(" order by field(region_code, %s) desc limit 1",
CollUtils.join(unitIdPaths, w -> "'" + w + "'", StrUtil.COMMA));
System.out.println("单位ID路径:" + unitIdPathsStr);
WflowModels one = processModelService.getOne(Wrappers.lambdaQuery(WflowModels.class)
.eq(WflowModels::getProcessType, ProjectProcessType.PROJECT_RECORD_APPROVAL_PROCESS.getCode())
.in(WflowModels::getRegionCode, unitIdPathsStr)
.last(orderSql));
System.out.println(one);
}

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


Loading…
Cancel
Save