@@ -2,16 +2,15 @@ package com.sdm.data.service.impl;
import com.alibaba.fastjson2.JSONObject ;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper ;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction ;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper ;
import com.github.pagehelper.PageInfo ;
import com.sdm.common.common.SdmResponse ;
import com.sdm.common.common.ThreadLocalContext ;
import com.sdm.common.entity.enums.DataTypeEnum ;
import com.sdm.common.entity.enums.DirTypeEnum ;
import com.sdm.common.entity.enums.NodeTypeEnum ;
import com.sdm.common.entity.req.data.CreateDirReq ;
import com.sdm.common.entity.req.data.DelDirReq ;
import com.sdm.common.entity.req.data.DelFileReq ;
import com.sdm.common.entity.req.data.UploadFilesReq ;
import com.sdm.common.entity.req.data.* ;
import com.sdm.common.entity.req.project.DelNodeReq ;
import com.sdm.common.entity.req.project.GetAllNodeByNodeTypeReq ;
import com.sdm.common.entity.req.project.GetTaskDetailReq ;
@@ -300,15 +299,16 @@ public class DimensionTemplateServiceImpl extends ServiceImpl<DimensionTemplateM
if ( CollectionUtils . isNotEmpty ( nextLevelUuids ) ) {
uuids . addAll ( nextLevelUuids ) ;
}
// 3、获取当前节点下的任务( 仅展示“应挂载在当前层”的任务, 避免任务提前出现在上层)
List < List < String > > displayTagLevels = buildDisplayTagLevels ( dimensionNodeTypeLevels ) ;
List < String > taskUuids = getTaskByTagReq ( req . getTagReq ( ) , displayTagLevels , currentLevelIndex ) ;
uuids . addAll ( taskUuids ) ;
log . info ( " 获取节点下task的uudis:{} " , taskUuids ) ;
}
// 3 、获取当前节点下的任务、 算列
SdmResponse < List < AllNodeByProjectIdAndTypeResp > > nodeTaskList = simuluationNodeFeignClient . getNodeTaskList ( chooseUuids ) ;
if ( nodeTaskList . isSuccess ( ) ) {
uuids . addAll ( nodeTaskList . getData ( ) . stream ( ) . map ( AllNodeByProjectIdAndTypeResp : : getUuid ) . toList ( ) ) ;
log . info ( " 获取节点下task的uudis:{} " , uuids ) ;
}
// 4 、获取任务下的 算列
SdmResponse < List < AllNodeByProjectIdAndTypeResp > > taskRunList = simuluationNodeFeignClient . getTaskRunList ( chooseUuids ) ;
if ( taskRunList . isSuccess ( ) ) {
uuids . addAll ( taskRunList . getData ( ) . stream ( ) . map ( AllNodeByProjectIdAndTypeResp : : getUuid ) . toList ( ) ) ;
@@ -336,6 +336,149 @@ public class DimensionTemplateServiceImpl extends ServiceImpl<DimensionTemplateM
return SdmResponse . success ( mergedResult ) ;
}
private List < String > getTaskByTagReq ( TagReq tagReq , List < List < String > > displayTagLevels , int currentLevelIndex ) {
LambdaQueryChainWrapper < FileMetadataInfo > wrapper = new LambdaQueryChainWrapper < > ( fileMetadataInfoService . getBaseMapper ( ) ) ;
// 查task
wrapper . eq ( FileMetadataInfo : : getRelatedResourceUuidOwnType , NodeTypeEnum . TASK . getValue ( ) ) ;
// tag1-tag10 可能是逗号拼接链,按完整 token 命中
if ( ObjectUtils . isNotEmpty ( tagReq ) ) {
inByCurrentLevelCsv ( wrapper , FileMetadataInfo : : getTag1 , tagReq . getTag1 ( ) ) ;
inByCurrentLevelCsv ( wrapper , FileMetadataInfo : : getTag2 , tagReq . getTag2 ( ) ) ;
inByCurrentLevelCsv ( wrapper , FileMetadataInfo : : getTag3 , tagReq . getTag3 ( ) ) ;
inByCurrentLevelCsv ( wrapper , FileMetadataInfo : : getTag4 , tagReq . getTag4 ( ) ) ;
inByCurrentLevelCsv ( wrapper , FileMetadataInfo : : getTag5 , tagReq . getTag5 ( ) ) ;
inByCurrentLevelCsv ( wrapper , FileMetadataInfo : : getTag6 , tagReq . getTag6 ( ) ) ;
inByCurrentLevelCsv ( wrapper , FileMetadataInfo : : getTag7 , tagReq . getTag7 ( ) ) ;
inByCurrentLevelCsv ( wrapper , FileMetadataInfo : : getTag8 , tagReq . getTag8 ( ) ) ;
inByCurrentLevelCsv ( wrapper , FileMetadataInfo : : getTag9 , tagReq . getTag9 ( ) ) ;
inByCurrentLevelCsv ( wrapper , FileMetadataInfo : : getTag10 , tagReq . getTag10 ( ) ) ;
}
List < FileMetadataInfo > taskInfos = wrapper . list ( ) ;
if ( CollectionUtils . isEmpty ( taskInfos ) ) {
return Collections . emptyList ( ) ;
}
// 仅展示“应挂在当前展开层级”的任务:
// deepestMatchedLevel == currentLevelIndex 时才展示,避免任务提前出现在上层。
return taskInfos . stream ( )
. filter ( task - > getDeepestMatchedLevel ( task , displayTagLevels ) = = currentLevelIndex )
. sorted ( Comparator
. comparing ( FileMetadataInfo : : getCreateTime , Comparator . nullsLast ( LocalDateTime : : compareTo ) ) . reversed ( )
. thenComparing ( FileMetadataInfo : : getOriginalName , Comparator . nullsLast ( String : : compareTo ) )
. thenComparing ( FileMetadataInfo : : getId , Comparator . nullsLast ( Long : : compareTo ) ) )
. map ( FileMetadataInfo : : getRelatedResourceUuid )
. filter ( StringUtils : : isNotBlank )
. distinct ( )
. toList ( ) ;
}
/**
* tag 字段可能存为 "a,b,c"。
* 只查询当前节点下的任务, 对于连续的节点类型, 机台1下又是机台2的展示, 机台1的任务只能挂机台1下, 机台2的任务只能挂机台2下展示
* 连续的机台一定会在数据总览中展开的, 所以不存在只有机台1, 没有机台2的情况, 这时候不需要考虑如果机台2不存在, 任务2需要挂在机台1下展示
* 1) column = v
* 3) column LIKE '%,v' (结尾)
*/
private < R > void inByCurrentLevelCsv ( LambdaQueryChainWrapper < FileMetadataInfo > wrapper ,
SFunction < FileMetadataInfo , R > column ,
String csvValue ) {
List < String > values = parseCsv ( csvValue ) ;
if ( CollectionUtils . isEmpty ( values ) ) {
return ;
}
wrapper . and ( q - > {
for ( int i = 0 ; i < values . size ( ) ; i + + ) {
String value = values . get ( i ) ;
if ( i > 0 ) {
q . or ( ) ;
}
q . eq ( column , value ) . or ( ) . likeLeft ( column , " , " + value ) ;
}
} ) ;
}
private List < String > parseCsv ( String value ) {
if ( StringUtils . isBlank ( value ) ) {
return Collections . emptyList ( ) ;
}
return Arrays . stream ( value . split ( " , " ) )
. map ( String : : trim )
. filter ( StringUtils : : isNotBlank )
. distinct ( )
. toList ( ) ;
}
/**
* 将展示维度节点类型顺序映射为 tag 顺序( 如: tag1-tag2-tag4-tag3)
* 一层个可能是展示多个tag (tag1-tag2+tag3-tag4)
*/
private List < List < String > > buildDisplayTagLevels ( List < List < String > > dimensionNodeTypeLevels ) {
if ( CollectionUtils . isEmpty ( dimensionNodeTypeLevels ) ) {
return Collections . emptyList ( ) ;
}
Map < String , String > nodeTypeToTagMap = tagMapService . getTagMapName ( ) ;
List < List < String > > displayTagLevels = new ArrayList < > ( ) ;
for ( List < String > levelNodeTypes : dimensionNodeTypeLevels ) {
if ( CollectionUtils . isEmpty ( levelNodeTypes ) ) {
continue ;
}
List < String > levelTags = levelNodeTypes . stream ( )
. map ( nodeTypeToTagMap : : get )
. filter ( StringUtils : : isNotBlank )
. distinct ( )
. toList ( ) ;
if ( CollectionUtils . isNotEmpty ( levelTags ) ) {
displayTagLevels . add ( levelTags ) ;
}
}
return displayTagLevels ;
}
/**
* 计算任务在当前展示顺序下可命中的最深层级。
* 命中规则: 从上往下逐层判断, 该层任一tag命中即可继续; 首次不命中即停止。
* 返回:最后命中层级索引;无命中返回 -1。
*/
private int getDeepestMatchedLevel ( FileMetadataInfo task , List < List < String > > displayTagLevels ) {
if ( task = = null | | CollectionUtils . isEmpty ( displayTagLevels ) ) {
return - 1 ;
}
int deepestLevel = - 1 ;
for ( int level = 0 ; level < displayTagLevels . size ( ) ; level + + ) {
List < String > levelTags = displayTagLevels . get ( level ) ;
boolean levelMatched = CollectionUtils . isNotEmpty ( levelTags ) & & levelTags . stream ( ) . anyMatch ( tagKey - >
CollectionUtils . isNotEmpty ( parseCsv ( getTagValueByKey ( task , tagKey ) ) )
) ;
if ( ! levelMatched ) {
break ;
}
deepestLevel = level ;
}
return deepestLevel ;
}
private String getTagValueByKey ( FileMetadataInfo task , String tagKey ) {
if ( task = = null | | StringUtils . isBlank ( tagKey ) ) {
return null ;
}
return switch ( tagKey ) {
case " tag1 " - > task . getTag1 ( ) ;
case " tag2 " - > task . getTag2 ( ) ;
case " tag3 " - > task . getTag3 ( ) ;
case " tag4 " - > task . getTag4 ( ) ;
case " tag5 " - > task . getTag5 ( ) ;
case " tag6 " - > task . getTag6 ( ) ;
case " tag7 " - > task . getTag7 ( ) ;
case " tag8 " - > task . getTag8 ( ) ;
case " tag9 " - > task . getTag9 ( ) ;
case " tag10 " - > task . getTag10 ( ) ;
default - > null ;
} ;
}
/**
* 递归获取维度模板中指定节点的下一层级子节点UUID。
* <p>
@@ -776,6 +919,7 @@ public class DimensionTemplateServiceImpl extends ServiceImpl<DimensionTemplateM
GetSimulationNodeTreeReq getSimulationNodeTreeReq = new GetSimulationNodeTreeReq ( ) ;
getSimulationNodeTreeReq . setDimensionTemplateId ( req . getDimensionTemplateId ( ) ) ;
getSimulationNodeTreeReq . setFileIds ( null ) ;
getSimulationNodeTreeReq . setTagReq ( req . getTagReq ( ) ) ;
SdmResponse < List < FileMetadataChildrenDTO > > nodeDirInfos = getSimulationNodeTree ( getSimulationNodeTreeReq ) ;
List < Long > dirInfos = extractDirIdsFromResponse ( nodeDirInfos ) ;
@@ -790,6 +934,7 @@ public class DimensionTemplateServiceImpl extends ServiceImpl<DimensionTemplateM
GetSimulationNodeTreeReq getSimulationNodeTreeReq = new GetSimulationNodeTreeReq ( ) ;
getSimulationNodeTreeReq . setDimensionTemplateId ( req . getDimensionTemplateId ( ) ) ;
getSimulationNodeTreeReq . setFileIds ( req . getFileIds ( ) ) ;
getSimulationNodeTreeReq . setTagReq ( req . getTagReq ( ) ) ;
SdmResponse < List < FileMetadataChildrenDTO > > nodeDirInfos = getSimulationNodeTree ( getSimulationNodeTreeReq ) ;
List < Long > dirInfos = extractDirIdsFromResponse ( nodeDirInfos ) ;