diff --git a/project/src/main/java/com/sdm/project/common/DemandTypeEnum.java b/project/src/main/java/com/sdm/project/common/DemandTypeEnum.java new file mode 100644 index 00000000..b8b57178 --- /dev/null +++ b/project/src/main/java/com/sdm/project/common/DemandTypeEnum.java @@ -0,0 +1,20 @@ +package com.sdm.project.common; + +import lombok.Getter; + +@Getter +public enum DemandTypeEnum { + + ANIMATION("动画"), + FINITE_ELEMENT_SIMULATION("有限元仿真"), + ROBOT_SIMULATION("机器人仿真"), + LOGISTICS_SIMULATION("物流仿真"); + + private final String name; + + + DemandTypeEnum(String name) { + this.name = name; + } + +} diff --git a/project/src/main/java/com/sdm/project/controller/SimulationLyricNodeController.java b/project/src/main/java/com/sdm/project/controller/SimulationLyricNodeController.java index c42ccb82..f2c0af47 100644 --- a/project/src/main/java/com/sdm/project/controller/SimulationLyricNodeController.java +++ b/project/src/main/java/com/sdm/project/controller/SimulationLyricNodeController.java @@ -51,8 +51,8 @@ public class SimulationLyricNodeController { @GetMapping("/optimisedGetTodoList") @Operation(summary = "获取待办列表(优化版)", description = "获取待办列表(优化版)") - public SdmResponse optimisedGetTodoList() { - return lyricInternalService.optimisedGetTodoList("http"); + public SdmResponse optimisedGetTodoList(@RequestParam(value = "startTime") @Validated String startTime,@RequestParam(value = "endTime") @Validated String endTime) { + return lyricInternalService.optimisedGetTodoList("http",startTime,endTime); } @GetMapping("/getProjectList") diff --git a/project/src/main/java/com/sdm/project/dao/SimulationDemandMapper.java b/project/src/main/java/com/sdm/project/dao/SimulationDemandMapper.java index 11137062..9b076087 100644 --- a/project/src/main/java/com/sdm/project/dao/SimulationDemandMapper.java +++ b/project/src/main/java/com/sdm/project/dao/SimulationDemandMapper.java @@ -8,6 +8,7 @@ import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import java.util.List; +import java.util.Set; @Mapper public interface SimulationDemandMapper extends BaseMapper { @@ -42,6 +43,8 @@ public interface SimulationDemandMapper extends BaseMapper { List getAllList(); + Set getAllCodeList(); + List getDemandListWithCondition(@Param("req") DemandQryReq req); } diff --git a/project/src/main/java/com/sdm/project/service/ILyricInternalService.java b/project/src/main/java/com/sdm/project/service/ILyricInternalService.java index d05fe595..82d84721 100644 --- a/project/src/main/java/com/sdm/project/service/ILyricInternalService.java +++ b/project/src/main/java/com/sdm/project/service/ILyricInternalService.java @@ -52,5 +52,5 @@ public interface ILyricInternalService { SdmResponse listNoPermission(SpdmNodeListReq req); - SdmResponse optimisedGetTodoList(String http); + SdmResponse optimisedGetTodoList(String http,String startTime,String endTime); } 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 e74b8fc3..569eb217 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 @@ -31,6 +31,7 @@ import com.sdm.outbridge.mode.LyricExceptionModel; import com.sdm.outbridge.mode.SimulationTaskSyncExBo; import com.sdm.outbridge.service.lyric.*; import com.sdm.project.common.ApprovalStatusEnum; +import com.sdm.project.common.DemandTypeEnum; import com.sdm.project.common.MemberTypeEnum; import com.sdm.project.common.generator.UniqueFileNameGenerator; import com.sdm.project.dao.SimulationDemandMapper; @@ -71,6 +72,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.text.SimpleDateFormat; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.*; import java.util.concurrent.locks.ReentrantLock; @@ -102,6 +105,9 @@ public class LyricInternalServiceImpl implements ILyricInternalService { // 同步待办锁 private final ReentrantLock syncTodoInfoLock = new ReentrantLock(); + // 同步待办关联的项目锁 + private final ReentrantLock syncTodoInfoProjectLock = new ReentrantLock(); + @Autowired private LyricIntegrateService lyricIntegrateService; @@ -157,6 +163,9 @@ public class LyricInternalServiceImpl implements ILyricInternalService { @Value("${lyric.syncTodoDataWaitSeconds:3}") private Long syncTodoDataWaitSeconds; + @Value("${lyric.syncProjectDataWaitSeconds:5}") + private Long syncProjectDataWaitSeconds; + @Autowired private SimulationTaskMapper simulationTaskMapper; @@ -173,6 +182,12 @@ public class LyricInternalServiceImpl implements ILyricInternalService { @Value("${lyric.syncException.batchSize:100}") private Integer batchSize; + private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + // 同步待办时,查询待办的最大时间间隔,单位:天 +// @Value("${lyricTodoInterval:7}") +// private int lyricTodoInterval; + /** * 判断字符串是否可以安全转换为Long类型 * @@ -323,8 +338,8 @@ public class LyricInternalServiceImpl implements ILyricInternalService { * 核心同步逻辑:构建数据并执行批量操作 */ private SdmResponse syncTodoData(List projectNodeList, - List todoInfoList,String traceId) { - if(StringUtils.isNotBlank(traceId)){ + List todoInfoList, String traceId) { + if (StringUtils.isNotBlank(traceId)) { MdcUtil.putTraceId(traceId); } // 尝试获取锁(立即返回,不等待) @@ -375,7 +390,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { SpdmAddDemandReq demandReq = buildDemandReq(todo, demandUuid, curDateStr); List memberList = buildDemandMemberList(todo, demandUuid, jobNumber, curDateStr); // 2. 构建权限更新参数 - buildPermissionReqList(demandUuid, jobNumber, todo, updatePermissionList,usernameToUserIdMap); + buildPermissionReqList(demandUuid, jobNumber, todo, updatePermissionList, usernameToUserIdMap); // 3. 构建需求文件夹节点 demandDirNodeList.add(buildDemandDirNode(demandUuid, projectNode, demandReq.getDemandName())); // 4. 异步保存需求数据 @@ -398,17 +413,17 @@ public class LyricInternalServiceImpl implements ILyricInternalService { // 执行批量操作 executeBatchOperations(createDirItemList, updatePermissionList); - if(CollectionUtils.isNotEmpty(demandToCreateTaskList)){ + if (CollectionUtils.isNotEmpty(demandToCreateTaskList)) { simulationTaskService.batchCreateTaskFromDemand(demandToCreateTaskList); } return SdmResponse.success(); } catch (Exception e) { log.error("syncTodoData 未知 error: {}", e.getMessage()); - return SdmResponse.failed(); - }finally { + return SdmResponse.failed(); + } finally { syncTodoInfoLock.unlock(); - if(StringUtils.isNotBlank(traceId)){ + if (StringUtils.isNotBlank(traceId)) { MdcUtil.removeTraceId(); } } @@ -572,7 +587,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { req.setUserId(userId); req.setUuid(uuid); Map permissions = new HashMap<>(); - if (MemberTypeEnum.PRINCIPAL.getCode().equals(type) || MemberTypeEnum.EXECUTOR.getCode().equals(type)) { + if (MemberTypeEnum.PRINCIPAL.getCode().equals(type) || MemberTypeEnum.EXECUTOR.getCode().equals(type)) { permissions.put(userId, FilePermissionEnum.BASE.getValue()); } else { permissions.put(userId, FilePermissionEnum.ALL.getValue()); @@ -628,7 +643,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { } catch (Exception e) { log.error("异步保存需求[{}]数据异常: ", demandReq.getDemandCode(), e); } - },projectTaskThreadPoolExecutor); + }, projectTaskThreadPoolExecutor); } /** @@ -641,26 +656,26 @@ public class LyricInternalServiceImpl implements ILyricInternalService { // project的uuid,createDirItemList中每一项project的uuid都一样,取第一个即可 String projectNodeId = createDirItemList.get(0).getParentDirNodeInfo().getUuId(); if (StringUtils.isBlank(projectNodeId)) { - log.error("projectNodeId为空,createDirItemList:{}",createDirItemList); + log.error("projectNodeId为空,createDirItemList:{}", createDirItemList); return; } SdmResponse fileMetadataInfoResp = dataFeignClient.queryFileMetadataInfo(projectNodeId, NodeTypeEnum.PROJECT.getValue(), 0L); if (fileMetadataInfoResp.getData() == null) { - log.error("fileMetadataInfoResp为空,projectNodeId为:{}",projectNodeId); + log.error("fileMetadataInfoResp为空,projectNodeId为:{}", projectNodeId); return; } // 查询需求附件的uuid,元数据表中【parentId是project的元数据主键id且originalName为:需求附件】 FileMetadataInfoResp projectMetadataInfo = fileMetadataInfoResp.getData(); SdmResponse> listSdmResponse = dataFeignClient.listDir(DirTypeEnum.PROJECT_NODE_DIR.getValue(), projectMetadataInfo.getId()); if (!listSdmResponse.isSuccess() || CollectionUtils.isEmpty(listSdmResponse.getData())) { - log.error("listSdmResponse为空,project的元数据主键id为:{}",projectMetadataInfo.getId()); + log.error("listSdmResponse为空,project的元数据主键id为:{}", projectMetadataInfo.getId()); return; } List childrenMetadataInfoList = listSdmResponse.getData(); FileMetadataInfoResp demandAttachFileMetadataInfoResp = childrenMetadataInfoList.stream().filter(metadataInfo -> AttachFileTypeEnum.DEMAND_FILE.getValue().equals(metadataInfo.getOriginalName())).findFirst().orElse(null); Long demandAttachFileMetadataInfoId; if (ObjectUtils.isEmpty(demandAttachFileMetadataInfoResp)) { - log.info("未查询到需求附件文件夹,当前项目下的子文件夹为:{}",childrenMetadataInfoList); + log.info("未查询到需求附件文件夹,当前项目下的子文件夹为:{}", childrenMetadataInfoList); // 项目层级文件夹和需求文件夹中,新增一层【需求附件】文件夹 List demandAttachFolderItemReqList = new ArrayList<>(); BatchCreateNormalDirReq demandAttachBatchCreateNormalDirReq = new BatchCreateNormalDirReq(); @@ -697,7 +712,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { } // 需求附件文件夹的元数据主键id demandAttachFileMetadataInfoId = successList.get(0).getId(); - }else { + } else { demandAttachFileMetadataInfoId = demandAttachFileMetadataInfoResp.getId(); } for (BatchCreateDirItem batchCreateDirItem : createDirItemList) { @@ -720,7 +735,6 @@ public class LyricInternalServiceImpl implements ILyricInternalService { } - // 批量更新权限 if (CollectionUtils.isNotEmpty(updatePermissionList)) { List filePermissions = new ArrayList<>(); @@ -779,8 +793,8 @@ public class LyricInternalServiceImpl implements ILyricInternalService { } // 4. 构建同步数据并执行批量操作 - return (Objects.equals("http",from)) ? httpSyncTodoData(projectNodeList, todoInfoList): - syncTodoData(projectNodeList, todoInfoList,""); + return (Objects.equals("http", from)) ? httpSyncTodoData(projectNodeList, todoInfoList) : + syncTodoData(projectNodeList, todoInfoList, ""); } @@ -1420,7 +1434,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { } catch (MyBatisSystemException ex) { // 查询发生异常,记录异常日志(可能是测试环境预期异常) log.warn("查询EP项目列表时发生异常(可能是测试环境预期异常),项目编号:{},项目名称:{},项目类型:{},异常信息:{}", - req.getProjectNum(),req.getProjectName(),req.getDifficultyType(), ex.getMessage()); + req.getProjectNum(), req.getProjectName(), req.getDifficultyType(), ex.getMessage()); } PageInfo page = new PageInfo<>(projectList); return PageUtils.getJsonObjectSdmResponse(projectList, page); @@ -1497,7 +1511,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { throw new RuntimeException(e); } } - },projectTaskThreadPoolExecutor); + }, projectTaskThreadPoolExecutor); nodeService.lambdaUpdate().set(SimulationNode::getApprovalStatus, String.valueOf(ApprovalStatusEnum.ING.getCode())) .eq(SimulationNode::getNodeCode, req.getWorkspaceCode()) .eq(SimulationNode::getNodeType, NodeTypeEnum.WORKSPACE.getValue()) @@ -1686,7 +1700,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { } catch (Exception e) { throw new RuntimeException(e); } - }else { + } else { try { // entry.getValue() = "uuid1,uuid2" setTagProperty(addNode, preTag, entry.getValue()); @@ -1732,9 +1746,9 @@ public class LyricInternalServiceImpl implements ILyricInternalService { Map userPermissions = new HashMap<>(); userPermissions.put(userId, FilePermissionEnum.ALL.getValue()); updatePermissionReq.setUserPermissions(userPermissions); - log.info("syncPhase,更新用户权限的参数为:{}",updatePermissionReq); + log.info("syncPhase,更新用户权限的参数为:{}", updatePermissionReq); SdmResponse updatePermissionResponse = dataFeignClient.updatePermission(updatePermissionReq); - log.info("syncPhase,更新用户权限的返回值为:{}",updatePermissionResponse); + log.info("syncPhase,更新用户权限的返回值为:{}", updatePermissionResponse); return SdmResponse.success(true); } @@ -1771,10 +1785,11 @@ public class LyricInternalServiceImpl implements ILyricInternalService { /** * 构建规范的分页返回结果,保证返回格式统一 + * * @param current 当前页 - * @param size 页大小 - * @param total 总条数 - * @param data 分页数据 + * @param size 页大小 + * @param total 总条数 + * @param data 分页数据 * @return 标准分页JSON */ private JSONObject buildPageResult(int current, int size, long total, List data) { @@ -1788,14 +1803,15 @@ public class LyricInternalServiceImpl implements ILyricInternalService { /** * 查询项目参与人员 + * * @param projectId 项目的uuid * @param queryType 区分人员状态的标识,为空:代表查询所有状态的人员,0:存在, 1:删除 , 2:冻结 - * @param current 当前页码,从1开始 - * @param size 每页展示的条数 + * @param current 当前页码,从1开始 + * @param size 每页展示的条数 * @return */ @Override - public SdmResponse queryProjectMember(String projectId,Integer queryType, Integer current, Integer size) { + public SdmResponse queryProjectMember(String projectId, Integer queryType, Integer current, Integer size) { log.info("开始查询项目参与人员信息,projectId:{}", projectId); // 1. 入参校验 if (StringUtils.isBlank(projectId)) { @@ -1826,7 +1842,7 @@ public class LyricInternalServiceImpl implements ILyricInternalService { try { projectMemberList = lyricVProjectResourcePlanDMService.lambdaQuery().eq(LyricVProjectResourcePlanDM::getProjectId, syncProjectId) .eq(ObjectUtils.isNotEmpty(queryType), LyricVProjectResourcePlanDM::getDelFlag, queryType).list(); - }catch (Exception ex) { + } catch (Exception ex) { // 查询发生异常,记录异常日志(可能是测试环境预期异常) if (ex instanceof MyBatisSystemException) { log.warn("查询项目参与人员视图发生预期异常(测试环境),syncProjectId:{},异常信息:{}", @@ -2049,34 +2065,655 @@ public class LyricInternalServiceImpl implements ILyricInternalService { return SdmResponse.success(jsonObject); } - @Override - public SdmResponse optimisedGetTodoList(String http) { + /** + * 查询固定时间内的待办数据 + */ + private List queryTodoListWithFixedTime(String startTime, String endTime) { + // 查询原始待办数据 + // TODO 这里要确认是不是只拉取有限元仿真 + List todoInfoList = lyricVTodoInfoService.lambdaQuery() + .in(LyricVTodoEmulationInfoDM::getRelevanceTask, Arrays.asList(DemandTypeEnum.FINITE_ELEMENT_SIMULATION.getName())) + .ge(LyricVTodoEmulationInfoDM::getCreateTime, startTime) + .le(LyricVTodoEmulationInfoDM::getCreateTime, endTime) + .list(); + if (CollectionUtils.isEmpty(todoInfoList)) { + log.info("未查询到{}到{}的待同步的待办数据", startTime, endTime); + return Collections.emptyList(); + } - // 先查询系统内所有待办 + // 过滤已同步的待办 + Set existDemandCodeSet = demandMapper.getAllCodeList(); + if (CollectionUtils.isEmpty(existDemandCodeSet)) { + return todoInfoList; + } + List filterTodoList = todoInfoList.stream() + .filter(todoInfo -> !existDemandCodeSet.contains(String.valueOf(todoInfo.getTodoId()))) + .collect(Collectors.toList()); - return null; + if (CollectionUtils.isEmpty(filterTodoList)) { + log.info("本次手动同步到的待办都已经进行过同步"); + } + return filterTodoList; } - private SdmResponse httpSyncTodoData( List projectNodeList,List todoInfoList){ + /** + * 根据间隔天数计算时间范围 + * @param lyricTodoInterval 倒退的天数(int类型) + * @return 数组,索引0是起始时间字符串,索引1是结束时间(当前时间)字符串 + */ + public static String[] calculateTimeRange(int lyricTodoInterval) { + // 1. 获取当前时间(精确到时分秒) + LocalDateTime currentTime = LocalDateTime.now(); + + // 2. 计算起始时间:当前时间向前倒退指定天数 + LocalDateTime startTime = currentTime.minusDays(lyricTodoInterval); + + // 3. 格式化时间为指定的字符串格式 + String startTimeStr = startTime.format(DATE_TIME_FORMATTER); + String endTimeStr = currentTime.format(DATE_TIME_FORMATTER); + + return new String[]{startTimeStr, endTimeStr}; + } + + @Override + public SdmResponse optimisedGetTodoList(String http, String startTime, String endTime) { + Long tenantId = ThreadLocalContext.getTenantId(); + Long jobNumber = ThreadLocalContext.getUserId(); + + // 缓存校验 + SdmResponse cacheCheckResponse = checkSyncCache(); + if (cacheCheckResponse != null) { + return cacheCheckResponse; + } + + // TODO 现场手动同步完成后,根据配置文件动态计算拉取待办的开始、结束时间 +// String[] timeArray = calculateTimeRange(lyricTodoInterval); +// String startTime = timeArray[0]; +// String endTime = timeArray[1]; + + // 先查询系统内所有待办(90天内仿真类型),同步历史待办时,先取startTime和endTime,同步固定某段时间内的待办 + List lyricVTodoEmulationInfoDMList = queryTodoListWithFixedTime(startTime, endTime); + + // 待办信息在系统中是否都已经存在 + if (CollectionUtils.isEmpty(lyricVTodoEmulationInfoDMList)) { + log.info("lyricVTodoEmulationInfoDMList为空"); + return SdmResponse.success(); + } + log.info("本次共同步待办:{}个",lyricVTodoEmulationInfoDMList.stream()); + + // 根据待办关联的项目情况,分为关联的项目已在系统和关联的项目未在系统两部分数据 + List noRelatedProjectVTodoEmulationInfoDMList; + List projectCodeList = lyricVTodoEmulationInfoDMList.stream().map(LyricVTodoEmulationInfoDM::getProject) + .filter(StringUtils::isNotBlank).distinct().collect(Collectors.toList()); + if (CollectionUtils.isEmpty(projectCodeList)) { + log.info("同步到的待办的项目号都是空,待办id:{}", lyricVTodoEmulationInfoDMList.stream().map(LyricVTodoEmulationInfoDM::getId).collect(Collectors.toSet())); + return SdmResponse.success(); + } + // 根据projectCodeList查询系统内的项目信息 + List projectNodeList = nodeService.lambdaQuery().in(SimulationNode::getNodeCode, projectCodeList).list(); + if (CollectionUtils.isEmpty(projectNodeList)) { + // 本次同步到的待办的关联项目都未在系统内 + log.info("本次同步到的待办的关联项目都未在系统内"); + noRelatedProjectVTodoEmulationInfoDMList = lyricVTodoEmulationInfoDMList; + } else { + // 本次同步到的待办的关联项目有一部分已经在系统内 + log.info("本次同步到的待办的关联项目有一部分已经在系统内"); + List projectNodeCodeList = projectNodeList.stream().map(SimulationNode::getNodeCode).toList(); + noRelatedProjectVTodoEmulationInfoDMList = lyricVTodoEmulationInfoDMList.stream().filter(lyricVTodoEmulationInfoDM -> !projectNodeCodeList.contains(lyricVTodoEmulationInfoDM.getProject())).collect(Collectors.toList()); + } + + // 关联的项目未在系统 + // 取项目视图、工位相关视图构建项目树信息(只同步当前阶段)创建任务(不创建任务文件夹,等下发时进行创建) + if (CollectionUtils.isNotEmpty(noRelatedProjectVTodoEmulationInfoDMList)) { + SdmResponse response = httpSyncHandleNoRelatedProjectTodo(noRelatedProjectVTodoEmulationInfoDMList, tenantId, jobNumber); + log.info("httpSyncHandleNoRelatedProjectTodo响应值为:{}",response); + if (!response.isSuccess()) { + return response; + } + } + + // 关联的项目已在系统 + // 直接关联在相应的项目下 创建任务(不创建任务文件夹,等下发时进行创建) + SdmResponse response = handleRelatedProjectTodo(projectNodeList, lyricVTodoEmulationInfoDMList); + log.info("handleRelatedProjectTodo响应值为:{}",response); + return response; + } + + private SdmResponse httpSyncHandleNoRelatedProjectTodo(List noRelatedProjectVTodoEmulationInfoDMList, Long tenantId, Long jobNumber) { + CompletableFuture syncHandleNoRelatedProjectTodoFeature = CompletableFuture.supplyAsync(() -> + handleNoRelatedProjectTodo(noRelatedProjectVTodoEmulationInfoDMList, tenantId, jobNumber)); + try { + SdmResponse sdmResponse = syncHandleNoRelatedProjectTodoFeature.get(syncProjectDataWaitSeconds, TimeUnit.SECONDS); + return sdmResponse; + } catch (InterruptedException e) { + log.error("同步项目信息异常终止:{}", e.getMessage()); + return SdmResponse.failed("同步项目信息异常终止"); + } catch (ExecutionException e) { + log.error("同步项目信息执行错误:{}", e.getMessage()); + return SdmResponse.failed("同步项目信息执行出错误"); + } catch (TimeoutException e) { + log.warn("同步项目信息执行超时:{}", e.getMessage()); + return SdmResponse.success("同步项目信息执行中,请稍后"); + } catch (Exception e) { + log.error("同步项目信息未知错误:{}", e.getMessage()); + return SdmResponse.failed("同步项目信息未知错误"); + } + } + + private SdmResponse handleNoRelatedProjectTodo(List noRelatedProjectVTodoEmulationInfoDMList, Long tenantId, Long jobNumber) { + // 尝试获取锁(立即返回,不等待) + if (!syncTodoInfoProjectLock.tryLock()) { + return SdmResponse.success("有数据同步任务(同步项目信息)正在执行中,请稍后再试"); + } + // 取项目视图、工位相关视图构建项目树信息(只同步当前阶段) + // 根据待办获取所有项目编号 + try { + List projectNumList = noRelatedProjectVTodoEmulationInfoDMList.stream().map(LyricVTodoEmulationInfoDM::getProject) + .filter(StringUtils::isNotBlank).distinct().toList(); + if (CollectionUtils.isEmpty(projectNumList)) { + log.info("projectNumList为空"); + return SdmResponse.success("projectNumList为空"); + } + // 根据项目编号查询项目视图获取项目信息 + List lyricVProjectToDMList = lyricVProjectToDmService.lambdaQuery().in(LyricVProjectToDM::getProjectNum, projectNumList).list(); + if (CollectionUtils.isEmpty(lyricVProjectToDMList)) { + log.info("lyricVProjectToDMList为空"); + return SdmResponse.success("lyricVProjectToDMList为空"); + } + for (LyricVProjectToDM lyricVProjectToDM : lyricVProjectToDMList) { + buildProjectForTodoInfo(lyricVProjectToDM, tenantId, jobNumber); + } + }catch (Exception e) { + log.error("handleNoRelatedProjectTodo 未知 error: {}", e.getMessage()); + return SdmResponse.failed(); + } finally { + syncTodoInfoProjectLock.unlock(); + } + return SdmResponse.success(); + } + + public static String getTagProperty(Object obj, String propertyName) throws Exception { + Class clazz = obj.getClass(); + Field field = clazz.getDeclaredField(propertyName); + field.setAccessible(true); + return (String) field.get(obj); + } + + /** + * 筛选不同类型的节点,封装为统一对象 + */ + private NodeServiceImpl.NodeTypeFilterResult filterNodesByType(List addNodeList) { + SpdmProjectNodeEditReq projectNode = addNodeList.stream() + .filter(node -> NodeTypeEnum.PROJECT.getValue().equals(node.getNodeType())) + .findFirst() + .orElse(null); + + List phaseNodes = addNodeList.stream() + .filter(node -> NodeTypeEnum.PHASE.getValue().equals(node.getNodeType())) + .collect(Collectors.toList()); + + List machineNodes = addNodeList.stream() + .filter(node -> NodeTypeEnum.MACHINE.getValue().equals(node.getNodeType())) + .collect(Collectors.toList()); + + List workspaceNodes = addNodeList.stream() + .filter(node -> NodeTypeEnum.WORKSPACE.getValue().equals(node.getNodeType())) + .collect(Collectors.toList()); + + return new NodeServiceImpl.NodeTypeFilterResult(projectNode, phaseNodes, machineNodes, workspaceNodes); + } + + /** + * 仅创建单个阶段节点 + */ + private void createSinglePhaseDir(List phaseNodes) { + if (CollectionUtils.isEmpty(phaseNodes)) { + log.warn("无阶段节点可创建"); + return; + } + SpdmProjectNodeEditReq firstPhaseNode = phaseNodes.get(0); + createDir(firstPhaseNode.getUuid(), firstPhaseNode.getNodeType(), + firstPhaseNode.getPid(), firstPhaseNode.getNodeName()); + } + + /** + * 通用方法:构建单个DirNodeInfo + */ + private DirNodeInfo buildDirNodeInfo(String uuid, String parentUuid, String nodeType, String dirName) { + DirNodeInfo dirNodeInfo = new DirNodeInfo(); + dirNodeInfo.setUuId(uuid); + dirNodeInfo.setParentUuId(parentUuid); + dirNodeInfo.setUuIdOwnType(nodeType); + dirNodeInfo.setDirName(dirName); + return dirNodeInfo; + } + + /** + * 通用方法:批量构建DirNodeInfo列表 + */ + private List buildDirNodeInfoList(List nodeList, String parentUuid, String nodeType) { + if (CollectionUtils.isEmpty(nodeList)) { + return new ArrayList<>(); + } + return nodeList.stream() + .map(node -> buildDirNodeInfo(node.getUuid(), parentUuid, nodeType, node.getNodeName())) + .collect(Collectors.toList()); + } + + /** + * 构建项目节点的dirItem + */ + private void buildProjectDirItem(NodeServiceImpl.NodeTypeFilterResult filterResult, List createDirItemList) { + SpdmProjectNodeEditReq projectNode = filterResult.getProjectNode(); + List phaseNodes = filterResult.getAddPhaseNodeList(); + BatchCreateDirItem projectCreateDirItem = new BatchCreateDirItem(); + DirNodeInfo projectDirNodeInfo = buildDirNodeInfo( + projectNode.getUuid(), null, + NodeTypeEnum.PROJECT.getValue(), projectNode.getNodeName() + ); + projectCreateDirItem.setParentDirNodeInfo(projectDirNodeInfo); + // 构建项目下的阶段子节点 + List phaseDirInfoList = buildDirNodeInfoList( + phaseNodes, projectNode.getUuid(), NodeTypeEnum.PHASE.getValue() + ); + projectCreateDirItem.setChildDirNodeInfos(phaseDirInfoList); + createDirItemList.add(projectCreateDirItem); + } + + /** + * 构建阶段节点的dirItem + */ + private BatchCreateDirItem buildPhaseDirItem(SpdmProjectNodeEditReq phaseNode, String projectUuid, List machineNodes) { + BatchCreateDirItem phaseCreateDirItem = new BatchCreateDirItem(); + DirNodeInfo phaseDirNodeInfo = buildDirNodeInfo( + phaseNode.getUuid(), projectUuid, + NodeTypeEnum.PHASE.getValue(), phaseNode.getNodeName() + ); + phaseCreateDirItem.setParentDirNodeInfo(phaseDirNodeInfo); + // 若无机台节点,子节点为空 + List phaseChildDirInfoList = CollectionUtils.isEmpty(machineNodes) + ? new ArrayList<>() + : buildDirNodeInfoList( + machineNodes.stream() + .filter(machineNode -> phaseNode.getUuid().equals(machineNode.getPid())) + .collect(Collectors.toList()), + phaseNode.getUuid(), NodeTypeEnum.MACHINE.getValue() + ); + phaseCreateDirItem.setChildDirNodeInfos(phaseChildDirInfoList); + return phaseCreateDirItem; + } + + /** + * 构建机台节点的dirItem + */ + private BatchCreateDirItem buildMachineDirItem(SpdmProjectNodeEditReq machineNode, + String phaseUuid, + List workspaceNodes) { + BatchCreateDirItem machineCreateDirItem = new BatchCreateDirItem(); + DirNodeInfo machineDirNodeInfo = buildDirNodeInfo( + machineNode.getUuid(), phaseUuid, + NodeTypeEnum.MACHINE.getValue(), machineNode.getNodeName() + ); + machineCreateDirItem.setParentDirNodeInfo(machineDirNodeInfo); + + // 构建机台下的工位子节点 + List workspaceDirInfoList = buildDirNodeInfoList( + workspaceNodes.stream() + .filter(workspaceNode -> machineNode.getUuid().equals(workspaceNode.getPid())) + .collect(Collectors.toList()), + machineNode.getUuid(), NodeTypeEnum.WORKSPACE.getValue() + ); + machineCreateDirItem.setChildDirNodeInfos(workspaceDirInfoList); + + return machineCreateDirItem; + } + + /** + * 构建工位节点的dirItem + */ + private void buildWorkspaceDirItems(SpdmProjectNodeEditReq machineNode, + List currentWorkspaceNodes, + List createDirItemList) { + if (CollectionUtils.isEmpty(currentWorkspaceNodes)) { + return; + } + for (SpdmProjectNodeEditReq workspaceNode : currentWorkspaceNodes) { + BatchCreateDirItem workspaceCreateDirItem = new BatchCreateDirItem(); + DirNodeInfo workspaceDirNodeInfo = buildDirNodeInfo( + workspaceNode.getUuid(), machineNode.getUuid(), + NodeTypeEnum.WORKSPACE.getValue(), workspaceNode.getNodeName() + ); + workspaceCreateDirItem.setParentDirNodeInfo(workspaceDirNodeInfo); + workspaceCreateDirItem.setChildDirNodeInfos(new ArrayList<>()); + createDirItemList.add(workspaceCreateDirItem); + } + } + + /** + * 构建机台、工位的dirItem + */ + private void buildMachineWorkspaceDirItems(SpdmProjectNodeEditReq phaseNode, + List currentMachineNodes, + List workspaceNodes, + List createDirItemList) { + if (CollectionUtils.isEmpty(currentMachineNodes)) { + return; + } + for (SpdmProjectNodeEditReq machineNode : currentMachineNodes) { + // 构建机台节点的dirItem + BatchCreateDirItem machineCreateDirItem = buildMachineDirItem(machineNode, phaseNode.getUuid(), workspaceNodes); + createDirItemList.add(machineCreateDirItem); + // 筛选当前机台下的工位节点 + List currentWorkspaceNodes = workspaceNodes.stream() + .filter(workspaceNode -> machineNode.getUuid().equals(workspaceNode.getPid())) + .collect(Collectors.toList()); + // 构建工位节点的dirItem + buildWorkspaceDirItems(machineNode, currentWorkspaceNodes, createDirItemList); + } + } + + /** + * 构建阶段、机台、工位的层级dirItem + */ + private void buildPhaseMachineWorkspaceDirItems(NodeServiceImpl.NodeTypeFilterResult filterResult, List createDirItemList) { + SpdmProjectNodeEditReq projectNode = filterResult.getProjectNode(); + List phaseNodes = filterResult.getAddPhaseNodeList(); + List machineNodes = filterResult.getAddMachineNodeList(); + List workspaceNodes = filterResult.getAddWorkspaceNodeList(); + if (CollectionUtils.isEmpty(phaseNodes)) { + return; + } + for (SpdmProjectNodeEditReq phaseNode : phaseNodes) { + // 构建阶段节点的dirItem + BatchCreateDirItem phaseCreateDirItem = buildPhaseDirItem(phaseNode, projectNode.getUuid(), machineNodes); + createDirItemList.add(phaseCreateDirItem); + // 筛选当前阶段下的机台节点 + List currentMachineNodes = machineNodes.stream() + .filter(machineNode -> phaseNode.getUuid().equals(machineNode.getPid())) + .collect(Collectors.toList()); + // 构建机台、工位的dirItem + buildMachineWorkspaceDirItems(phaseNode, currentMachineNodes, workspaceNodes, createDirItemList); + } + } + + /** + * 构建批量创建文件夹请求 + */ + private BatchCreateDirReq buildBatchCreateDirReq(NodeServiceImpl.NodeTypeFilterResult filterResult) { + BatchCreateDirReq batchCreateDirReq = new BatchCreateDirReq(); + List createDirItemList = new ArrayList<>(); + // 构建项目节点的dirItem + buildProjectDirItem(filterResult, createDirItemList); + // 构建阶段、机台、工位的层级dirItem + buildPhaseMachineWorkspaceDirItems(filterResult, createDirItemList); + batchCreateDirReq.setItems(createDirItemList); + batchCreateDirReq.setDirType(DirTypeEnum.PROJECT_NODE_DIR.getValue()); + return batchCreateDirReq; + } + + /** + * 构建批量创建节点文件夹的参数并调用接口 + * @param addNodeList + */ + public void batchCreateNodeDir(List addNodeList) { + // 1. 分类筛选节点 + NodeServiceImpl.NodeTypeFilterResult filterResult = filterNodesByType(addNodeList); + // 2. 无项目节点时,仅创建单个阶段节点 + if (ObjectUtils.isEmpty(filterResult.getProjectNode())) { + createSinglePhaseDir(filterResult.getAddPhaseNodeList()); + return; + } + // 3. 有项目节点时,批量构建层级化文件夹创建请求 + BatchCreateDirReq batchCreateDirReq = buildBatchCreateDirReq(filterResult); + // 4. 调用批量创建接口并记录日志 + callBatchCreateDirApi(batchCreateDirReq); + // 项目下新增一层【项目文件】文件夹,项目文件Tab上传的文件都放到这个文件夹里 + // 5. 创建项目文件夹下【项目文件】层级文件夹 + BatchCreateNormalDirReq batchCreateNormalDirReq = new BatchCreateNormalDirReq(); + SpdmProjectNodeEditReq projectNode = filterResult.getProjectNode(); + batchCreateNormalDirReq.setParentUUId(projectNode.getUuid()); + List folderItemReqList = new ArrayList<>(); + FolderItemReq folderItemReq = new FolderItemReq(); + folderItemReq.setFolderName(AttachFileTypeEnum.PROJECT_FILE.getValue()); + folderItemReq.setFolderUuid(RandomUtil.generateString(32)); + folderItemReqList.add(folderItemReq); + batchCreateNormalDirReq.setFolderItems(folderItemReqList); + log.info("创建【项目文件】文件夹请求参数:{}", batchCreateNormalDirReq); + try { + SdmResponse response = dataFeignClient.batchCreateNormalDirs(batchCreateNormalDirReq); + log.info("创建【项目文件】文件夹响应:{}", response); + } catch (Exception e) { + log.error("创建【项目文件】文件夹接口失败", e); + } + } + + /** + * 调用批量创建文件夹接口并记录日志 + */ + private void callBatchCreateDirApi(BatchCreateDirReq batchCreateDirReq) { + log.info("创建节点时,调用批量创建文件夹的参数为:{}", batchCreateDirReq); + SdmResponse response = dataFeignClient.batchCreateDir(batchCreateDirReq); + log.info("创建节点时,调用批量创建文件夹的返回值为:{}", response); + } + + private void buildProjectForTodoInfo(LyricVProjectToDM lyricVProjectToDM, Long tenantId, Long jobNumber) { + String curDateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); + List currentNodeList; + List addNodeList = new ArrayList<>(); + // 构建项目——阶段——机台——工位节点树 + SpdmProjectNodeEditReq spdmProjectNodeEditReq = new SpdmProjectNodeEditReq(); + spdmProjectNodeEditReq.setUuid(RandomUtil.generateString(32)); + spdmProjectNodeEditReq.setNodeCode(lyricVProjectToDM.getProjectNum()); + spdmProjectNodeEditReq.setNodeName(lyricVProjectToDM.getProjectName()); + spdmProjectNodeEditReq.setNodeType(NodeTypeEnum.PROJECT.getValue()); + spdmProjectNodeEditReq.setPid(""); + spdmProjectNodeEditReq.setCreateTime(curDateStr); + spdmProjectNodeEditReq.setCreator(jobNumber); + spdmProjectNodeEditReq.setTenantId(tenantId); + spdmProjectNodeEditReq.setProjectSource(SYNC_PROJECT_SOURCE); + + // 根据projectId查询项目机台工位信息的视图 + List projectStationList = new ArrayList<>(); + try { + projectStationList = lyricVProjectStationToDmService.lambdaQuery() + .eq(LyricVProjectStationToDM::getProjectId, spdmProjectNodeEditReq.getProjectId()) + .list(); + } catch (MyBatisSystemException ex) { + // 查询发生异常,记录异常日志(可能是测试环境预期异常) + log.warn("查询项目机台工位信息的视图时发生异常(可能是测试环境预期异常),项目id:{},异常信息:{}", + spdmProjectNodeEditReq.getProjectId(), ex.getMessage()); + } + if (CollectionUtils.isNotEmpty(projectStationList)) { + // 同步EP中的节点、机台、工位到DM + // 查询当前阶段 + LyricVProjectToDM lyricVProject = null; + try { + lyricVProject = lyricVProjectToDmService.lambdaQuery() + .eq(LyricVProjectToDM::getProjectNum, spdmProjectNodeEditReq.getNodeCode()) + .one(); + } catch (MyBatisSystemException ex) { + // 查询发生异常,记录异常日志(可能是测试环境预期异常) + log.warn("查询当前阶段时发生异常(可能是测试环境预期异常),项目编码:{},异常信息:{}", + spdmProjectNodeEditReq.getProjectId(), ex.getMessage()); + } + + if (ObjectUtils.isNotEmpty(lyricVProject)) { + // 当前阶段 + String currentPhase = lyricVProject.getStage(); + SpdmProjectNodeEditReq phaseNode = new SpdmProjectNodeEditReq(); + phaseNode.setUuid(RandomUtil.generateString(32)); + phaseNode.setNodeCode(currentPhase); + phaseNode.setNodeName(currentPhase); + phaseNode.setNodeType(NodeTypeEnum.PHASE.getValue()); + phaseNode.setCreateTime(curDateStr); + phaseNode.setCreator(jobNumber); + phaseNode.setTenantId(tenantId); + phaseNode.setProjectSource(SYNC_PROJECT_SOURCE); + phaseNode.setPid(spdmProjectNodeEditReq.getUuid()); + addNodeList.add(phaseNode); + // 机台、工位 + Map> machineMap = projectStationList.stream().collect(Collectors.groupingBy(LyricVProjectStationToDM::getMachineNumber)); + for (Map.Entry> machineEntry : machineMap.entrySet()) { + String machineNumber = machineEntry.getKey(); + List projectStationByMachineNumberList = machineEntry.getValue(); + SpdmProjectNodeEditReq machineNode = new SpdmProjectNodeEditReq(); + machineNode.setUuid(RandomUtil.generateString(32)); + machineNode.setNodeCode(machineNumber); + machineNode.setNodeName(projectStationByMachineNumberList.get(0).getMachineName()); + machineNode.setNodeType(NodeTypeEnum.MACHINE.getValue()); + machineNode.setCreateTime(curDateStr); + machineNode.setCreator(jobNumber); + machineNode.setTenantId(tenantId); + machineNode.setProjectSource(SYNC_PROJECT_SOURCE); + machineNode.setPid(phaseNode.getUuid()); + addNodeList.add(machineNode); + for (LyricVProjectStationToDM lyricVProjectStationToDM : projectStationByMachineNumberList) { + SpdmProjectNodeEditReq workspaceNode = new SpdmProjectNodeEditReq(); + workspaceNode.setUuid(RandomUtil.generateString(32)); + workspaceNode.setNodeCode(lyricVProjectStationToDM.getStationNum()); + workspaceNode.setNodeName(lyricVProjectStationToDM.getStationName()); + workspaceNode.setNodeType(NodeTypeEnum.WORKSPACE.getValue()); + workspaceNode.setCreateTime(curDateStr); + workspaceNode.setCreator(jobNumber); + workspaceNode.setTenantId(tenantId); + workspaceNode.setProjectSource(SYNC_PROJECT_SOURCE); + workspaceNode.setPid(machineNode.getUuid()); + addNodeList.add(workspaceNode); + } + } + } + } + + List tagMap = new ArrayList<>(); + TaskNodeTag projectTaskNodeTag = new TaskNodeTag(); + projectTaskNodeTag.setKey(NodeTypeEnum.PROJECT.getValue()); + projectTaskNodeTag.setValue("tag1"); + TaskNodeTag phaseTaskNodeTag = new TaskNodeTag(); + phaseTaskNodeTag.setKey(NodeTypeEnum.PHASE.getValue()); + phaseTaskNodeTag.setValue("tag2"); + TaskNodeTag machineTaskNodeTag = new TaskNodeTag(); + machineTaskNodeTag.setKey(NodeTypeEnum.MACHINE.getValue()); + machineTaskNodeTag.setValue("tag4"); + TaskNodeTag workspaceTaskNodeTag = new TaskNodeTag(); + workspaceTaskNodeTag.setKey(NodeTypeEnum.WORKSPACE.getValue()); + workspaceTaskNodeTag.setValue("tag5"); + tagMap.add(projectTaskNodeTag); + tagMap.add(phaseTaskNodeTag); + tagMap.add(machineTaskNodeTag); + tagMap.add(workspaceTaskNodeTag); + for (TaskNodeTag tagReq : tagMap) { + String currentNodeType = tagReq.getKey(); // project phase + log.info("当前nodeType为:{},tag为:{}", currentNodeType, tagReq.getValue()); + currentNodeList = addNodeList.stream().filter(node -> node.getNodeType().equals(currentNodeType)).toList(); // projectNodeList phaseNodeList + if (CollectionUtils.isEmpty(currentNodeList)) { + log.error("addNodeList中不存在{}类型的节点", currentNodeType); + continue; + } + SpdmProjectNodeEditReq eachSpdmProjectNodeEditReq; + String tagListProperty; + for (SpdmProjectNodeEditReq addNode : currentNodeList) { + if (StringUtils.isBlank(addNode.getUuid())) { + addNode.setUuid(RandomUtil.generateString(32)); + } + String pid = addNode.getPid(); + if (StringUtils.isBlank(pid)) { + try { + // tagReq.getValue()="Tag1" + setTagProperty(addNode, tagReq.getValue(), addNode.getUuid()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + // 复制父节点的tag + eachSpdmProjectNodeEditReq = addNodeList.stream().filter(node -> pid.equals(node.getUuid())).findFirst().orElse(null); + if (ObjectUtils.isNotEmpty(eachSpdmProjectNodeEditReq)) { + for (int i = 1; i <= 10; i++) { + try { + tagListProperty = getTagProperty(eachSpdmProjectNodeEditReq, "tag" + i); + if (StringUtils.isBlank(tagListProperty)) { + continue; + } + setTagProperty(addNode, "tag" + i, tagListProperty); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + try { + // tagReq.getValue()="Tag1" + setTagProperty(addNode, tagReq.getValue(), addNode.getUuid()); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + // 设置 当前节点所属项目根节点uuid + // addNode.getPid()为空时,在创建项目,ownRootNodeUuid就是addNode本身uuid + // addNode.getPid()不为空时,在创建阶段,ownRootNodeUuid就是入参的pid父节点 + addNode.setOwnRootNodeUuid(ObjectUtils.isEmpty(addNode.getPid()) ? addNode.getUuid() : addNode.getPid()); + addNode.setCreateTime(curDateStr); + addNode.setCreator(jobNumber); + addNode.setTenantId(tenantId); + } + } + + if (nodeMapper.addNodeBatch(addNodeList) <= 0) { + return ; + } + + // 批量创建文件夹 + batchCreateNodeDir(addNodeList); + + // 批量更新权限 + List filePermissions = new ArrayList<>(); + for (SpdmProjectNodeEditReq addNode : addNodeList) { + BatchUpdatePermissionReq.FilePermissionItem item = new BatchUpdatePermissionReq.FilePermissionItem(); + item.setUuid(addNode.getUuid()); + Map userPermissions = new HashMap<>(); + // 2026-02-09 因为项目视图中没有项目经理,这里将项目创建人当成项目经理 + userPermissions.put(jobNumber, FilePermissionEnum.ALL.getValue()); + item.setUserPermissions(userPermissions); + filePermissions.add(item); + } + if (CollectionUtils.isNotEmpty(filePermissions)) { + BatchUpdatePermissionReq batchReq = new BatchUpdatePermissionReq(); + batchReq.setFilePermissions(filePermissions); + log.info("创建项目阶段时,批量更新权限,任务数量:{}", filePermissions.size()); + SdmResponse response = dataFeignClient.batchUpdatePermission(batchReq); + log.info("创建项目阶段时,批量更新权限结果:{}", response); + if (!response.isSuccess()) { + log.error("批量更新权限失败:{}", response.getMessage()); + } + } + + } + + + private SdmResponse handleRelatedProjectTodo(List projectNodeList, List relatedProjectVTodoEmulationInfoDMList) { + return httpSyncTodoData(projectNodeList, relatedProjectVTodoEmulationInfoDMList); + } + + + private SdmResponse httpSyncTodoData(List projectNodeList, List todoInfoList) { String traceId = MdcUtil.getTraceId(); CompletableFuture syncTodoDataFeature = CompletableFuture.supplyAsync(() -> - syncTodoData(projectNodeList, todoInfoList,traceId)); + syncTodoData(projectNodeList, todoInfoList, traceId)); try { SdmResponse sdmResponse = syncTodoDataFeature.get(syncTodoDataWaitSeconds, TimeUnit.SECONDS); return sdmResponse; } catch (InterruptedException e) { - log.error("同步异常终止:{}",e.getMessage()); + log.error("同步异常终止:{}", e.getMessage()); return SdmResponse.failed("同步异常终止"); } catch (ExecutionException e) { - log.error("同步执行错误:{}",e.getMessage()); + log.error("同步执行错误:{}", e.getMessage()); return SdmResponse.failed("同步执行出错误"); } catch (TimeoutException e) { - log.warn("同步执行超时:{}",e.getMessage()); + log.warn("同步执行超时:{}", e.getMessage()); return SdmResponse.success("同步执行中,请稍后"); - }catch (Exception e) { - log.error("同步未知错误:{}",e.getMessage()); + } catch (Exception e) { + log.error("同步未知错误:{}", e.getMessage()); return SdmResponse.failed("同步未知错误"); } } @@ -2085,12 +2722,13 @@ public class LyricInternalServiceImpl implements ILyricInternalService { * 查询未同步异常的任务列表 */ private List queryUnsyncedExceptionTasks(int fromIndex, int endIndex) { - return simulationTaskMapper.queryLyricHasNotSyncExceptionDatas(fromIndex,endIndex); + return simulationTaskMapper.queryLyricHasNotSyncExceptionDatas(fromIndex, endIndex); } /** * 构建标签对应的节点信息映射 - * @param tasks 任务列表 + * + * @param tasks 任务列表 * @param tagField 标签字段名(tag1/tag5) * @param nodeType 节点类型(project/workspace) */ @@ -2218,8 +2856,9 @@ public class LyricInternalServiceImpl implements ILyricInternalService { /** * 匹配两个集合,筛选符合条件的数据并封装为 LyricExceptionModel 列表 + * * @param exceptionList 异常信息列表 - * @param noSyncLists 没有同步的有异常的任务同步列表 + * @param noSyncLists 没有同步的有异常的任务同步列表 * @return 匹配后的异常模型列表 */ public List matchExceptionAndTask(List exceptionList, 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 85f7cdd9..0dc99a76 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 @@ -878,7 +878,7 @@ public class NodeServiceImpl extends ServiceImpl addPhaseNodeList; private final List addMachineNodeList; diff --git a/project/src/main/resources/application-local.yml b/project/src/main/resources/application-local.yml index 2472ce21..abbca104 100644 --- a/project/src/main/resources/application-local.yml +++ b/project/src/main/resources/application-local.yml @@ -188,4 +188,7 @@ xxl: # 通过标识判断是否走查询现场视图逻辑(0不查询,1查询) -lyricFlag : 0 \ No newline at end of file +lyricFlag : 0 + +# 同步待办时,查询待办的最大时间间隔,单位:天 +#lyricTodoInterval : 7 \ No newline at end of file diff --git a/project/src/main/resources/mapper/SimulationDemandMapper.xml b/project/src/main/resources/mapper/SimulationDemandMapper.xml index 901bb186..d8856c78 100644 --- a/project/src/main/resources/mapper/SimulationDemandMapper.xml +++ b/project/src/main/resources/mapper/SimulationDemandMapper.xml @@ -177,6 +177,10 @@ select * from simulation_demand where demandSource = 'EP' + +