@@ -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 < SimulationNode > projectNodeList ,
List < LyricVTodoEmulationInfoDM > todoInfoList , String traceId ) {
if ( StringUtils . isNotBlank ( traceId ) ) {
List < LyricVTodoEmulationInfoDM > 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 < SpdmDemandRelateMemberReq > 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 < Long , Byte > 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 > 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 < List < FileMetadataInfoResp > > 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 < FileMetadataInfoResp > 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 < FolderItemReq > 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 < BatchUpdatePermissionReq . FilePermissionItem > 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 < LyricVProjectToDM > 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 < Long , Byte > 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 < LyricVProjectResourcePlanDM > 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 < LyricVTodoEmulationInfoDM > queryTodoListWithFixedTime ( String startTime , String endTime ) {
// 查询原始待办数据
// TODO 这里要确认是不是只拉取有限元仿真
List < LyricVTodoEmulationInfoDM > 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 < String > existDemandCodeSet = demandMapper . getAllCodeList ( ) ;
if ( CollectionUtils . isEmpty ( existDemandCodeSet ) ) {
return todoInfoList ;
}
List < LyricVTodoEmulationInfoDM > 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 < SimulationNode > projectNodeList , List < LyricVTodoEmulationInfoDM > 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 < LyricVTodoEmulationInfoDM > lyricVTodoEmulationInfoDMList = queryTodoListWithFixedTime ( startTime , endTime ) ;
// 待办信息在系统中是否都已经存在
if ( CollectionUtils . isEmpty ( lyricVTodoEmulationInfoDMList ) ) {
log . info ( " lyricVTodoEmulationInfoDMList为空 " ) ;
return SdmResponse . success ( ) ;
}
log . info ( " 本次共同步待办:{}个 " , lyricVTodoEmulationInfoDMList . stream ( ) ) ;
// 根据待办关联的项目情况,分为关联的项目已在系统和关联的项目未在系统两部分数据
List < LyricVTodoEmulationInfoDM > noRelatedProjectVTodoEmulationInfoDMList ;
List < String > 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 < SimulationNode > projectNodeList = nodeService . lambdaQuery ( ) . in ( SimulationNode : : getNodeCode , projectCodeList ) . list ( ) ;
if ( CollectionUtils . isEmpty ( projectNodeList ) ) {
// 本次同步到的待办的关联项目都未在系统内
log . info ( " 本次同步到的待办的关联项目都未在系统内 " ) ;
noRelatedProjectVTodoEmulationInfoDMList = lyricVTodoEmulationInfoDMList ;
} else {
// 本次同步到的待办的关联项目有一部分已经在系统内
log . info ( " 本次同步到的待办的关联项目有一部分已经在系统内 " ) ;
List < String > 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 < LyricVTodoEmulationInfoDM > noRelatedProjectVTodoEmulationInfoDMList , Long tenantId , Long jobNumber ) {
CompletableFuture < SdmResponse > 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 < LyricVTodoEmulationInfoDM > noRelatedProjectVTodoEmulationInfoDMList , Long tenantId , Long jobNumber ) {
// 尝试获取锁(立即返回,不等待)
if ( ! syncTodoInfoProjectLock . tryLock ( ) ) {
return SdmResponse . success ( " 有数据同步任务(同步项目信息)正在执行中,请稍后再试 " ) ;
}
// 取项目视图、工位相关视图构建项目树信息(只同步当前阶段)
// 根据待办获取所有项目编号
try {
List < String > projectNumList = noRelatedProjectVTodoEmulationInfoDMList . stream ( ) . map ( LyricVTodoEmulationInfoDM : : getProject )
. filter ( StringUtils : : isNotBlank ) . distinct ( ) . toList ( ) ;
if ( CollectionUtils . isEmpty ( projectNumList ) ) {
log . info ( " projectNumList为空 " ) ;
return SdmResponse . success ( " projectNumList为空 " ) ;
}
// 根据项目编号查询项目视图获取项目信息
List < LyricVProjectToDM > 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 < SpdmProjectNodeEditReq > addNodeList ) {
SpdmProjectNodeEditReq projectNode = addNodeList . stream ( )
. filter ( node - > NodeTypeEnum . PROJECT . getValue ( ) . equals ( node . getNodeType ( ) ) )
. findFirst ( )
. orElse ( null ) ;
List < SpdmProjectNodeEditReq > phaseNodes = addNodeList . stream ( )
. filter ( node - > NodeTypeEnum . PHASE . getValue ( ) . equals ( node . getNodeType ( ) ) )
. collect ( Collectors . toList ( ) ) ;
List < SpdmProjectNodeEditReq > machineNodes = addNodeList . stream ( )
. filter ( node - > NodeTypeEnum . MACHINE . getValue ( ) . equals ( node . getNodeType ( ) ) )
. collect ( Collectors . toList ( ) ) ;
List < SpdmProjectNodeEditReq > 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 < SpdmProjectNodeEditReq > 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 < DirNodeInfo > buildDirNodeInfoList ( List < SpdmProjectNodeEditReq > 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 < BatchCreateDirItem > createDirItemList ) {
SpdmProjectNodeEditReq projectNode = filterResult . getProjectNode ( ) ;
List < SpdmProjectNodeEditReq > phaseNodes = filterResult . getAddPhaseNodeList ( ) ;
BatchCreateDirItem projectCreateDirItem = new BatchCreateDirItem ( ) ;
DirNodeInfo projectDirNodeInfo = buildDirNodeInfo (
projectNode . getUuid ( ) , null ,
NodeTypeEnum . PROJECT . getValue ( ) , projectNode . getNodeName ( )
) ;
projectCreateDirItem . setParentDirNodeInfo ( projectDirNodeInfo ) ;
// 构建项目下的阶段子节点
List < DirNodeInfo > phaseDirInfoList = buildDirNodeInfoList (
phaseNodes , projectNode . getUuid ( ) , NodeTypeEnum . PHASE . getValue ( )
) ;
projectCreateDirItem . setChildDirNodeInfos ( phaseDirInfoList ) ;
createDirItemList . add ( projectCreateDirItem ) ;
}
/**
* 构建阶段节点的dirItem
*/
private BatchCreateDirItem buildPhaseDirItem ( SpdmProjectNodeEditReq phaseNode , String projectUuid , List < SpdmProjectNodeEditReq > machineNodes ) {
BatchCreateDirItem phaseCreateDirItem = new BatchCreateDirItem ( ) ;
DirNodeInfo phaseDirNodeInfo = buildDirNodeInfo (
phaseNode . getUuid ( ) , projectUuid ,
NodeTypeEnum . PHASE . getValue ( ) , phaseNode . getNodeName ( )
) ;
phaseCreateDirItem . setParentDirNodeInfo ( phaseDirNodeInfo ) ;
// 若无机台节点,子节点为空
List < DirNodeInfo > 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 < SpdmProjectNodeEditReq > workspaceNodes ) {
BatchCreateDirItem machineCreateDirItem = new BatchCreateDirItem ( ) ;
DirNodeInfo machineDirNodeInfo = buildDirNodeInfo (
machineNode . getUuid ( ) , phaseUuid ,
NodeTypeEnum . MACHINE . getValue ( ) , machineNode . getNodeName ( )
) ;
machineCreateDirItem . setParentDirNodeInfo ( machineDirNodeInfo ) ;
// 构建机台下的工位子节点
List < DirNodeInfo > 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 < SpdmProjectNodeEditReq > currentWorkspaceNodes ,
List < BatchCreateDirItem > 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 < SpdmProjectNodeEditReq > currentMachineNodes ,
List < SpdmProjectNodeEditReq > workspaceNodes ,
List < BatchCreateDirItem > createDirItemList ) {
if ( CollectionUtils . isEmpty ( currentMachineNodes ) ) {
return ;
}
for ( SpdmProjectNodeEditReq machineNode : currentMachineNodes ) {
// 构建机台节点的dirItem
BatchCreateDirItem machineCreateDirItem = buildMachineDirItem ( machineNode , phaseNode . getUuid ( ) , workspaceNodes ) ;
createDirItemList . add ( machineCreateDirItem ) ;
// 筛选当前机台下的工位节点
List < SpdmProjectNodeEditReq > 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 < BatchCreateDirItem > createDirItemList ) {
SpdmProjectNodeEditReq projectNode = filterResult . getProjectNode ( ) ;
List < SpdmProjectNodeEditReq > phaseNodes = filterResult . getAddPhaseNodeList ( ) ;
List < SpdmProjectNodeEditReq > machineNodes = filterResult . getAddMachineNodeList ( ) ;
List < SpdmProjectNodeEditReq > workspaceNodes = filterResult . getAddWorkspaceNodeList ( ) ;
if ( CollectionUtils . isEmpty ( phaseNodes ) ) {
return ;
}
for ( SpdmProjectNodeEditReq phaseNode : phaseNodes ) {
// 构建阶段节点的dirItem
BatchCreateDirItem phaseCreateDirItem = buildPhaseDirItem ( phaseNode , projectNode . getUuid ( ) , machineNodes ) ;
createDirItemList . add ( phaseCreateDirItem ) ;
// 筛选当前阶段下的机台节点
List < SpdmProjectNodeEditReq > 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 < BatchCreateDirItem > 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 < SpdmProjectNodeEditReq > 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 < FolderItemReq > 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 < SpdmProjectNodeEditReq > currentNodeList ;
List < SpdmProjectNodeEditReq > 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 < LyricVProjectStationToDM > 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 < String , List < LyricVProjectStationToDM > > machineMap = projectStationList . stream ( ) . collect ( Collectors . groupingBy ( LyricVProjectStationToDM : : getMachineNumber ) ) ;
for ( Map . Entry < String , List < LyricVProjectStationToDM > > machineEntry : machineMap . entrySet ( ) ) {
String machineNumber = machineEntry . getKey ( ) ;
List < LyricVProjectStationToDM > 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 < TaskNodeTag > 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 < BatchUpdatePermissionReq . FilePermissionItem > filePermissions = new ArrayList < > ( ) ;
for ( SpdmProjectNodeEditReq addNode : addNodeList ) {
BatchUpdatePermissionReq . FilePermissionItem item = new BatchUpdatePermissionReq . FilePermissionItem ( ) ;
item . setUuid ( addNode . getUuid ( ) ) ;
Map < Long , Byte > 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 < SimulationNode > projectNodeList , List < LyricVTodoEmulationInfoDM > relatedProjectVTodoEmulationInfoDMList ) {
return httpSyncTodoData ( projectNodeList , relatedProjectVTodoEmulationInfoDMList ) ;
}
private SdmResponse httpSyncTodoData ( List < SimulationNode > projectNodeList , List < LyricVTodoEmulationInfoDM > todoInfoList ) {
String traceId = MdcUtil . getTraceId ( ) ;
CompletableFuture < SdmResponse > 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 < SimulationTaskSyncExBo > 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 < LyricExceptionModel > matchExceptionAndTask ( List < LyricVProjectStationExcepTionToDM > exceptionList ,