移除学科节点,优化学科存储统计
This commit is contained in:
@@ -4,7 +4,6 @@ import com.alibaba.fastjson2.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.entity.enums.NodeTypeEnum;
|
||||
import com.sdm.common.entity.req.project.GetAllTasksByDisciplineReq;
|
||||
import com.sdm.common.entity.resp.PageDataResp;
|
||||
import com.sdm.common.feign.inter.project.ISimulationTaskFeignClient;
|
||||
@@ -23,7 +22,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -50,39 +48,29 @@ public class DataStorageAnalysisController {
|
||||
* 查询项目存储空间占用:项目Uuid+项目queryNodeType
|
||||
* 查询学科存储空间占用:学科字典名:MVH+学科queryNodeType
|
||||
*
|
||||
* @param queryNodeType 需要统计的节点类型
|
||||
* @param queryNodeNames 节点名称
|
||||
* @param queryNodeType 需要统计的节点类型
|
||||
* @param queryNodeNames 节点名称列表
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getNodeSizeByNodeType")
|
||||
@Operation(summary = "根据nodeId(项目nodeId)获取指定查询类型(queryNodeType)文件空间占用")
|
||||
public SdmResponse getNodeSizeByNodeType(
|
||||
@Parameter(description = "查询节点类型:project,discipline") @RequestParam(value = "queryNodeType", required = false) String queryNodeType,
|
||||
@Parameter(description = "查询节点类型:project") @RequestParam(value = "queryNodeType", required = false) String queryNodeType,
|
||||
@Parameter(description = "节点名称") @RequestParam(value = "queryNodeNames", required = false) List<String> queryNodeNames,
|
||||
@Parameter(description = "查询时间间隔(月)") @RequestParam(value = "intervalMonths", required = false) Integer intervalMonths,
|
||||
@Parameter(description = "增量查询指定的月:2025-06") @RequestParam(value = "targetYm", required = false) String targetYm
|
||||
) {
|
||||
|
||||
if (ObjectUtils.isEmpty(queryNodeType)) {
|
||||
return SdmResponse.success();
|
||||
}
|
||||
List<List<JSONObject>> result = new ArrayList<>();
|
||||
if(CollectionUtils.isEmpty(queryNodeNames)){
|
||||
|
||||
// 如果未指定节点名称,获取默认的top10
|
||||
if (CollectionUtils.isEmpty(queryNodeNames)) {
|
||||
queryNodeNames = fileStorageService.getdefaultNodeSizeUUID(queryNodeType, 10);
|
||||
}
|
||||
|
||||
for (String queryNodeName : queryNodeNames) {
|
||||
try {
|
||||
SdmResponse<List<JSONObject>> sdmResponse = dataStorageAnalysis.getNodeSizeByNodeType(queryNodeType, queryNodeName, intervalMonths, targetYm);
|
||||
if (CollectionUtils.isNotEmpty(sdmResponse.getData())) {
|
||||
result.add(sdmResponse.getData());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("获取文件空间占用失败", e);
|
||||
}
|
||||
}
|
||||
return SdmResponse.success(result);
|
||||
|
||||
// 直接调用批量查询接口
|
||||
return dataStorageAnalysis.getNodeSizeByNodeType(queryNodeType, queryNodeNames, intervalMonths, targetYm);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,7 +88,7 @@ public class DataStorageAnalysisController {
|
||||
return SdmResponse.success(new ArrayList<>());
|
||||
}
|
||||
|
||||
// 1. 调用feign获取每个学科对应的任务名称列表
|
||||
// 1. 调用feign获取每个学科对应的任务UUID列表
|
||||
GetAllTasksByDisciplineReq req = new GetAllTasksByDisciplineReq();
|
||||
req.setDisciplines(disciplines);
|
||||
SdmResponse<Map<String, List<String>>> disciplineTasksResponse = simulationTaskFeignClient.getAllTasksByDiscipline(req);
|
||||
@@ -110,84 +98,9 @@ public class DataStorageAnalysisController {
|
||||
return SdmResponse.success(new ArrayList<>());
|
||||
}
|
||||
|
||||
Map<String, List<String>> discipline2TaskNames = disciplineTasksResponse.getData();
|
||||
|
||||
// 2. 对每个学科,汇总其下所有任务的存储空间
|
||||
List<JSONObject> result = new ArrayList<>();
|
||||
for (Map.Entry<String, List<String>> entry : discipline2TaskNames.entrySet()) {
|
||||
String discipline = entry.getKey();
|
||||
List<String> taskNames = entry.getValue();
|
||||
|
||||
if (CollectionUtils.isEmpty(taskNames)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
JSONObject disciplineSize = calculateDisciplineSize(discipline, taskNames, intervalMonths, targetYm);
|
||||
if (disciplineSize != null) {
|
||||
result.add(disciplineSize);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("获取学科[{}]存储空间占用失败", discipline, e);
|
||||
}
|
||||
}
|
||||
|
||||
return SdmResponse.success(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算单个学科的存储空间占用(汇总该学科下所有任务的存储空间)
|
||||
*/
|
||||
private JSONObject calculateDisciplineSize(String discipline, List<String> taskNames,
|
||||
Integer intervalMonths, String targetYm) {
|
||||
BigDecimal totalSize = BigDecimal.ZERO;
|
||||
BigDecimal beforeSize = BigDecimal.ZERO;
|
||||
BigDecimal incrementSize = BigDecimal.ZERO;
|
||||
|
||||
for (String taskName : taskNames) {
|
||||
try {
|
||||
SdmResponse<List<JSONObject>> sdmResponse = dataStorageAnalysis.getNodeSizeByNodeType(
|
||||
NodeTypeEnum.TASK.getValue(), taskName, intervalMonths, targetYm);
|
||||
|
||||
if (!sdmResponse.isSuccess() || CollectionUtils.isEmpty(sdmResponse.getData())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 汇总每个task的存储空间
|
||||
for (JSONObject taskSize : sdmResponse.getData()) {
|
||||
if (ObjectUtils.isNotEmpty(intervalMonths)) {
|
||||
// 近几个月模式:汇总totalSize
|
||||
Object sizeObj = taskSize.get("totalSize");
|
||||
if (sizeObj != null) {
|
||||
totalSize = totalSize.add(new BigDecimal(sizeObj.toString()));
|
||||
}
|
||||
} else if (ObjectUtils.isNotEmpty(targetYm)) {
|
||||
// 增量查询模式:汇总BEFORE和INCREMENT
|
||||
Object beforeObj = taskSize.get("BEFORE");
|
||||
Object incrementObj = taskSize.get("INCREMENT");
|
||||
if (beforeObj != null) {
|
||||
beforeSize = beforeSize.add(new BigDecimal(beforeObj.toString()));
|
||||
}
|
||||
if (incrementObj != null) {
|
||||
incrementSize = incrementSize.add(new BigDecimal(incrementObj.toString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("获取任务[{}]存储空间失败", taskName, e);
|
||||
}
|
||||
}
|
||||
|
||||
// 构建返回结果
|
||||
JSONObject result = new JSONObject();
|
||||
result.put("nodeName", discipline);
|
||||
if (ObjectUtils.isNotEmpty(intervalMonths)) {
|
||||
result.put("totalSize", totalSize);
|
||||
} else if (ObjectUtils.isNotEmpty(targetYm)) {
|
||||
result.put("BEFORE", beforeSize);
|
||||
result.put("INCREMENT", incrementSize);
|
||||
}
|
||||
return result;
|
||||
// 2. 调用Service层批量计算
|
||||
Map<String, List<String>> discipline2TaskUuids = disciplineTasksResponse.getData();
|
||||
return dataStorageAnalysis.getNodeSizeByDiscipline(discipline2TaskUuids, intervalMonths, targetYm);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,18 +11,30 @@ import com.sdm.data.model.req.QueryBigFileReq;
|
||||
import com.sdm.data.model.resp.ListBigFileResp;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface DataStorageAnalysis {
|
||||
/**
|
||||
* 根据类型获取文件空间占用
|
||||
* 根据类型获取文件空间占用(支持批量查询)
|
||||
*
|
||||
* @param queryNodeType 节点类型(project,discipline)
|
||||
* @param queryNodeName 节点id
|
||||
* @param intervalMonths 查询时间间隔(月)
|
||||
* @param targetYm 增量查询指定的月:2025-06
|
||||
* @return 文件总大小(字节)
|
||||
* @param queryNodeType 节点类型(project,task等)
|
||||
* @param queryNodeNames 节点名称列表
|
||||
* @param intervalMonths 查询时间间隔(月)
|
||||
* @param targetYm 增量查询指定的月:2025-06
|
||||
* @return 文件总大小
|
||||
*/
|
||||
SdmResponse<List<JSONObject>> getNodeSizeByNodeType(String queryNodeType, String queryNodeName, Integer intervalMonths, String targetYm);
|
||||
SdmResponse<List<JSONObject>> getNodeSizeByNodeType(String queryNodeType, List<String> queryNodeNames, Integer intervalMonths, String targetYm);
|
||||
|
||||
/**
|
||||
* 根据学科获取存储空间占用
|
||||
* 学科是Task节点的属性,通过task UUID精确匹配,避免不同学科下同名task的混淆
|
||||
*
|
||||
* @param discipline2TaskUuids 学科 -> 任务UUID列表的映射
|
||||
* @param intervalMonths 查询时间间隔(月)
|
||||
* @param targetYm 增量查询指定的月:2025-06
|
||||
* @return 学科存储空间列表
|
||||
*/
|
||||
SdmResponse<List<JSONObject>> getNodeSizeByDiscipline(Map<String, List<String>> discipline2TaskUuids, Integer intervalMonths, String targetYm);
|
||||
|
||||
/**
|
||||
* 根据用户id获取用户的空间占用
|
||||
|
||||
@@ -67,116 +67,290 @@ public class DataStorageAnalysisImpl implements DataStorageAnalysis {
|
||||
@Autowired
|
||||
FileMetadataHierarchyHelper hierarchyHelper;
|
||||
|
||||
public SdmResponse<List<JSONObject>> getNodeSizeByNodeType(String queryNodeType, String queryNodeName, Integer intervalMonths, String targetYm) {
|
||||
// uuid是项目的uuid
|
||||
List<FileMetadataInfo> nodeList = fileMetadataInfoService.lambdaQuery()
|
||||
.eq(FileMetadataInfo::getRelatedResourceUuidOwnType, queryNodeType)
|
||||
.eq(FileMetadataInfo::getOriginalName, queryNodeName)
|
||||
.list();
|
||||
|
||||
if (ObjectUtils.isEmpty(nodeList)) {
|
||||
log.error("获取节点信息失败,节点类型: {}, 标识符: {}", queryNodeType, queryNodeName);
|
||||
return getEmptyNodeSize(queryNodeName,intervalMonths,targetYm);
|
||||
/**
|
||||
* 根据节点类型获取存储空间占用(支持批量查询)
|
||||
*/
|
||||
@Override
|
||||
public SdmResponse<List<JSONObject>> getNodeSizeByNodeType(String queryNodeType, List<String> queryNodeNames,
|
||||
Integer intervalMonths, String targetYm) {
|
||||
if (CollectionUtils.isEmpty(queryNodeNames)) {
|
||||
return SdmResponse.success(buildEmptyResults(Collections.emptySet(), intervalMonths, targetYm));
|
||||
}
|
||||
|
||||
// 1. 批量查询所有节点信息
|
||||
List<FileMetadataInfo> nodeList = queryNodeListBatch(queryNodeType, queryNodeNames);
|
||||
|
||||
// 2. 构建 nodeName -> dirIds 的映射
|
||||
Map<String, List<Long>> nodeNameToDirIdsMap = buildNodeNameToDirIdsMap(nodeList);
|
||||
|
||||
// 3. 调用核心计算方法,传入所有 queryNodeNames 以确保无数据的节点也返回空结果
|
||||
return calculateGroupedStorageSize(nodeNameToDirIdsMap, queryNodeNames, intervalMonths, targetYm);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据学科获取存储空间占用
|
||||
* 学科是Task节点的属性,通过task UUID精确匹配,避免不同学科下同名task的混淆
|
||||
*/
|
||||
@Override
|
||||
public SdmResponse<List<JSONObject>> getNodeSizeByDiscipline(Map<String, List<String>> discipline2TaskUuids,
|
||||
Integer intervalMonths, String targetYm) {
|
||||
if (discipline2TaskUuids == null || discipline2TaskUuids.isEmpty()) {
|
||||
return SdmResponse.success(buildEmptyResults(Collections.emptySet(), intervalMonths, targetYm));
|
||||
}
|
||||
|
||||
// 1. 收集所有task UUID(去重)
|
||||
Set<String> allTaskUuids = discipline2TaskUuids.values().stream()
|
||||
.flatMap(List::stream)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 2. 根据UUID批量查询Task节点信息,获取 uuid -> dirId 的映射
|
||||
Map<String, Long> uuidToDirIdMap = queryDirIdsByUuids(new ArrayList<>(allTaskUuids));
|
||||
|
||||
// 3. 构建 discipline -> dirIds 的映射
|
||||
Map<String, List<Long>> disciplineToDirIdsMap = new HashMap<>();
|
||||
for (Map.Entry<String, List<String>> entry : discipline2TaskUuids.entrySet()) {
|
||||
String discipline = entry.getKey();
|
||||
List<Long> dirIds = entry.getValue().stream()
|
||||
.map(uuidToDirIdMap::get)
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
disciplineToDirIdsMap.put(discipline, dirIds);
|
||||
}
|
||||
|
||||
// 4. 调用核心计算方法,统一返回格式(即使无数据也返回带结构的空结果)
|
||||
return calculateGroupedStorageSize(disciplineToDirIdsMap, new ArrayList<>(discipline2TaskUuids.keySet()), intervalMonths, targetYm);
|
||||
}
|
||||
|
||||
// ==================== 核心计算方法 ====================
|
||||
|
||||
/**
|
||||
* 核心方法:根据分组名称到dirIds的映射计算存储空间
|
||||
*
|
||||
* @param groupNameToDirIdsMap 分组名称 -> dirId列表的映射
|
||||
* @param allGroupNames 所有需要返回结果的分组名称(包含无数据的)
|
||||
* @param intervalMonths 近几个月模式
|
||||
* @param targetYm 增量查询模式
|
||||
*/
|
||||
private SdmResponse<List<JSONObject>> calculateGroupedStorageSize(
|
||||
Map<String, List<Long>> groupNameToDirIdsMap,
|
||||
List<String> allGroupNames,
|
||||
Integer intervalMonths,
|
||||
String targetYm) {
|
||||
|
||||
// 收集所有有效的dirIds
|
||||
List<Long> allDirIds = groupNameToDirIdsMap.values().stream()
|
||||
.flatMap(List::stream)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 查询存储空间统计数据
|
||||
Long tenantId = ThreadLocalContext.getTenantId();
|
||||
|
||||
//将 nodeList的 relatedResourceUuid1-学科1 relatedResourceUuid2-学科1 转换成 valueToKeysMap: 学科1->[uuid1,uuid2] 学科2->[uuid3,uuid4]
|
||||
Map<String, List<String>> nodeNameToUuidListMap = nodeList.stream()
|
||||
.collect(Collectors.groupingBy(FileMetadataInfo::getOriginalName,
|
||||
Collectors.mapping(FileMetadataInfo::getRelatedResourceUuid, Collectors.toList())
|
||||
));
|
||||
|
||||
|
||||
List<JSONObject> result = new ArrayList<>();
|
||||
|
||||
//nodeIds获取所有节点id: [nodeid1,nodeid2,nodeid3,nodeid4]
|
||||
List<String> uuids = nodeList.stream().map(FileMetadataInfo::getRelatedResourceUuid).collect(Collectors.toList());
|
||||
if (ObjectUtils.isNotEmpty(uuids)) {
|
||||
// uuidToDirIdMap :获取uuid->fileID映射
|
||||
Map<String, Long> uuidToDirIdMap = fileMetadataInfoService.lambdaQuery().select(FileMetadataInfo::getId, FileMetadataInfo::getRelatedResourceUuid)
|
||||
.in(FileMetadataInfo::getRelatedResourceUuid, uuids)
|
||||
.eq(FileMetadataInfo::getTenantId, tenantId)
|
||||
.list().stream().collect(Collectors.toMap(FileMetadataInfo::getRelatedResourceUuid, FileMetadataInfo::getId));
|
||||
if (uuidToDirIdMap.isEmpty()) {
|
||||
log.error("获取节点ID映射失败,节点类型: {}, 标识符: {}", queryNodeType, queryNodeName);
|
||||
return getEmptyNodeSize(queryNodeName,intervalMonths,targetYm);
|
||||
}
|
||||
|
||||
// fileMetadIds: uuid对应的fileid结合
|
||||
List<Long> fileMetadIds = new ArrayList<>(uuidToDirIdMap.values());
|
||||
|
||||
// nodeSizeDTOS: 获取所有node节点目录空间
|
||||
List<NodeSizeDTO> nodeSizeDTOS = null;
|
||||
if (ObjectUtils.isNotEmpty(intervalMonths)) {
|
||||
// 近几个月
|
||||
nodeSizeDTOS = fileStorageService.selectNodeSizeByNodeType(fileMetadIds, intervalMonths,tenantId );
|
||||
|
||||
if (ObjectUtils.isEmpty(nodeSizeDTOS)) {
|
||||
// 空间为空 也要返回nodeName
|
||||
return getEmptyNodeSize(queryNodeName,intervalMonths,targetYm);
|
||||
}
|
||||
|
||||
// nodeSizeDTOMaps: 节点的fileid --> filesize
|
||||
Map<Long, Long> nodeSizeDTOMaps = nodeSizeDTOS.stream().collect(Collectors.toMap(NodeSizeDTO::getDirId, NodeSizeDTO::getTotalSize));
|
||||
nodeNameToUuidListMap.forEach((nodeName, uuidList) -> {
|
||||
AtomicLong totalSize = new AtomicLong();
|
||||
uuidList.forEach(uuidItem -> {
|
||||
Long dirId = uuidToDirIdMap.get(uuidItem);
|
||||
Long filesize = nodeSizeDTOMaps.get(dirId);
|
||||
if (ObjectUtils.isNotEmpty(filesize)) {
|
||||
totalSize.addAndGet(filesize);
|
||||
}
|
||||
});
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("nodeName", nodeName);
|
||||
jsonObject.put("totalSize", FileSizeUtils.formatFileSizeToGB(new BigDecimal(totalSize.toString())));
|
||||
result.add(jsonObject);
|
||||
});
|
||||
}else if (ObjectUtils.isNotEmpty(targetYm)) {
|
||||
//查询增量的
|
||||
nodeSizeDTOS = fileStorageService.statDirStorageByTargetYm(fileMetadIds, targetYm,tenantId);
|
||||
|
||||
if (ObjectUtils.isEmpty(nodeSizeDTOS)) {
|
||||
// 空间为空 也要返回nodeName
|
||||
return getEmptyNodeSize(queryNodeName,intervalMonths,targetYm);
|
||||
}
|
||||
|
||||
Map<Long, Map<String, Long>> nodeSizeDTOMaps = nodeSizeDTOS.stream().collect(Collectors.groupingBy(NodeSizeDTO::getDirId,
|
||||
Collectors.toMap(NodeSizeDTO::getStatDimension, NodeSizeDTO::getTotalSize)));
|
||||
nodeNameToUuidListMap.forEach((nodeName, uuidList) -> {
|
||||
Map<String, Long> totalSizeMap = new HashMap<>();
|
||||
uuidList.forEach(uuidItem -> {
|
||||
Long dirId = uuidToDirIdMap.get(uuidItem);
|
||||
Map<String, Long> statDimensionSizeMap = nodeSizeDTOMaps.get(dirId);
|
||||
totalSizeMap.put("BEFORE", totalSizeMap.getOrDefault("BEFORE",0L) + statDimensionSizeMap.getOrDefault("BEFORE",0L));
|
||||
totalSizeMap.put("INCREMENT", totalSizeMap.getOrDefault("INCREMENT",0L) + statDimensionSizeMap.getOrDefault("INCREMENT",0L));
|
||||
});
|
||||
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("nodeName", nodeName);
|
||||
jsonObject.put("BEFORE", FileSizeUtils.formatFileSizeToGB(new BigDecimal(totalSizeMap.get("BEFORE").toString())));
|
||||
jsonObject.put("INCREMENT", FileSizeUtils.formatFileSizeToGB(new BigDecimal(totalSizeMap.get("INCREMENT").toString())));
|
||||
result.add(jsonObject);
|
||||
});
|
||||
}
|
||||
|
||||
if (ObjectUtils.isNotEmpty(intervalMonths)) {
|
||||
return calculateByIntervalMonths(groupNameToDirIdsMap, allGroupNames, allDirIds, intervalMonths, tenantId);
|
||||
} else if (ObjectUtils.isNotEmpty(targetYm)) {
|
||||
return calculateByTargetYm(groupNameToDirIdsMap, allGroupNames, allDirIds, targetYm, tenantId);
|
||||
}
|
||||
|
||||
// 查询模式未指定时,返回统一格式的空结果
|
||||
return SdmResponse.success(buildEmptyResults(new HashSet<>(allGroupNames), intervalMonths, targetYm));
|
||||
}
|
||||
|
||||
/**
|
||||
* 近几个月模式计算存储空间
|
||||
*/
|
||||
private SdmResponse<List<JSONObject>> calculateByIntervalMonths(
|
||||
Map<String, List<Long>> groupNameToDirIdsMap,
|
||||
List<String> allGroupNames,
|
||||
List<Long> allDirIds,
|
||||
Integer intervalMonths,
|
||||
Long tenantId) {
|
||||
|
||||
// 查询存储空间数据
|
||||
Map<Long, Long> dirIdToSizeMap = Collections.emptyMap();
|
||||
if (!allDirIds.isEmpty()) {
|
||||
List<NodeSizeDTO> nodeSizeList = fileStorageService.selectNodeSizeByNodeType(allDirIds, intervalMonths, tenantId);
|
||||
if (CollectionUtils.isNotEmpty(nodeSizeList)) {
|
||||
dirIdToSizeMap = nodeSizeList.stream()
|
||||
.collect(Collectors.toMap(NodeSizeDTO::getDirId, NodeSizeDTO::getTotalSize, Long::sum));
|
||||
}
|
||||
}
|
||||
|
||||
// 构建结果
|
||||
List<JSONObject> result = new ArrayList<>();
|
||||
for (String groupName : allGroupNames) {
|
||||
List<Long> dirIds = groupNameToDirIdsMap.getOrDefault(groupName, Collections.emptyList());
|
||||
long totalSize = sumSizeByDirIds(dirIds, dirIdToSizeMap);
|
||||
|
||||
JSONObject item = new JSONObject();
|
||||
item.put("nodeName", groupName);
|
||||
item.put("totalSize", FileSizeUtils.formatFileSizeToGB(new BigDecimal(totalSize)));
|
||||
result.add(item);
|
||||
}
|
||||
|
||||
return SdmResponse.success(result);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static SdmResponse<List<JSONObject>> getEmptyNodeSize(String actualNodeName,Integer intervalMonths, String targetYm) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
if (ObjectUtils.isNotEmpty(intervalMonths)) {
|
||||
jsonObject.put("nodeName", actualNodeName);
|
||||
jsonObject.put("totalSize", 0);
|
||||
}else if (ObjectUtils.isNotEmpty(targetYm)) {
|
||||
jsonObject.put("nodeName", actualNodeName);
|
||||
jsonObject.put("BEFORE", 0);
|
||||
jsonObject.put("INCREMENT", 0);
|
||||
/**
|
||||
* 增量模式计算存储空间
|
||||
*/
|
||||
private SdmResponse<List<JSONObject>> calculateByTargetYm(
|
||||
Map<String, List<Long>> groupNameToDirIdsMap,
|
||||
List<String> allGroupNames,
|
||||
List<Long> allDirIds,
|
||||
String targetYm,
|
||||
Long tenantId) {
|
||||
|
||||
// 查询存储空间数据
|
||||
Map<Long, Map<String, Long>> dirIdToDimensionSizeMap = Collections.emptyMap();
|
||||
if (!allDirIds.isEmpty()) {
|
||||
List<NodeSizeDTO> nodeSizeList = fileStorageService.statDirStorageByTargetYm(allDirIds, targetYm, tenantId);
|
||||
if (CollectionUtils.isNotEmpty(nodeSizeList)) {
|
||||
dirIdToDimensionSizeMap = nodeSizeList.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
NodeSizeDTO::getDirId,
|
||||
Collectors.toMap(NodeSizeDTO::getStatDimension, NodeSizeDTO::getTotalSize, Long::sum)
|
||||
));
|
||||
}
|
||||
}
|
||||
return SdmResponse.success(List.of(jsonObject));
|
||||
|
||||
// 构建结果
|
||||
List<JSONObject> result = new ArrayList<>();
|
||||
for (String groupName : allGroupNames) {
|
||||
List<Long> dirIds = groupNameToDirIdsMap.getOrDefault(groupName, Collections.emptyList());
|
||||
Map<String, Long> dimensionTotals = sumDimensionSizeByDirIds(dirIds, dirIdToDimensionSizeMap);
|
||||
|
||||
JSONObject item = new JSONObject();
|
||||
item.put("nodeName", groupName);
|
||||
item.put("BEFORE", FileSizeUtils.formatFileSizeToGB(new BigDecimal(dimensionTotals.getOrDefault("BEFORE", 0L))));
|
||||
item.put("INCREMENT", FileSizeUtils.formatFileSizeToGB(new BigDecimal(dimensionTotals.getOrDefault("INCREMENT", 0L))));
|
||||
result.add(item);
|
||||
}
|
||||
|
||||
return SdmResponse.success(result);
|
||||
}
|
||||
|
||||
// ==================== 私有辅助方法 ====================
|
||||
|
||||
/**
|
||||
* 批量查询节点列表
|
||||
*/
|
||||
private List<FileMetadataInfo> queryNodeListBatch(String queryNodeType, List<String> queryNodeNames) {
|
||||
if (CollectionUtils.isEmpty(queryNodeNames)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Long tenantId = ThreadLocalContext.getTenantId();
|
||||
return fileMetadataInfoService.lambdaQuery()
|
||||
.eq(FileMetadataInfo::getRelatedResourceUuidOwnType, queryNodeType)
|
||||
.in(FileMetadataInfo::getOriginalName, queryNodeNames)
|
||||
.eq(FileMetadataInfo::getTenantId, tenantId)
|
||||
.list();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据UUID列表批量查询dirId
|
||||
* @param uuids 节点UUID列表
|
||||
* @return uuid -> dirId 的映射
|
||||
*/
|
||||
private Map<String, Long> queryDirIdsByUuids(List<String> uuids) {
|
||||
if (CollectionUtils.isEmpty(uuids)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Long tenantId = ThreadLocalContext.getTenantId();
|
||||
List<FileMetadataInfo> nodeList = fileMetadataInfoService.lambdaQuery()
|
||||
.select(FileMetadataInfo::getId, FileMetadataInfo::getRelatedResourceUuid)
|
||||
.in(FileMetadataInfo::getRelatedResourceUuid, uuids)
|
||||
.eq(FileMetadataInfo::getTenantId, tenantId)
|
||||
.list();
|
||||
|
||||
if (CollectionUtils.isEmpty(nodeList)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return nodeList.stream().collect(
|
||||
Collectors.toMap(
|
||||
FileMetadataInfo::getRelatedResourceUuid,
|
||||
FileMetadataInfo::getId,
|
||||
(existing, replacement) -> existing
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建 nodeName -> dirIds 的映射
|
||||
*/
|
||||
private Map<String, List<Long>> buildNodeNameToDirIdsMap(List<FileMetadataInfo> nodeList) {
|
||||
if (ObjectUtils.isEmpty(nodeList)) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
return nodeList.stream().collect(
|
||||
Collectors.groupingBy(
|
||||
FileMetadataInfo::getOriginalName,
|
||||
Collectors.mapping(FileMetadataInfo::getId, Collectors.toList())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据dirIds汇总存储空间
|
||||
*/
|
||||
private long sumSizeByDirIds(List<Long> dirIds, Map<Long, Long> dirIdToSizeMap) {
|
||||
if (CollectionUtils.isEmpty(dirIds)) {
|
||||
return 0L;
|
||||
}
|
||||
long total = 0L;
|
||||
for (Long dirId : dirIds) {
|
||||
Long size = dirIdToSizeMap.get(dirId);
|
||||
if (size != null) {
|
||||
total += size;
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据dirIds汇总各维度存储空间
|
||||
*/
|
||||
private Map<String, Long> sumDimensionSizeByDirIds(List<Long> dirIds,
|
||||
Map<Long, Map<String, Long>> dirIdToDimensionSizeMap) {
|
||||
long beforeTotal = 0L;
|
||||
long incrementTotal = 0L;
|
||||
|
||||
if (CollectionUtils.isNotEmpty(dirIds)) {
|
||||
for (Long dirId : dirIds) {
|
||||
Map<String, Long> dimensionMap = dirIdToDimensionSizeMap.get(dirId);
|
||||
if (dimensionMap != null) {
|
||||
beforeTotal += dimensionMap.getOrDefault("BEFORE", 0L);
|
||||
incrementTotal += dimensionMap.getOrDefault("INCREMENT", 0L);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Long> result = new HashMap<>();
|
||||
result.put("BEFORE", beforeTotal);
|
||||
result.put("INCREMENT", incrementTotal);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建空结果列表
|
||||
*/
|
||||
private List<JSONObject> buildEmptyResults(Set<String> groupNames, Integer intervalMonths, String targetYm) {
|
||||
List<JSONObject> result = new ArrayList<>();
|
||||
for (String name : groupNames) {
|
||||
JSONObject item = new JSONObject();
|
||||
item.put("nodeName", name);
|
||||
if (ObjectUtils.isNotEmpty(targetYm)) {
|
||||
// 增量模式
|
||||
item.put("BEFORE", BigDecimal.ZERO);
|
||||
item.put("INCREMENT", BigDecimal.ZERO);
|
||||
} else {
|
||||
// 近几月模式或默认模式
|
||||
item.put("totalSize", BigDecimal.ZERO);
|
||||
}
|
||||
result.add(item);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1414,6 +1414,7 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
public SdmResponse getTaskCompleteStatisticsByDiscipline(CommonGetCompleteStatisticsReq req) {
|
||||
List<SimulationTask> simulationTasks = simulationTaskService.lambdaQuery()
|
||||
.eq(SimulationTask::getTenantId, ThreadLocalContext.getTenantId())
|
||||
.isNotNull(SimulationTask::getDiscipline)
|
||||
.isNotNull(SimulationTask::getExeStatus)
|
||||
.eq(ObjectUtils.isNotEmpty(req.getTag1()), SimulationTask::getTag1, req.getTag1())
|
||||
.eq(ObjectUtils.isNotEmpty(req.getTag2()), SimulationTask::getTag2, req.getTag2())
|
||||
|
||||
@@ -1751,7 +1751,8 @@ public class TaskServiceImpl implements ITaskService {
|
||||
public SdmResponse<Map<String, List<String>>> getAllTasksByDiscipline(GetAllTasksByDisciplineReq req) {
|
||||
Map<String, List<String>> discipline2TaskUUIDMap = simulationTaskService.lambdaQuery()
|
||||
.in(SimulationTask::getDiscipline, req.getDisciplines())
|
||||
.list().stream().collect(Collectors.groupingBy(SimulationTask::getDiscipline, Collectors.mapping(SimulationTask::getTaskName, Collectors.toList())));
|
||||
.in(SimulationTask::getTenantId, ThreadLocalContext.getTenantId())
|
||||
.list().stream().collect(Collectors.groupingBy(SimulationTask::getDiscipline, Collectors.mapping(SimulationTask::getUuid, Collectors.toList())));
|
||||
return SdmResponse.success(discipline2TaskUUIDMap);
|
||||
}
|
||||
|
||||
|
||||
@@ -583,8 +583,8 @@
|
||||
left join simulation_performance performance on performance.taskId = task.uuid
|
||||
<where>
|
||||
performance.completeStatus is not null
|
||||
and
|
||||
task.tenant_Id = #{req.tenantId}
|
||||
and task.discipline is not null
|
||||
and task.tenant_Id = #{req.tenantId}
|
||||
<if test="req.tag1 != null and req.tag1 !='' ">
|
||||
and task.tag1 = #{req.tag1}
|
||||
</if>
|
||||
|
||||
Reference in New Issue
Block a user