From 37af04bc7deff7398a2314bdd4cf2ac93fbb9779 Mon Sep 17 00:00:00 2001 From: lidongyang <506508008@qq.com> Date: Wed, 4 Mar 2026 12:45:32 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E6=A0=B9=E6=8D=AE=E5=86=9B=E4=BB=A4?= =?UTF-8?q?=E7=8A=B6=E6=97=B6=E9=97=B4=E5=88=A4=E6=96=AD=E4=BB=BB=E5=8A=A1?= =?UTF-8?q?=E9=80=BE=E6=9C=9F=E7=9B=B8=E5=85=B3=E7=9A=84=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/enums/MessageTemplateEnum.java | 3 +- .../common/service/TaskProgressService.java | 35 ++ .../CommitmentDeadlineStatusSchedule.java | 24 - ...mitmentDeadlineStatusScheduleExecutor.java | 492 ++++++++++++------ .../impl/LyricInternalServiceImpl.java | 2 +- .../project/service/impl/NodeServiceImpl.java | 2 +- .../impl/SimulationTaskServiceImpl.java | 2 +- .../project/service/impl/TaskServiceImpl.java | 2 +- 8 files changed, 369 insertions(+), 193 deletions(-) create mode 100644 common/src/main/java/com/sdm/common/service/TaskProgressService.java delete mode 100644 project/src/main/java/com/sdm/project/schedule/lyric/CommitmentDeadlineStatusSchedule.java diff --git a/common/src/main/java/com/sdm/common/entity/enums/MessageTemplateEnum.java b/common/src/main/java/com/sdm/common/entity/enums/MessageTemplateEnum.java index 06deb4e0..541c23e0 100644 --- a/common/src/main/java/com/sdm/common/entity/enums/MessageTemplateEnum.java +++ b/common/src/main/java/com/sdm/common/entity/enums/MessageTemplateEnum.java @@ -10,7 +10,8 @@ public enum MessageTemplateEnum { DATA_ALERT_MANAGER("数据通知", "%s的数据存储空间已达阈值"), APPROVE_ALERT("审批通知", "收到一条%s消息"), HPC_START("作业通知", "HPC任务作业:%s,已发起%s"), - HPC_END("作业通知", "HPC任务作业:%s,已结束,执行结果:%s") + HPC_END("作业通知", "HPC任务作业:%s,已结束,执行结果:%s"), + TASK_OVERDUE("任务逾期通知", "任务:%s,已逾期") ; private final String title; diff --git a/common/src/main/java/com/sdm/common/service/TaskProgressService.java b/common/src/main/java/com/sdm/common/service/TaskProgressService.java new file mode 100644 index 00000000..1765a23f --- /dev/null +++ b/common/src/main/java/com/sdm/common/service/TaskProgressService.java @@ -0,0 +1,35 @@ +package com.sdm.common.service; + +import com.sdm.common.common.SdmResponse; +import com.sdm.common.entity.bo.DataDictionary; +import com.sdm.common.entity.constants.TagConstant; +import com.sdm.common.feign.impl.system.SysConfigFeignClientImpl; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import static java.util.Collections.emptyMap; + +@Service +@Slf4j +public class TaskProgressService { + + @Autowired + private SysConfigFeignClientImpl sysConfigFeignClient; + + private static final String TASK_PROGRESS_STATUS = "TASK_PROGRESS_STATUS"; + + public Map getMapName() { + SdmResponse> taskProgressStatusList = sysConfigFeignClient.getDictionaryData(TASK_PROGRESS_STATUS); + if (!taskProgressStatusList.isSuccess() || ObjectUtils.isEmpty(taskProgressStatusList.getData())) { + log.error("字典信息查询失败"); + return emptyMap(); + } + return taskProgressStatusList.getData().stream().collect(Collectors.toMap(DataDictionary::getDictName, DataDictionary::getDictValue)); + } +} diff --git a/project/src/main/java/com/sdm/project/schedule/lyric/CommitmentDeadlineStatusSchedule.java b/project/src/main/java/com/sdm/project/schedule/lyric/CommitmentDeadlineStatusSchedule.java deleted file mode 100644 index 69dacbae..00000000 --- a/project/src/main/java/com/sdm/project/schedule/lyric/CommitmentDeadlineStatusSchedule.java +++ /dev/null @@ -1,24 +0,0 @@ -//package com.sdm.project.schedule.lyric; -// -//import lombok.extern.slf4j.Slf4j; -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.scheduling.annotation.Scheduled; -//import org.springframework.stereotype.Component; -// -//@Component -//@Slf4j -//public class CommitmentDeadlineStatusSchedule { -// -// @Autowired -// private CommitmentDeadlineStatusScheduleExecutor commitmentDeadlineStatusScheduleExecutor; -// -// // fixedDelayString 读取配置,值为【毫秒】,所以拼接000 -// @Scheduled(fixedDelayString = "${commitmentDeadlineStatusTask.schedule.interval:1800}000") -// public void doCommitmentDeadlineStatusTask() { -// try { -// commitmentDeadlineStatusScheduleExecutor.run(); -// } catch (Exception e) { -// log.error("【承诺截止状态更新任务】执行异常,原因:{}", e.getMessage(), e); -// } -// } -//} \ No newline at end of file diff --git a/project/src/main/java/com/sdm/project/schedule/lyric/CommitmentDeadlineStatusScheduleExecutor.java b/project/src/main/java/com/sdm/project/schedule/lyric/CommitmentDeadlineStatusScheduleExecutor.java index 5b63350c..0c2ef0ef 100644 --- a/project/src/main/java/com/sdm/project/schedule/lyric/CommitmentDeadlineStatusScheduleExecutor.java +++ b/project/src/main/java/com/sdm/project/schedule/lyric/CommitmentDeadlineStatusScheduleExecutor.java @@ -1,166 +1,330 @@ -//package com.sdm.project.schedule.lyric; -// -//import com.sdm.common.entity.enums.NodeTypeEnum; -//import com.sdm.project.common.TaskExeStatusEnum; -//import com.sdm.project.model.entity.SimulationNode; -//import com.sdm.project.model.entity.SimulationTask; -//import com.sdm.project.service.INodeService; -//import com.sdm.project.service.ISimulationTaskService; -//import com.xxl.job.core.handler.annotation.XxlJob; -//import lombok.extern.slf4j.Slf4j; -//import org.apache.commons.collections4.CollectionUtils; -//import org.apache.commons.lang3.StringUtils; -//import org.springframework.beans.factory.annotation.Value; -//import org.springframework.stereotype.Component; -//import org.springframework.stereotype.Service; -// -//import javax.annotation.Resource; -//import java.time.LocalDateTime; -//import java.time.format.DateTimeFormatter; -//import java.time.temporal.ChronoUnit; -//import java.util.*; -//import java.util.stream.Collectors; -// -//import static com.sdm.project.service.impl.NodeServiceImpl.SYNC_PROJECT_SOURCE; -// -//@Slf4j -//@Component -//public class CommitmentDeadlineStatusScheduleExecutor{ -// -// // 时间格式化器:全局常量,线程安全,可复用(yyyy-MM-dd HH:mm:ss 固定格式) -// private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); -// -// @Value("${commitmentDeadlineStatusTask.schedule.calculationInterval:5}") -// private int calculationInterval; -// -// @Resource -// private INodeService nodeService; -// -// @Resource -// private ISimulationTaskService taskService; -// -// @XxlJob("commitmentDeadlineStatusHandler") -// public void commitmentDeadlineStatusHandler() { -// log.info("定时任务执行"); -// try { -// // 1. 获取所有节点(工位) -// List nodeList = nodeService.lambdaQuery().eq(SimulationNode::getNodeType, NodeTypeEnum.WORKSPACE) -// .eq(SimulationNode::getProjectSource, SYNC_PROJECT_SOURCE).isNotNull(SimulationNode::getCommitmentDeadline) -// .list(); -// Map nodeMap = new HashMap<>(); -// if (CollectionUtils.isNotEmpty(nodeList)) { +package com.sdm.project.schedule.lyric; + +import com.alibaba.fastjson2.JSONObject; +import com.sdm.common.common.ThreadLocalContext; +import com.sdm.common.entity.enums.MessageTemplateEnum; +import com.sdm.common.entity.enums.NodeTypeEnum; +import com.sdm.common.entity.req.system.SendMsgReq; +import com.sdm.common.entity.resp.system.CIDStaffResp; +import com.sdm.common.feign.impl.system.MessageFeignClientImpl; +import com.sdm.common.service.TagMapService; +import com.sdm.common.service.TaskProgressService; +import com.sdm.outbridge.entity.LyricVProjectToDM; +import com.sdm.project.common.MemberTypeEnum; +import com.sdm.project.common.TaskExeStatusEnum; +import com.sdm.project.dao.SimulationNodeMapper; +import com.sdm.project.model.bo.TaskNodeTag; +import com.sdm.project.model.entity.SimulationNode; +import com.sdm.project.model.entity.SimulationTask; +import com.sdm.project.model.entity.SimulationTaskExtra; +import com.sdm.project.model.entity.SimulationTaskMember; +import com.sdm.project.model.vo.SpdmNodeExtraVo; +import com.sdm.project.service.INodeService; +import com.sdm.project.service.ISimulationTaskExtraService; +import com.sdm.project.service.ISimulationTaskMemberService; +import com.sdm.project.service.ISimulationTaskService; +import com.xxl.job.core.handler.annotation.XxlJob; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.*; +import java.util.stream.Collectors; + +import static com.sdm.project.model.entity.SimulationTaskExtra.PROPERTY_NAME_ACTUAL_PROGRESS; +import static com.sdm.project.service.impl.NodeServiceImpl.SYNC_PROJECT_SOURCE; + +@Slf4j +@Component +public class CommitmentDeadlineStatusScheduleExecutor{ + + // 时间格式化器:全局常量,线程安全,可复用(yyyy-MM-dd HH:mm:ss 固定格式) + private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + @Value("${commitmentDeadlineStatusTask.schedule.calculationInterval:5}") + private int calculationInterval; + + @Resource + private INodeService nodeService; + + @Autowired + private SimulationNodeMapper nodeMapper; + + @Resource + private ISimulationTaskService taskService; + + @Resource + private ISimulationTaskMemberService taskMemberService; + + @Resource + private ISimulationTaskExtraService taskExtraService; + + @Autowired + private TaskProgressService taskProgressService; + + @Autowired + private MessageFeignClientImpl messageFeignClient; + + public static final String LIST_RELEASE_TIME = "listReleaseTime"; + + public static final String THREE_D_DESIGN = "3D设计"; + + @XxlJob("commitmentDeadlineStatusHandler") + public void commitmentDeadlineStatusHandler() { + log.info("项目是否延期的定时任务执行中"); + try { + // 1. 获取所有节点(工位) + List nodeList = nodeService.lambdaQuery().eq(SimulationNode::getNodeType, NodeTypeEnum.WORKSPACE) + .eq(SimulationNode::getProjectSource, SYNC_PROJECT_SOURCE).isNotNull(SimulationNode::getCommitmentDeadline) + .list(); + Map nodeMap = new HashMap<>(); + if (CollectionUtils.isNotEmpty(nodeList)) { // nodeMap = nodeList.stream().filter(node -> StringUtils.isNotBlank(node.getCommitmentDeadline())) // .collect(Collectors.toMap(SimulationNode::getUuid,SimulationNode::getCommitmentDeadline)); -// } -// // 2. 获取所有任务 -// List taskList = taskService.lambdaQuery() -// .in(SimulationTask::getExeStatus, Arrays.asList(TaskExeStatusEnum.NO_CONFIRM.getCode() -// , TaskExeStatusEnum.NO_STARTED.getCode(), TaskExeStatusEnum.IN_PROGRESS.getCode())) -// .list(); -// // 3. 计算间隔时间(单位:天) -//// if (CollectionUtils.isNotEmpty(nodeList)) { -//// List updateNodeList = handleNodeCommitmentDeadlineStatus(nodeList); -//// if (CollectionUtils.isNotEmpty(updateNodeList)) { -//// log.info("共有:{}个节点已延期", updateNodeList.size()); -//// nodeService.updateBatchById(updateNodeList); -//// } else { -//// log.info("无节点延期"); -//// } -//// } else { -//// log.info("无节点延期"); -//// } -// -// if (CollectionUtils.isNotEmpty(taskList)) { -// for (SimulationTask simulationTask : taskList) { -// // 取工位的军令状时间 -// String workspaceNodeId = simulationTask.getTag5(); -// if (StringUtils.isBlank(workspaceNodeId)) { -// continue; -// } -// simulationTask.setCommitmentDeadline(nodeMap.get(workspaceNodeId)); -// } -// taskList = taskList.stream().filter(task -> StringUtils.isNotBlank(task.getCommitmentDeadline())).toList(); -// List updateTaskList = new ArrayList<>(); -// if (CollectionUtils.isNotEmpty(taskList)) { -// updateTaskList = handleTaskCommitmentDeadlineStatus(taskList); -// } -// if (CollectionUtils.isNotEmpty(updateTaskList)) { -// log.info("共有:{}个任务已延期,延期的任务id为:{}", updateTaskList.size(),updateTaskList.stream().map(SimulationTask::getId).toList()); -// taskService.updateBatchById(updateTaskList); -// } else { -// log.info("无任务延期"); -// } -// } else { -// log.info("无任务延期"); -// } -// } catch (Exception ex) { -// log.error("定时任务执行异常", ex); -// } -// -// } -// -// /** -// * 核心方法:根据截止时间和间隔天数,判断并更新SimulationNode的exeStatus -// * -// * @param node 待处理的实体对象 -// * @param calculationInterval 间隔天数(int,单位:天) -// */ -// public static void updateNodeStatus(SimulationNode node, int calculationInterval) { -// // 1. 判空 -// if (node.getCommitmentDeadline().trim().isEmpty()) { -// return; -// } -// // 2. 字符串转日期对象 -// LocalDateTime deadlineTime = LocalDateTime.parse(node.getCommitmentDeadline().trim(), DATE_TIME_FORMATTER); -// LocalDateTime currentTime = LocalDateTime.now(); -// // 3. 先计算两个时间的毫秒差值 -// long diffMillis = ChronoUnit.MILLIS.between(currentTime, deadlineTime); -// // 1天 = 24*60*60*1000 毫秒 = 86400000L 毫秒,换算成带小数的天数 -// double daysBetween = diffMillis / 86400000.0D; -// // 4. 业务判断:精准天数 > 配置间隔天数 → 更新状态为:已延期 -// if (daysBetween < calculationInterval) { -// node.setExeStatus(TaskExeStatusEnum.POSTPONED.getCode()); -// } -// } -// -// private List handleNodeCommitmentDeadlineStatus(List nodeList) { -// List updateNodeList = new ArrayList<>(); -// for (SimulationNode simulationNode : nodeList) { -// updateNodeStatus(simulationNode, calculationInterval); -// if (TaskExeStatusEnum.POSTPONED.getCode().equals(simulationNode.getExeStatus())) { -// updateNodeList.add(simulationNode); -// } -// } -// return updateNodeList; -// } -// -// public static void updateTaskStatus(SimulationTask task, int calculationInterval) { -// // 1. 判空 -// if (task.getCommitmentDeadline().trim().isEmpty()) { -// return; -// } -// // 2. 字符串转日期对象 -// LocalDateTime deadlineTime = LocalDateTime.parse(task.getCommitmentDeadline().trim(), DATE_TIME_FORMATTER); -// LocalDateTime currentTime = LocalDateTime.now(); -// // 3. 先计算两个时间的毫秒差值 -// long diffMillis = ChronoUnit.MILLIS.between(currentTime, deadlineTime); -// // 1天 = 24*60*60*1000 毫秒 = 86400000L 毫秒,换算成带小数的天数 -// double daysBetween = diffMillis / 86400000.0D; -// // 4. 业务判断:精准天数 > 配置间隔天数 → 更新状态为:已延期 -// if (daysBetween < calculationInterval) { -// task.setExeStatus(TaskExeStatusEnum.POSTPONED.getCode()); -// } -// } -// -// private List handleTaskCommitmentDeadlineStatus(List taskList) { -// List updateTaskList = new ArrayList<>(); -// for (SimulationTask simulationTask : taskList) { -// updateTaskStatus(simulationTask, calculationInterval); -// if (TaskExeStatusEnum.POSTPONED.getCode().equals(simulationTask.getExeStatus())) { -// updateTaskList.add(simulationTask); -// } -// } -// return updateTaskList; -// } -// -//} + List nodeIdList = nodeList.stream().map(SimulationNode::getUuid).toList(); + List nodeExtraList = nodeMapper.getNodeExtraListByNodeIdList(nodeIdList); + if (CollectionUtils.isEmpty(nodeExtraList)) { + log.info("项目是否延期的定时任务中未查询到工位的拓展属性"); + return; + } + List listReleaseTimeExtraList = nodeExtraList.stream().filter(nodeExtra -> LIST_RELEASE_TIME.equals(nodeExtra.getPropertyName())).toList(); + if (CollectionUtils.isEmpty(listReleaseTimeExtraList)) { + log.info("项目是否延期的定时任务中未查询到工位的军令状时间"); + return; + } + nodeMap = listReleaseTimeExtraList.stream() + .collect(Collectors.toMap( + SpdmNodeExtraVo::getNodeId, + SpdmNodeExtraVo::getPropertyValue, + (existing, replacement) -> existing + )); + for (SimulationNode simulationNode : nodeList) { + simulationNode.setCommitmentDeadline(nodeMap.get(simulationNode.getUuid())); + } + } + // 2. 获取所有任务 + List taskList = taskService.lambdaQuery() + .in(SimulationTask::getExeStatus, Arrays.asList(TaskExeStatusEnum.NO_CONFIRM.getCode() + , TaskExeStatusEnum.NO_STARTED.getCode(), TaskExeStatusEnum.IN_PROGRESS.getCode())) + .list(); + // 3. 计算间隔时间(单位:天) + if (CollectionUtils.isNotEmpty(nodeList)) { + List updateNodeList = handleNodeCommitmentDeadlineStatus(nodeList); + if (CollectionUtils.isNotEmpty(updateNodeList)) { + log.info("共有:{}个节点已延期", updateNodeList.size()); + nodeService.updateBatchById(updateNodeList); + } else { + log.info("无节点延期"); + } + } else { + log.info("无节点延期"); + } + + // 查询任务进度状态的字典 + Map taskProgressMap = taskProgressService.getMapName(); + // 若实际达成进度超过 3D设计,则不发消息给提出人 + int taskProgressValue = 0; + if (isConvertibleToInt(taskProgressMap.get(THREE_D_DESIGN))) { + taskProgressValue = Integer.parseInt(taskProgressMap.get(THREE_D_DESIGN)); + }else { + log.error("未查询到3D设计的字典值,或字典值不为数字。{}",taskProgressMap.get(THREE_D_DESIGN)); + taskProgressValue = -1; + } + log.info("taskProgressValue为:{}",taskProgressValue); + + if (CollectionUtils.isNotEmpty(taskList)) { + + + for (SimulationTask simulationTask : taskList) { + // 取工位的军令状时间 + String workspaceNodeId = simulationTask.getTag5(); + if (StringUtils.isBlank(workspaceNodeId)) { + continue; + } + simulationTask.setCommitmentDeadline(nodeMap.get(workspaceNodeId)); + } + taskList = taskList.stream().filter(task -> StringUtils.isNotBlank(task.getCommitmentDeadline())).toList(); + List updateTaskList = new ArrayList<>(); + if (CollectionUtils.isNotEmpty(taskList)) { + updateTaskList = handleTaskCommitmentDeadlineStatus(taskList); + } + if (CollectionUtils.isNotEmpty(updateTaskList)) { + log.info("共有:{}个任务已延期,延期的任务id为:{}", updateTaskList.size(),updateTaskList.stream().map(SimulationTask::getId).toList()); + taskService.updateBatchById(updateTaskList); + // 查询任务的执行人 + List executorUserList = taskMemberService.lambdaQuery().in(SimulationTaskMember::getTaskId, updateTaskList.stream().map(SimulationTask::getUuid).toList()) + .eq(SimulationTaskMember::getType, MemberTypeEnum.EXECUTOR).list(); + Map> taskMemberMap = new HashMap<>(); + if (CollectionUtils.isNotEmpty(executorUserList)) { + taskMemberMap = executorUserList.stream().collect(Collectors.groupingBy(SimulationTaskMember::getTaskId)); + } + // 查询任务的拓展属性(实际达成进度) + List actualProgressList = taskExtraService.lambdaQuery().in(SimulationTaskExtra::getTaskId, updateTaskList.stream().map(SimulationTask::getUuid).toList()) + .eq(SimulationTaskExtra::getPropertyName, PROPERTY_NAME_ACTUAL_PROGRESS).list(); + Map actualProgressMap = new HashMap<>(); + if (CollectionUtils.isNotEmpty(actualProgressList)) { + actualProgressMap = actualProgressList.stream() + .collect(Collectors.toMap( + SimulationTaskExtra::getTaskId, + SimulationTaskExtra::getPropertyValue, + (oldValue, newValue) -> oldValue + )); + } + List currentTaskMemberList; + for (SimulationTask simulationTask : updateTaskList) { + // 若实际达成进度不超过 3D设计,则发消息给提出人 + String actualProgress = actualProgressMap.get(simulationTask.getUuid()); + log.info("actualProgress为:{}",actualProgress); + if (StringUtils.isNotBlank(actualProgress)) { + String actualProgressValueStr = taskProgressMap.get(actualProgress); + log.info("actualProgressValueStr为:{}",actualProgressValueStr); + if (StringUtils.isNotBlank(actualProgressValueStr) && isConvertibleToInt(actualProgressValueStr)) { + int actualProgressValue = Integer.parseInt(actualProgressValueStr); + if ((taskProgressValue == -1 || actualProgressValue <= taskProgressValue) + && ObjectUtils.isNotEmpty(simulationTask.getCreator())) { + sendMessage(MessageTemplateEnum.TASK_OVERDUE, simulationTask.getTaskName(), String.valueOf(simulationTask.getCreator()), simulationTask.getUuid()); + } + } + } + // 发消息给执行人 + currentTaskMemberList = taskMemberMap.get(simulationTask.getUuid()); + if (CollectionUtils.isEmpty(currentTaskMemberList)) { + log.info("未查询到任务:{}的执行人,无法发送消息",simulationTask.getUuid()); + continue; + } + for (SimulationTaskMember simulationTaskMember : currentTaskMemberList) { + sendMessage(MessageTemplateEnum.TASK_OVERDUE, simulationTask.getTaskName(), String.valueOf(simulationTaskMember.getUserId()), simulationTask.getUuid()); + } + + } + + + } else { + log.info("无任务延期"); + } + } else { + log.info("无任务延期"); + } + } catch (Exception ex) { + log.error("定时任务执行异常", ex); + } + + } + + /** + * 核心方法:根据截止时间和间隔天数,判断并更新SimulationNode的exeStatus + * + * @param node 待处理的实体对象 + * @param calculationInterval 间隔天数(int,单位:天) + */ + public static void updateNodeStatus(SimulationNode node, int calculationInterval) { + // 1. 判空 + if (node.getCommitmentDeadline().trim().isEmpty()) { + return; + } + // 2. 字符串转日期对象 + LocalDateTime deadlineTime = LocalDateTime.parse(node.getCommitmentDeadline().trim(), DATE_TIME_FORMATTER); + LocalDateTime currentTime = LocalDateTime.now(); + // 3. 先计算两个时间的毫秒差值 + long diffMillis = ChronoUnit.MILLIS.between(currentTime, deadlineTime); + // 1天 = 24*60*60*1000 毫秒 = 86400000L 毫秒,换算成带小数的天数 + double daysBetween = diffMillis / 86400000.0D; + // 4. 业务判断:精准天数 > 配置间隔天数 → 更新状态为:已延期 + if (daysBetween < calculationInterval) { + node.setExeStatus(TaskExeStatusEnum.POSTPONED.getCode()); + } + } + + private List handleNodeCommitmentDeadlineStatus(List nodeList) { + List updateNodeList = new ArrayList<>(); + for (SimulationNode simulationNode : nodeList) { + updateNodeStatus(simulationNode, calculationInterval); + if (TaskExeStatusEnum.POSTPONED.getCode().equals(simulationNode.getExeStatus())) { + updateNodeList.add(simulationNode); + } + } + return updateNodeList; + } + + public static void updateTaskStatus(SimulationTask task, int calculationInterval) { + // 1. 判空 + if (task.getCommitmentDeadline().trim().isEmpty()) { + return; + } + // 2. 字符串转日期对象 + LocalDateTime deadlineTime = LocalDateTime.parse(task.getCommitmentDeadline().trim(), DATE_TIME_FORMATTER); + LocalDateTime currentTime = LocalDateTime.now(); + // 3. 先计算两个时间的毫秒差值 + long diffMillis = ChronoUnit.MILLIS.between(currentTime, deadlineTime); + // 1天 = 24*60*60*1000 毫秒 = 86400000L 毫秒,换算成带小数的天数 + double daysBetween = diffMillis / 86400000.0D; + // 4. 业务判断:精准天数 > 配置间隔天数 → 更新状态为:已延期 + if (daysBetween < calculationInterval) { + task.setExeStatus(TaskExeStatusEnum.POSTPONED.getCode()); + } + } + + private List handleTaskCommitmentDeadlineStatus(List taskList) { + List updateTaskList = new ArrayList<>(); + for (SimulationTask simulationTask : taskList) { + updateTaskStatus(simulationTask, calculationInterval); + if (TaskExeStatusEnum.POSTPONED.getCode().equals(simulationTask.getExeStatus())) { + updateTaskList.add(simulationTask); + } + } + return updateTaskList; + } + + private void sendMessage(MessageTemplateEnum templateEnum, String taskName, String userId, String uuid) { + SendMsgReq req = new SendMsgReq(); + req.setTitle(templateEnum.getTitle()); + req.setContent(templateEnum.getContent(taskName)); + req.setTenantId(ThreadLocalContext.getTenantId().toString()); + req.setUserId(userId); + JSONObject params = new JSONObject(); + params.put("taskId", uuid); + req.setParams(JSONObject.toJSONString(params)); + messageFeignClient.sendMessage(req); + } + + /** + * 判断字符串是否可以安全转换为int类型 + * + * @param str 待判断的字符串 + * @return true-可以安全转换,false-不可以 + */ + public static boolean isConvertibleToInt(String str) { + // 1. 处理null或空字符串 + if (str == null || str.trim().isEmpty()) { + return false; + } + + // 去除首尾空格 + String trimmedStr = str.trim(); + + // 2. 正则校验:匹配整数格式(可选的正负号 + 至少1位数字) + // 正则说明:^[-+]? 匹配开头的正负号(可选);\\d+ 匹配至少1位数字;$ 匹配字符串结尾 + if (!trimmedStr.matches("^[-+]?\\d+$")) { + return false; + } + + try { + // 3. 先尝试转换为long(避免int范围溢出),再判断是否在int范围内 + long num = Long.parseLong(trimmedStr); + return num >= Integer.MIN_VALUE && num <= Integer.MAX_VALUE; + } catch (NumberFormatException e) { + // 理论上正则校验通过后不会走到这里,做兜底处理 + return false; + } + } + +} diff --git a/project/src/main/java/com/sdm/project/service/impl/LyricInternalServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/LyricInternalServiceImpl.java index eddf9636..3113630f 100644 --- a/project/src/main/java/com/sdm/project/service/impl/LyricInternalServiceImpl.java +++ b/project/src/main/java/com/sdm/project/service/impl/LyricInternalServiceImpl.java @@ -387,7 +387,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { SdmResponse>> pageDataRespSdmResponse = sysUserFeignClient.listUser(userListReq); if (pageDataRespSdmResponse.isSuccess() && pageDataRespSdmResponse.getData().getData() != null) { List userList = pageDataRespSdmResponse.getData().getData(); - usernameToUserIdMap = userList.stream().collect(Collectors.toMap(CIDUserResp::getUsername, CIDUserResp::getUserId)); + usernameToUserIdMap = userList.stream().collect(Collectors.toMap(CIDUserResp::getJobNumber, CIDUserResp::getUserId)); } for (SimulationNode projectNode : projectNodeList) { diff --git a/project/src/main/java/com/sdm/project/service/impl/NodeServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/NodeServiceImpl.java index a39dd2eb..ee5d4c4c 100644 --- a/project/src/main/java/com/sdm/project/service/impl/NodeServiceImpl.java +++ b/project/src/main/java/com/sdm/project/service/impl/NodeServiceImpl.java @@ -3426,7 +3426,7 @@ public class NodeServiceImpl extends ServiceImpl>> pageDataRespSdmResponse = sysUserFeignClient.listUser(userListReq); if (pageDataRespSdmResponse.isSuccess() && pageDataRespSdmResponse.getData().getData() != null) { List userList = pageDataRespSdmResponse.getData().getData(); - usernameToUserIdMap = userList.stream().collect(Collectors.toMap(CIDUserResp::getUsername, CIDUserResp::getUserId)); + usernameToUserIdMap = userList.stream().collect(Collectors.toMap(CIDUserResp::getJobNumber, CIDUserResp::getUserId)); } // 筛选出所有工位节点 for (LyricVTodoEmulationInfoDM todoItem : todoInfoList) { diff --git a/project/src/main/java/com/sdm/project/service/impl/SimulationTaskServiceImpl.java b/project/src/main/java/com/sdm/project/service/impl/SimulationTaskServiceImpl.java index 68fe5356..615fee0e 100644 --- a/project/src/main/java/com/sdm/project/service/impl/SimulationTaskServiceImpl.java +++ b/project/src/main/java/com/sdm/project/service/impl/SimulationTaskServiceImpl.java @@ -203,7 +203,7 @@ public class SimulationTaskServiceImpl extends ServiceImpl>> pageDataRespSdmResponse = sysUserFeignClient.listUser(userListReq); if (pageDataRespSdmResponse.isSuccess() && pageDataRespSdmResponse.getData().getData() != null) { List userList = pageDataRespSdmResponse.getData().getData(); - usernameToUserIdMap = userList.stream().collect(Collectors.toMap(CIDUserResp::getUsername, CIDUserResp::getUserId)); + usernameToUserIdMap = userList.stream().collect(Collectors.toMap(CIDUserResp::getJobNumber, CIDUserResp::getUserId)); } List newTaskList = convertToNewVoBatch(pageTaskList, batchData,usernameToUserIdMap); stopWatch.stop();