@@ -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; | |||
@@ -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) { | |||
@@ -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; | |||
} | |||
/** | |||
* 催办 | |||
* | |||
@@ -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); | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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); | |||
} | |||