数据存储分析管理
This commit is contained in:
@@ -7,7 +7,7 @@ import lombok.Data;
|
||||
*/
|
||||
@Data
|
||||
public class AllNodeByProjectIdAndTypeResp {
|
||||
private Integer id;
|
||||
private Long id;
|
||||
private String uuid;
|
||||
private String nodeType;
|
||||
private String nodeName;
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
package com.sdm.data.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.data.model.req.AddUserQuotaEntity;
|
||||
import com.sdm.data.model.req.ListUserQuotaReq;
|
||||
import com.sdm.data.model.req.QueryBigFileReq;
|
||||
import com.sdm.data.service.DataStorageAnalysis;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -9,6 +13,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 数据存储分析管理
|
||||
*/
|
||||
@@ -21,29 +27,77 @@ public class DataStorageAnalysisController {
|
||||
private DataStorageAnalysis dataStorageAnalysis;
|
||||
|
||||
/**
|
||||
* 根据类型获取文件空间占用
|
||||
* @param nodeType 节点类型
|
||||
* 根据nodeId(项目nodeId)获取指定查询类型(queryNodeType)文件空间占用(近几个月、增量查询)
|
||||
* 查询项目存储空间占用:项目nodeId+项目queryNodeType
|
||||
* 查询学科存储空间占用:项目nodeId+学科queryNodeType
|
||||
*
|
||||
* @param queryNodeType 需要统计的节点类型
|
||||
* @param nodeId 节点id
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getNodeSizeByNodeType")
|
||||
@Operation(summary = "根据节点类型获取文件空间占用")
|
||||
public SdmResponse getNodeSizeByNodeType(@Parameter(description = "节点类型:project,discipline") @RequestParam(value = "nodeType") String nodeType,@Parameter(description = "节点id") @RequestParam(value = "nodeId", required = false) Long nodeId) {
|
||||
@Operation(summary = "根据nodeId(项目nodeId)获取指定查询类型(queryNodeType)文件空间占用")
|
||||
public SdmResponse getNodeSizeByNodeType(
|
||||
@Parameter(description = "查询节点类型:project,discipline") @RequestParam(value = "queryNodeType", required = false) String queryNodeType,
|
||||
@Parameter(description = "节点id:项目nodeId") @RequestParam(value = "nodeId", required = false) Long nodeId,
|
||||
@Parameter(description = "查询时间间隔(月)") @RequestParam(value = "intervalMonths", required = false) Integer intervalMonths,
|
||||
@Parameter(description = "增量查询指定的月:2025-06") @RequestParam(value = "targetYm", required = false) String targetYm
|
||||
) {
|
||||
try {
|
||||
return dataStorageAnalysis.getNodeSizeByNodeType(nodeType,nodeId);
|
||||
}catch (Exception e){
|
||||
if (ObjectUtils.isEmpty(queryNodeType) || ObjectUtils.isEmpty(nodeId)) {
|
||||
return SdmResponse.success();
|
||||
}
|
||||
return dataStorageAnalysis.getNodeSizeByNodeType(queryNodeType, nodeId, intervalMonths, targetYm);
|
||||
} catch (Exception e) {
|
||||
log.error("获取文件空间占用失败", e);
|
||||
return SdmResponse.failed("获取文件空间占用");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id获取用户的空间占用,不传userId时,返回所有用户空间占用
|
||||
* @param userId 用户id
|
||||
* 根据用户组和用户id获取用户的空间占用
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@GetMapping("/getDirectorySizeByUserId")
|
||||
@Operation(summary = "根据用户id获取用户的空间占用,不传userId时,返回所有用户空间占用")
|
||||
public SdmResponse getDirectorySizeByUserId(@Parameter(description = "用户id") @RequestParam(required = false) Long userId) {
|
||||
return dataStorageAnalysis.getDirectorySizeByUserId(userId);
|
||||
@Operation(summary = "根据用户组和用户id获取用户的空间占用")
|
||||
public SdmResponse getDirectorySizeByUserId(@Parameter(description = "用户id") @RequestParam(value = "userIds", required = false) List<Long> userIds,
|
||||
@Parameter(description = "查询时间间隔(月)") @RequestParam(value = "intervalMonths", required = false) Integer intervalMonths,
|
||||
@Parameter(description = "增量查询指定的月:2025-06") @RequestParam(value = "targetYm", required = false) String targetYm
|
||||
) {
|
||||
return dataStorageAnalysis.getDirectorySizeByUserId(userIds,intervalMonths,targetYm);
|
||||
}
|
||||
|
||||
// 存储系统大文件筛选
|
||||
@PostMapping("/listBigFile")
|
||||
@Operation(summary = "存储系统大文件筛选")
|
||||
public SdmResponse listBigFile(@RequestBody QueryBigFileReq queryBigFileReq){
|
||||
return dataStorageAnalysis.listBigFile(queryBigFileReq);
|
||||
}
|
||||
|
||||
//批量删除大文件
|
||||
@PostMapping("/batchDeleteBigFile")
|
||||
@Operation(summary = "批量删除大文件")
|
||||
public SdmResponse batchDeleteBigFile(@RequestBody List<Long> fileIds){
|
||||
return dataStorageAnalysis.batchDeleteBigFile(fileIds);
|
||||
}
|
||||
|
||||
//新增用户配额
|
||||
@PostMapping("/addUserQuota")
|
||||
@Operation(summary = "新增用户配额")
|
||||
public SdmResponse addUserQuota(@RequestBody AddUserQuotaEntity addUserQuota){
|
||||
return dataStorageAnalysis.addUserQuota(addUserQuota);
|
||||
}
|
||||
// 查询用户配额
|
||||
@PostMapping("/listUserQuota")
|
||||
@Operation(summary = "查询用户配额")
|
||||
public SdmResponse listUserQuota(ListUserQuotaReq listUserQuotaReq){
|
||||
return dataStorageAnalysis.listUserQuota(listUserQuotaReq);
|
||||
}
|
||||
//批量修改用户配额
|
||||
@PostMapping("/batchUpdateUserQuota")
|
||||
@Operation(summary = "批量修改用户配额")
|
||||
public SdmResponse batchUpdateUserQuota(@RequestBody List<AddUserQuotaEntity> addUserQuota){
|
||||
return dataStorageAnalysis.batchUpdateUserQuota(addUserQuota);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.sdm.data.dao;
|
||||
|
||||
import com.sdm.data.model.entity.FileDirectoryRelation;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 文件与父目录关系记录表(含ID路径) Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author author
|
||||
* @since 2025-09-28
|
||||
*/
|
||||
public interface FileDirectoryRelationMapper extends BaseMapper<FileDirectoryRelation> {
|
||||
|
||||
}
|
||||
@@ -17,7 +17,4 @@ import java.util.List;
|
||||
* @since 2025-09-05
|
||||
*/
|
||||
public interface FileMetadataInfoMapper extends BaseMapper<FileMetadataInfo> {
|
||||
List<UserTotalFileSizeDTO> selectTotalFileSizeByUserId(@Param("userId") Long userId);
|
||||
|
||||
List<NodeSizeDTO> selectNodeSizeByNodeType(@Param("directoryIds") List<Long> directoryIds);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class NodeSizeDTO {
|
||||
private Integer parentDirectoryId;
|
||||
private Integer fileSize;
|
||||
private Long dirId;
|
||||
private String nodeName;
|
||||
private Long totalSize;
|
||||
private String statDimension;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ import java.math.BigDecimal;
|
||||
@Data
|
||||
public class UserTotalFileSizeDTO {
|
||||
// 用户ID
|
||||
private Long creatorId;
|
||||
|
||||
// 总文件大小(字节/其他单位)
|
||||
private BigDecimal totalFileSize;
|
||||
private Long userId;
|
||||
private String userName;
|
||||
private Long totalSize;
|
||||
private String statDimension;
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
package com.sdm.data.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 文件与父目录关系记录表(含ID路径)
|
||||
* </p>
|
||||
*
|
||||
* @author author
|
||||
* @since 2025-09-28
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
@TableName("file_directory_relation")
|
||||
@ApiModel(value="FileDirectoryRelation对象", description="文件与父目录关系记录表(含ID路径)")
|
||||
public class FileDirectoryRelation implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty(value = "文件唯一标识")
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "文件唯一标识")
|
||||
@TableField("fileId")
|
||||
private Long fileId;
|
||||
|
||||
@ApiModelProperty(value = "父目录唯一标识,根目录下文件为null")
|
||||
@TableField("parentDirectoryId")
|
||||
private Long parentDirectoryId;
|
||||
|
||||
@ApiModelProperty(value = "上层所有路径的id序列,如:1/3/5")
|
||||
@TableField("fullPathIds")
|
||||
private String fullPathIds;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.sdm.data.model.req;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class AddUserQuotaEntity {
|
||||
@Schema(title = "用户ID")
|
||||
private Long userId;
|
||||
|
||||
@Schema(title = "配额值")
|
||||
private Long quotaValue;
|
||||
|
||||
@Schema(title = "配额单位")
|
||||
private String quotaUnit;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.sdm.data.model.req;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ListUserQuotaReq extends BaseReq{
|
||||
private String userName;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.sdm.data.model.req;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class QueryBigFileReq extends BaseReq{
|
||||
/**
|
||||
* 目录ID或项目节点id
|
||||
*/
|
||||
private Long dirId;
|
||||
|
||||
/**
|
||||
* 文件名称
|
||||
*/
|
||||
private String fileName;
|
||||
|
||||
/**
|
||||
* 文件创建时间 createTime
|
||||
*/
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/**
|
||||
* 文件大小
|
||||
*/
|
||||
private Long fileSize;
|
||||
|
||||
|
||||
/**
|
||||
* 文件大小单位
|
||||
*/
|
||||
private String fileSizeUnit;
|
||||
}
|
||||
@@ -1,23 +1,44 @@
|
||||
package com.sdm.data.service;
|
||||
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.data.model.req.AddUserQuotaEntity;
|
||||
import com.sdm.data.model.req.ListUserQuotaReq;
|
||||
import com.sdm.data.model.req.QueryBigFileReq;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface DataStorageAnalysis {
|
||||
/**
|
||||
* 根据类型获取文件空间占用
|
||||
*
|
||||
* @param nodeType 节点类型(project,discipline)
|
||||
* @param nodeId 节点id
|
||||
* @param queryNodeType 节点类型(project,discipline)
|
||||
* @param nodeId 节点id
|
||||
* @param intervalMonths 查询时间间隔(月)
|
||||
* @param targetYm 增量查询指定的月:2025-06
|
||||
* @return 文件总大小(字节)
|
||||
*/
|
||||
SdmResponse getNodeSizeByNodeType(String nodeType,Long nodeId);
|
||||
SdmResponse getNodeSizeByNodeType(String queryNodeType, Long nodeId, Integer intervalMonths, String targetYm);
|
||||
|
||||
/**
|
||||
* 根据用户id获取用户的空间占用,不传userId时,返回所有用户空间占用
|
||||
*
|
||||
* @param userId
|
||||
* 根据用户id获取用户的空间占用
|
||||
* @param userIds 用户id
|
||||
* @param intervalMonths 查询时间间隔(月)
|
||||
* @param targetYm 增量查询指定的月:2025-06
|
||||
* @return
|
||||
*/
|
||||
SdmResponse getDirectorySizeByUserId(Long userId);
|
||||
SdmResponse getDirectorySizeByUserId(List<Long> userIds, Integer intervalMonths, String targetYm);
|
||||
|
||||
/**
|
||||
* 存储系统大文件筛选
|
||||
*/
|
||||
SdmResponse listBigFile(QueryBigFileReq queryBigFileReq);
|
||||
|
||||
SdmResponse batchDeleteBigFile(List<Long> fileIds);
|
||||
|
||||
SdmResponse addUserQuota(AddUserQuotaEntity addUserQuota);
|
||||
|
||||
SdmResponse listUserQuota(ListUserQuotaReq listUserQuotaReq);
|
||||
|
||||
SdmResponse batchUpdateUserQuota(List<AddUserQuotaEntity> addUserQuota);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.sdm.data.service;
|
||||
|
||||
import com.sdm.data.model.entity.FileDirectoryRelation;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 文件与父目录关系记录表(含ID路径) 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author author
|
||||
* @since 2025-09-28
|
||||
*/
|
||||
public interface IFileDirectoryRelationService extends IService<FileDirectoryRelation> {
|
||||
|
||||
}
|
||||
@@ -16,7 +16,4 @@ import java.util.List;
|
||||
* @since 2025-09-05
|
||||
*/
|
||||
public interface IFileMetadataInfoService extends IService<FileMetadataInfo> {
|
||||
List<UserTotalFileSizeDTO> getTotalFileSizeByCreator(Long userId);
|
||||
|
||||
List<NodeSizeDTO> selectNodeSizeByNodeType(List<Long> directoryIds);
|
||||
}
|
||||
|
||||
@@ -1,30 +1,41 @@
|
||||
package com.sdm.data.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.sdm.common.common.SdmResponse;
|
||||
import com.sdm.common.common.ThreadLocalContext;
|
||||
import com.sdm.common.entity.req.system.UserListReq;
|
||||
import com.sdm.common.entity.req.system.UserQueryReq;
|
||||
import com.sdm.common.entity.resp.AllNodeByProjectIdAndTypeResp;
|
||||
import com.sdm.common.entity.resp.PageDataResp;
|
||||
import com.sdm.common.entity.resp.system.CIDUserResp;
|
||||
import com.sdm.common.utils.FileSizeUtils;
|
||||
import com.sdm.common.feign.impl.project.SimuluationNodeFeignClientImpl;
|
||||
import com.sdm.common.feign.impl.system.SysUserFeignClientImpl;
|
||||
import com.sdm.common.utils.PageUtils;
|
||||
import com.sdm.data.model.dto.NodeSizeDTO;
|
||||
import com.sdm.data.model.dto.UserTotalFileSizeDTO;
|
||||
import com.sdm.data.model.entity.FileMetadataInfo;
|
||||
import com.sdm.data.service.DataStorageAnalysis;
|
||||
import com.sdm.data.service.IFileDirectoryRelationService;
|
||||
import com.sdm.data.service.IFileMetadataInfoService;
|
||||
import com.sdm.data.model.entity.FileStorage;
|
||||
import com.sdm.data.model.entity.FileStorageQuota;
|
||||
import com.sdm.data.model.req.AddUserQuotaEntity;
|
||||
import com.sdm.data.model.req.DelFileReq;
|
||||
import com.sdm.data.model.req.ListUserQuotaReq;
|
||||
import com.sdm.data.model.req.QueryBigFileReq;
|
||||
import com.sdm.data.service.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@@ -34,7 +45,7 @@ public class DataStorageAnalysisImpl implements DataStorageAnalysis {
|
||||
private IFileMetadataInfoService fileMetadataInfoService;
|
||||
|
||||
@Autowired
|
||||
IFileDirectoryRelationService fileDirectoryRelationService;
|
||||
IFileStorageService fileStorageService;
|
||||
|
||||
@Autowired
|
||||
SimuluationNodeFeignClientImpl simuluationNodeFeignClient;
|
||||
@@ -42,9 +53,15 @@ public class DataStorageAnalysisImpl implements DataStorageAnalysis {
|
||||
@Autowired
|
||||
SysUserFeignClientImpl sysUserFeignClient;
|
||||
|
||||
public SdmResponse getNodeSizeByNodeType(String nodeType,Long nodeId) {
|
||||
SdmResponse<List<AllNodeByProjectIdAndTypeResp>> response = simuluationNodeFeignClient.getAllNodeByNodeType(nodeId,nodeType);
|
||||
if(!response.isSuccess()){
|
||||
@Autowired
|
||||
IDataFileService dataFileService;
|
||||
|
||||
@Autowired
|
||||
IFileStorageQuotaService fileStorageQuotaService;
|
||||
|
||||
public SdmResponse getNodeSizeByNodeType(String queryNodeType, Long nodeId, Integer intervalMonths, String targetYm) {
|
||||
SdmResponse<List<AllNodeByProjectIdAndTypeResp>> response = simuluationNodeFeignClient.getAllNodeByProjectIdAndType(nodeId, queryNodeType);
|
||||
if (!response.isSuccess()) {
|
||||
return SdmResponse.failed("获取节点信息失败");
|
||||
}
|
||||
|
||||
@@ -52,16 +69,16 @@ public class DataStorageAnalysisImpl implements DataStorageAnalysis {
|
||||
|
||||
|
||||
// nodeid1-学科1 nodeid2-学科1 转换成 valueToKeysMap: 学科1->[nodeid1,nodeid2] 学科2->[nodeid3,nodeid4]
|
||||
Map<String, List<Integer>> valueToKeysMap = nodeLists.stream()
|
||||
Map<String, List<Long>> valueToKeysMap = nodeLists.stream()
|
||||
.collect(Collectors.groupingBy(
|
||||
AllNodeByProjectIdAndTypeResp::getNodeType,
|
||||
AllNodeByProjectIdAndTypeResp::getNodeName,
|
||||
Collectors.mapping(AllNodeByProjectIdAndTypeResp::getId, Collectors.toList())
|
||||
));
|
||||
List<JSONObject> result = new ArrayList<>();
|
||||
|
||||
//nodeIds获取所有节点id: [nodeid1,nodeid2,nodeid3,nodeid4]
|
||||
List<Integer> nodeIds = nodeLists.stream().map(AllNodeByProjectIdAndTypeResp::getId).collect(Collectors.toList());
|
||||
if (!ObjectUtils.isEmpty(nodeIds)) {
|
||||
List<Long> nodeIds = nodeLists.stream().map(AllNodeByProjectIdAndTypeResp::getId).collect(Collectors.toList());
|
||||
if (ObjectUtils.isNotEmpty(nodeIds)) {
|
||||
// nodeIdToNodeDirIdMap :获取nodeid->fileID映射
|
||||
Map<Long, Long> nodeIdToNodeDirIdMap = fileMetadataInfoService.lambdaQuery().select(FileMetadataInfo::getId, FileMetadataInfo::getNodeId)
|
||||
.in(FileMetadataInfo::getNodeId, nodeIds)
|
||||
@@ -74,26 +91,38 @@ public class DataStorageAnalysisImpl implements DataStorageAnalysis {
|
||||
List<Long> fileMetadIds = new ArrayList<>(nodeIdToNodeDirIdMap.values());
|
||||
|
||||
// nodeSizeDTOS: 获取所有node节点目录空间
|
||||
List<NodeSizeDTO> nodeSizeDTOS = fileMetadataInfoService.selectNodeSizeByNodeType(fileMetadIds);
|
||||
|
||||
if (!CollectionUtils.isEmpty(nodeSizeDTOS)) {
|
||||
// nodeSizeDTOMaps: 节点的fileid --> filesize
|
||||
Map<Integer, Integer> nodeSizeDTOMaps = nodeSizeDTOS.stream().collect(Collectors.toMap(NodeSizeDTO::getParentDirectoryId, NodeSizeDTO::getFileSize));
|
||||
valueToKeysMap.forEach((nodeName, nodeIdList) -> {
|
||||
AtomicInteger totalSize = new AtomicInteger();
|
||||
nodeIdList.forEach(nodeid -> {
|
||||
Long dirId = nodeIdToNodeDirIdMap.get(nodeid);
|
||||
Integer filesize = nodeSizeDTOMaps.get(dirId);
|
||||
if (!ObjectUtils.isEmpty(filesize)) {
|
||||
totalSize.addAndGet(filesize);
|
||||
}
|
||||
});
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("nodeName", nodeName);
|
||||
jsonObject.put("totalSize", FileSizeUtils.formatFileSizeToGB(new BigDecimal(totalSize.toString())));
|
||||
result.add(jsonObject);
|
||||
});
|
||||
List<NodeSizeDTO> nodeSizeDTOS = null;
|
||||
if (ObjectUtils.isNotEmpty(intervalMonths)) {
|
||||
// 近几个月
|
||||
nodeSizeDTOS = fileStorageService.selectNodeSizeByNodeType(fileMetadIds, intervalMonths);
|
||||
}
|
||||
if (ObjectUtils.isNotEmpty(targetYm)) {
|
||||
//查询增量的
|
||||
nodeSizeDTOS = fileStorageService.statDirStorageByTargetYm(fileMetadIds, targetYm);
|
||||
}
|
||||
|
||||
if (ObjectUtils.isEmpty(nodeSizeDTOS)) {
|
||||
return SdmResponse.success();
|
||||
}
|
||||
|
||||
|
||||
// nodeSizeDTOMaps: 节点的fileid --> filesize
|
||||
Map<Long, Long> nodeSizeDTOMaps = nodeSizeDTOS.stream().collect(Collectors.toMap(NodeSizeDTO::getDirId, NodeSizeDTO::getTotalSize));
|
||||
valueToKeysMap.forEach((nodeName, nodeIdList) -> {
|
||||
AtomicLong totalSize = new AtomicLong();
|
||||
nodeIdList.forEach(nodeid -> {
|
||||
Long dirId = nodeIdToNodeDirIdMap.get(nodeid);
|
||||
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);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -101,24 +130,142 @@ public class DataStorageAnalysisImpl implements DataStorageAnalysis {
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse getDirectorySizeByUserId(Long userId) {
|
||||
List<UserTotalFileSizeDTO> totalFileSizeByCreator = fileMetadataInfoService.getTotalFileSizeByCreator(userId);
|
||||
public SdmResponse getDirectorySizeByUserId(List<Long> userIds, Integer intervalMonths, String targetYm) {
|
||||
if (ObjectUtils.isEmpty(userIds)) {
|
||||
return SdmResponse.success();
|
||||
}
|
||||
List<UserTotalFileSizeDTO> totalFileSizeByCreator = null;
|
||||
if (ObjectUtils.isNotEmpty(intervalMonths)) {
|
||||
// 近几个月
|
||||
totalFileSizeByCreator = fileStorageService.getTotalFileSizeByCreator(userIds, intervalMonths);
|
||||
}
|
||||
if (ObjectUtils.isNotEmpty(targetYm)) {
|
||||
//查询增量的
|
||||
totalFileSizeByCreator = fileStorageService.getTotalFileSizeByCreatorAndTargetYm(userIds, targetYm);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isEmpty(totalFileSizeByCreator)) return SdmResponse.success();
|
||||
|
||||
// 组装返回结果 userName, totalFileSize(格式化大小)
|
||||
List<JSONObject> result = new ArrayList<>();
|
||||
for (UserTotalFileSizeDTO userTotalFileSizeDTO : totalFileSizeByCreator) {
|
||||
UserQueryReq req = new UserQueryReq();
|
||||
req.setUserId(userTotalFileSizeDTO.getCreatorId());
|
||||
req.setUserId(userTotalFileSizeDTO.getUserId());
|
||||
req.setTenantId(ThreadLocalContext.getTenantId());
|
||||
|
||||
SdmResponse<CIDUserResp> cidUserRespSdmResponse = sysUserFeignClient.queryUserDetail(req);
|
||||
if (!cidUserRespSdmResponse.isSuccess()) continue;
|
||||
|
||||
JSONObject tmp = new JSONObject();
|
||||
tmp.put("userName", cidUserRespSdmResponse.getData().getUsername() != null ? cidUserRespSdmResponse.getData().getUsername() : cidUserRespSdmResponse.getData().getNickname());
|
||||
tmp.put("totalFileSize", FileSizeUtils.formatFileSizeToGB(userTotalFileSizeDTO.getTotalFileSize()));
|
||||
tmp.put("totalFileSize", FileSizeUtils.formatFileSizeToGB(new BigDecimal(userTotalFileSizeDTO.getTotalSize())));
|
||||
result.add(tmp);
|
||||
}
|
||||
return SdmResponse.success(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse listBigFile(QueryBigFileReq queryBigFileReq) {
|
||||
// 将前端传入的 fileSize 和 fileSizeUnit 转换为字节(B)
|
||||
Long fileSizeInBytes = null;
|
||||
if (queryBigFileReq.getFileSize() != null && queryBigFileReq.getFileSizeUnit() != null) {
|
||||
fileSizeInBytes = convertToBytes(queryBigFileReq.getFileSize(), queryBigFileReq.getFileSizeUnit());
|
||||
}
|
||||
|
||||
PageHelper.startPage(queryBigFileReq.getCurrent(), queryBigFileReq.getSize());
|
||||
List<FileStorage> list = fileStorageService.lambdaQuery()
|
||||
.eq(ObjectUtils.isNotEmpty(queryBigFileReq.getDirId()), FileStorage::getDirId, queryBigFileReq.getDirId())
|
||||
.like(ObjectUtils.isNotEmpty(queryBigFileReq.getFileName()), FileStorage::getFileName, queryBigFileReq.getFileName())
|
||||
.gt(ObjectUtils.isNotEmpty(queryBigFileReq.getCreateTime()), FileStorage::getCreateTime, queryBigFileReq.getCreateTime())
|
||||
.gt(ObjectUtils.isNotEmpty(fileSizeInBytes), FileStorage::getFileSize, fileSizeInBytes).list();
|
||||
PageInfo<FileStorage> page = new PageInfo<>(list);
|
||||
return PageUtils.getJsonObjectSdmResponse(list, page);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指定单位的文件大小转换为字节大小
|
||||
*
|
||||
* @param size 文件大小
|
||||
* @param unit 文件大小单位 (B, KB, MB, GB, TB)
|
||||
* @return 字节大小
|
||||
*/
|
||||
private Long convertToBytes(Long size, String unit) {
|
||||
if (size == null || unit == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (unit.toUpperCase()) {
|
||||
case "B":
|
||||
return size;
|
||||
case "KB":
|
||||
return size * 1024L;
|
||||
case "MB":
|
||||
return size * 1024L * 1024L;
|
||||
case "GB":
|
||||
return size * 1024L * 1024L * 1024L;
|
||||
case "TB":
|
||||
return size * 1024L * 1024L * 1024L * 1024L;
|
||||
default:
|
||||
return size; // 默认认为是字节
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse batchDeleteBigFile(List<Long> fileIds) {
|
||||
if (CollectionUtils.isEmpty(fileIds)) {
|
||||
return SdmResponse.success();
|
||||
}
|
||||
for (Long fileId : fileIds) {
|
||||
DelFileReq delFileReq = new DelFileReq();
|
||||
delFileReq.setDelFileId(fileId);
|
||||
dataFileService.delFile(delFileReq);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse addUserQuota(AddUserQuotaEntity addUserQuota) {
|
||||
Long quotaValue = convertToBytes(addUserQuota.getQuotaValue(), addUserQuota.getQuotaUnit());
|
||||
FileStorageQuota fileStorageQuota = new FileStorageQuota();
|
||||
fileStorageQuota.setUserId(addUserQuota.getUserId());
|
||||
fileStorageQuota.setQuotaValue(quotaValue);
|
||||
fileStorageQuota.setQuotaUnit(addUserQuota.getQuotaUnit());
|
||||
fileStorageQuota.setStatus("NORMAL");
|
||||
fileStorageQuotaService.save(fileStorageQuota);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse listUserQuota(ListUserQuotaReq listUserQuotaReq) {
|
||||
UserListReq req = new UserListReq();
|
||||
req.setUserName(listUserQuotaReq.getUserName());
|
||||
SdmResponse<PageDataResp<List<CIDUserResp>>> pageDataRespSdmResponse = sysUserFeignClient.listUser(req);
|
||||
if (!pageDataRespSdmResponse.isSuccess()) {
|
||||
return SdmResponse.success();
|
||||
}
|
||||
List<Long> userIds = pageDataRespSdmResponse.getData().getData().stream().map(CIDUserResp::getUserId).toList();
|
||||
PageHelper.startPage(listUserQuotaReq.getCurrent(), listUserQuotaReq.getSize());
|
||||
List<FileStorageQuota> list = fileStorageQuotaService.lambdaQuery().in(ObjectUtils.isNotEmpty(userIds), FileStorageQuota::getUserId, userIds).list();
|
||||
PageInfo<FileStorageQuota> page = new PageInfo<>(list);
|
||||
return PageUtils.getJsonObjectSdmResponse(list, page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SdmResponse batchUpdateUserQuota(List<AddUserQuotaEntity> addUserQuota) {
|
||||
if (CollectionUtils.isEmpty(addUserQuota)) {
|
||||
return SdmResponse.success();
|
||||
}
|
||||
List<FileStorageQuota> fileStorageQuotas = new ArrayList<>();
|
||||
for (AddUserQuotaEntity addUserQuotaEntity : addUserQuota) {
|
||||
Long quotaValue = convertToBytes(addUserQuotaEntity.getQuotaValue(), addUserQuotaEntity.getQuotaUnit());
|
||||
FileStorageQuota fileStorageQuota = new FileStorageQuota();
|
||||
fileStorageQuota.setUserId(addUserQuotaEntity.getUserId());
|
||||
fileStorageQuota.setQuotaValue(quotaValue);
|
||||
fileStorageQuota.setQuotaUnit(addUserQuotaEntity.getQuotaUnit());
|
||||
fileStorageQuotas.add(fileStorageQuota);
|
||||
}
|
||||
|
||||
fileStorageQuotaService.saveBatch(fileStorageQuotas);
|
||||
return SdmResponse.success();
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package com.sdm.data.service.impl;
|
||||
|
||||
import com.sdm.data.model.entity.FileDirectoryRelation;
|
||||
import com.sdm.data.dao.FileDirectoryRelationMapper;
|
||||
import com.sdm.data.service.IFileDirectoryRelationService;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 文件与父目录关系记录表(含ID路径) 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author author
|
||||
* @since 2025-09-28
|
||||
*/
|
||||
@Service
|
||||
public class FileDirectoryRelationServiceImpl extends ServiceImpl<FileDirectoryRelationMapper, FileDirectoryRelation> implements IFileDirectoryRelationService {
|
||||
|
||||
}
|
||||
@@ -20,14 +20,4 @@ import java.util.List;
|
||||
*/
|
||||
@Service
|
||||
public class FileMetadataInfoServiceImpl extends ServiceImpl<FileMetadataInfoMapper, FileMetadataInfo> implements IFileMetadataInfoService {
|
||||
|
||||
@Override
|
||||
public List<UserTotalFileSizeDTO> getTotalFileSizeByCreator(Long userId) {
|
||||
return baseMapper.selectTotalFileSizeByUserId(userId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NodeSizeDTO> selectNodeSizeByNodeType(List<Long> directoryIds) {
|
||||
return baseMapper.selectNodeSizeByNodeType(directoryIds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.sdm.data.dao.FileDirectoryRelationMapper">
|
||||
|
||||
</mapper>
|
||||
@@ -1,53 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.sdm.data.dao.FileMetadataInfoMapper">
|
||||
<resultMap id="fileStatMap" type="com.sdm.data.model.dto.UserTotalFileSizeDTO">
|
||||
<!-- 数据库字段creatorId(INTEGER)映射到Java的Integer类型 -->
|
||||
<result column="creatorId" property="creatorId"
|
||||
jdbcType="INTEGER" javaType="java.lang.Integer"/>
|
||||
|
||||
<!-- 数据库字段totalFileSize(DECIMAL)映射到Java的BigDecimal类型 -->
|
||||
<result column="totalFileSize" property="totalFileSize"
|
||||
jdbcType="DECIMAL" javaType="java.math.BigDecimal"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="selectTotalFileSizeByUserId" resultMap="fileStatMap">
|
||||
SELECT creatorId,
|
||||
SUM(fileSize) AS totalFileSize
|
||||
FROM file_metadata_info
|
||||
<where>
|
||||
creatorId IS NOT NULL
|
||||
AND creatorId != ''
|
||||
<if test="userId != null">
|
||||
AND creatorId = #{userId}
|
||||
</if>
|
||||
</where>
|
||||
GROUP BY creatorId
|
||||
</select>
|
||||
|
||||
<!-- <resultMap id="NodeSizeDTOMap" type="com.sdm.data.model.dto.NodeSizeDTO">
|
||||
<!– 数据库字段creatorId(INTEGER)映射到Java的Integer类型 –>
|
||||
<result column="creatorId" property="creatorId"
|
||||
jdbcType="INTEGER" javaType="java.lang.Integer"/>
|
||||
|
||||
<!– 数据库字段totalFileSize(DECIMAL)映射到Java的BigDecimal类型 –>
|
||||
<result column="totalFileSize" property="totalFileSize"
|
||||
jdbcType="DECIMAL" javaType="java.math.BigDecimal"/>
|
||||
</resultMap>-->
|
||||
|
||||
|
||||
<select id="selectNodeSizeByNodeType" resultType="com.sdm.data.model.dto.NodeSizeDTO">
|
||||
SELECT
|
||||
r.parentDirectoryId as parentDirectoryId,
|
||||
SUM(m.fileSize) as fileSize
|
||||
FROM `file_directory_relation` r
|
||||
JOIN file_metadata_info m ON r.fileId = m.id
|
||||
WHERE r.parentDirectoryId IN
|
||||
<foreach collection="directoryIds" item="id" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
GROUP BY r.parentDirectoryId
|
||||
</select>
|
||||
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -647,7 +647,7 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
List<AllNodeByProjectIdAndTypeResp> allNodeByProjectIdAndTypeRespList = new ArrayList<>();
|
||||
List<SimulationNode> nodeList = this.lambdaQuery()
|
||||
.eq(ObjectUtils.isNotEmpty(nodeId), SimulationNode::getId, nodeId)
|
||||
.eq(SimulationNode::getNodeType, nodeType)
|
||||
.eq(ObjectUtils.isNotEmpty(nodeType),SimulationNode::getNodeType, nodeType)
|
||||
.list();
|
||||
if (CollectionUtils.isEmpty(nodeList)) {
|
||||
return SdmResponse.failed("未找到节点");
|
||||
@@ -656,6 +656,7 @@ public class NodeServiceImpl extends ServiceImpl<SimulationNodeMapper, Simulatio
|
||||
nodeList.forEach(simulationNode -> {
|
||||
AllNodeByProjectIdAndTypeResp allNodeByProjectIdAndTypeResp = new AllNodeByProjectIdAndTypeResp();
|
||||
BeanUtils.copyProperties(simulationNode, allNodeByProjectIdAndTypeResp);
|
||||
allNodeByProjectIdAndTypeResp.setId(simulationNode.getId().longValue());
|
||||
allNodeByProjectIdAndTypeRespList.add(allNodeByProjectIdAndTypeResp);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user