diff --git a/common/src/main/java/com/sdm/common/entity/req/data/SimulationPoolInfo.java b/common/src/main/java/com/sdm/common/entity/req/data/SimulationPoolInfo.java new file mode 100644 index 00000000..9f896a05 --- /dev/null +++ b/common/src/main/java/com/sdm/common/entity/req/data/SimulationPoolInfo.java @@ -0,0 +1,27 @@ +package com.sdm.common.entity.req.data; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Data +public class SimulationPoolInfo { + /** + * 所属工况库id + */ + @Schema(description = "所属工况库id") + private Integer simulationPoolId; + + /** + * 工况库版本 + */ + @Schema(description = "工况库版本") + private String simulationPoolVersion; + + /** + * 关联工况 + */ + @Schema(description = "关联工况") + private List simulationPoolTaskIds; +} diff --git a/common/src/main/java/com/sdm/common/entity/req/data/UploadFilesReq.java b/common/src/main/java/com/sdm/common/entity/req/data/UploadFilesReq.java index 52f5dc86..450029d6 100644 --- a/common/src/main/java/com/sdm/common/entity/req/data/UploadFilesReq.java +++ b/common/src/main/java/com/sdm/common/entity/req/data/UploadFilesReq.java @@ -73,26 +73,8 @@ public class UploadFilesReq { @Schema(description = "关联项目id") private String projectId; - /** - * 所属工况库id - */ - @Schema(description = "所属工况库id") - private Integer simulationPoolId; - - /** - * 工况库版本 - */ - @Schema(description = "工况库版本") - private String simulationPoolVersion; - - /** - * 关联工况 - */ - @Schema(description = "关联工况") - private List simulationPoolTaskIds; - - @Schema(description = "删除文件和工况库关联") - private List deleteFileSimulationMappingIds; + @Schema(description = "关联工况库信息") + private List simulationPoolInfoList; /** * 关联分析项目id diff --git a/common/src/main/java/com/sdm/common/entity/req/system/UserListReq.java b/common/src/main/java/com/sdm/common/entity/req/system/UserListReq.java index f1faa4f4..4579e416 100644 --- a/common/src/main/java/com/sdm/common/entity/req/system/UserListReq.java +++ b/common/src/main/java/com/sdm/common/entity/req/system/UserListReq.java @@ -2,7 +2,6 @@ package com.sdm.common.entity.req.system; import com.sdm.common.entity.BaseReq; import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotNull; import lombok.Data; @Schema(description = "用户列表查询请求参数") @@ -14,9 +13,12 @@ public class UserListReq extends BaseReq { @Schema(description = "用户ID") private Long userId; - @Schema(description = "用户名") + @Schema(description = "CID userName是手机号") private String userName; + @Schema(description = "昵称") + private String nickname; + @Schema(description = "手机号") private String phone; } \ No newline at end of file diff --git a/common/src/main/java/com/sdm/common/entity/req/system/UserQueryReq.java b/common/src/main/java/com/sdm/common/entity/req/system/UserQueryReq.java index 9e3782a0..57b71b70 100644 --- a/common/src/main/java/com/sdm/common/entity/req/system/UserQueryReq.java +++ b/common/src/main/java/com/sdm/common/entity/req/system/UserQueryReq.java @@ -20,9 +20,12 @@ public class UserQueryReq { @NotNull(message = "用户ID不能为空") private Long userId; - @Schema(description = "用户名") + @Schema(description = "CID userName是手机号") private String userName; + @Schema(description = "昵称") + private String nickName; + @Schema(description = "用户IDS") private List userIds; diff --git a/common/src/main/java/com/sdm/common/utils/FileSizeUtils.java b/common/src/main/java/com/sdm/common/utils/FileSizeUtils.java index 3672968a..252b2819 100644 --- a/common/src/main/java/com/sdm/common/utils/FileSizeUtils.java +++ b/common/src/main/java/com/sdm/common/utils/FileSizeUtils.java @@ -65,5 +65,71 @@ public class FileSizeUtils { DecimalFormat df = new DecimalFormat("0.00000000"); return df.format(gbValue); } + + /** + * 将指定单位的文件大小转换为字节大小 + * + * @param size 文件大小 + * @param unit 文件大小单位 (B, KB, MB, GB, TB) + * @return 字节大小 + */ + public static 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; // 默认认为是字节 + } + } + + /** + * 将字节大小转换为指定单位的文件大小 + * + * @param bytes 字节大小 + * @param unit 文件大小单位 (B, KB, MB, GB, TB) + * @return 文件大小 + */ + public static BigDecimal convertToUnit(Long bytes, String unit) { + if (bytes == null || unit == null) { + return null; + } + + BigDecimal byteValue = new BigDecimal(bytes); + BigDecimal result; + + switch (unit.toUpperCase()) { + case "B": + result = byteValue; + break; + case "KB": + result = byteValue.divide(new BigDecimal(1024L), 8, RoundingMode.HALF_UP); + break; + case "MB": + result = byteValue.divide(new BigDecimal(1024L * 1024L), 8, RoundingMode.HALF_UP); + break; + case "GB": + result = byteValue.divide(new BigDecimal(1024L * 1024L * 1024L), 8, RoundingMode.HALF_UP); + break; + case "TB": + result = byteValue.divide(new BigDecimal(1024L * 1024L * 1024L * 1024L), 8, RoundingMode.HALF_UP); + break; + default: + result = byteValue; // 默认认为是字节 + } + + return result; + } } diff --git a/data/src/main/java/com/sdm/data/controller/DataStorageAnalysisController.java b/data/src/main/java/com/sdm/data/controller/DataStorageAnalysisController.java index 7e9a1d54..f5ef6cb5 100644 --- a/data/src/main/java/com/sdm/data/controller/DataStorageAnalysisController.java +++ b/data/src/main/java/com/sdm/data/controller/DataStorageAnalysisController.java @@ -93,7 +93,7 @@ public class DataStorageAnalysisController { // 查询用户配额 @PostMapping("/listUserQuota") @Operation(summary = "查询用户配额") - public SdmResponse listUserQuota(ListUserQuotaReq listUserQuotaReq){ + public SdmResponse listUserQuota(@RequestBody ListUserQuotaReq listUserQuotaReq){ return dataStorageAnalysis.listUserQuota(listUserQuotaReq); } //批量修改用户配额 diff --git a/data/src/main/java/com/sdm/data/model/enums/FileStorageQuotaStatusEnum.java b/data/src/main/java/com/sdm/data/model/enums/FileStorageQuotaStatusEnum.java new file mode 100644 index 00000000..d83c308b --- /dev/null +++ b/data/src/main/java/com/sdm/data/model/enums/FileStorageQuotaStatusEnum.java @@ -0,0 +1,16 @@ +package com.sdm.data.model.enums; + +public enum FileStorageQuotaStatusEnum { + // 配额状态(枚举:NORMAL-正常/WARNING-临界/EXCEED-超限) + NORMAL("正常"), + WARNING("临界"), + EXCEED("超限"); + private String description; + FileStorageQuotaStatusEnum(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } +} diff --git a/data/src/main/java/com/sdm/data/model/resp/FileStorageQuotaResp.java b/data/src/main/java/com/sdm/data/model/resp/FileStorageQuotaResp.java new file mode 100644 index 00000000..e368e454 --- /dev/null +++ b/data/src/main/java/com/sdm/data/model/resp/FileStorageQuotaResp.java @@ -0,0 +1,29 @@ +package com.sdm.data.model.resp; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class FileStorageQuotaResp { + @Schema(description = "用户id") + private String userId; + + @Schema(description = "用户昵称") + private String nickName; + + @Schema(description = "用户工号") + private String jobNumber; + + @Schema(description = "用户部门") + private String department; + + @Schema(description = "存储阈值(显示单位:TB/GB/MB/KB)") + private String quotaValueString; + + @Schema(description = "已使用存储(单位:TB/GB/MB/KB)") + private String usedValueString; + + @Schema(description = "配额状态(枚举:NORMAL-正常/WARNING-临界/EXCEED-超限)") + private String status; + +} diff --git a/data/src/main/java/com/sdm/data/service/impl/DataStorageAnalysisImpl.java b/data/src/main/java/com/sdm/data/service/impl/DataStorageAnalysisImpl.java index 89cc1c7b..2a1cee7e 100644 --- a/data/src/main/java/com/sdm/data/service/impl/DataStorageAnalysisImpl.java +++ b/data/src/main/java/com/sdm/data/service/impl/DataStorageAnalysisImpl.java @@ -19,14 +19,15 @@ import com.sdm.data.model.dto.UserTotalFileSizeDTO; import com.sdm.data.model.entity.FileMetadataInfo; import com.sdm.data.model.entity.FileStorage; import com.sdm.data.model.entity.FileStorageQuota; +import com.sdm.data.model.enums.FileStorageQuotaStatusEnum; import com.sdm.data.model.req.AddUserQuotaEntity; import com.sdm.common.entity.req.data.DelFileReq; import com.sdm.data.model.req.ListUserQuotaReq; import com.sdm.data.model.req.QueryBigFileReq; +import com.sdm.data.model.resp.FileStorageQuotaResp; import com.sdm.data.service.*; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ObjectUtils; -import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -34,10 +35,10 @@ import org.springframework.util.CollectionUtils; import java.math.BigDecimal; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Function; import java.util.stream.Collectors; @Service @@ -229,48 +230,131 @@ public class DataStorageAnalysisImpl implements DataStorageAnalysis { @Override public SdmResponse addUserQuota(AddUserQuotaEntity addUserQuota) { - Long quotaValue = convertToBytes(addUserQuota.getQuotaValue(), addUserQuota.getQuotaUnit()); + if(ObjectUtils.isEmpty(addUserQuota.getUserId()) || ObjectUtils.isEmpty(addUserQuota.getQuotaValue()) || ObjectUtils.isEmpty(addUserQuota.getQuotaUnit())){ + return SdmResponse.failed("配置参数不能为空"); + } + FileStorageQuota existFileStorageQuota = fileStorageQuotaService.lambdaQuery().eq(FileStorageQuota::getUserId, addUserQuota.getUserId()).one(); + if (existFileStorageQuota != null){ + return SdmResponse.failed("该用户已存在存储配额"); + } + FileStorageQuota fileStorageQuota = new FileStorageQuota(); fileStorageQuota.setUserId(addUserQuota.getUserId()); - fileStorageQuota.setQuotaValue(quotaValue); + fileStorageQuota.setQuotaValue(addUserQuota.getQuotaValue()); fileStorageQuota.setQuotaUnit(addUserQuota.getQuotaUnit()); - fileStorageQuota.setStatus("NORMAL"); fileStorageQuotaService.save(fileStorageQuota); - return null; + return SdmResponse.success("新增用户存储配额成功"); } @Override public SdmResponse listUserQuota(ListUserQuotaReq listUserQuotaReq) { UserListReq req = new UserListReq(); - req.setUserName(listUserQuotaReq.getUserName()); + req.setNickname(listUserQuotaReq.getUserName()); + req.setCurrent(listUserQuotaReq.getCurrent()); + req.setSize(listUserQuotaReq.getSize()); SdmResponse>> pageDataRespSdmResponse = sysUserFeignClient.listUser(req); if (!pageDataRespSdmResponse.isSuccess()) { return SdmResponse.success(); } List userIds = pageDataRespSdmResponse.getData().getData().stream().map(CIDUserResp::getUserId).toList(); - PageHelper.startPage(listUserQuotaReq.getCurrent(), listUserQuotaReq.getSize()); - List list = fileStorageQuotaService.lambdaQuery().in(ObjectUtils.isNotEmpty(userIds), FileStorageQuota::getUserId, userIds).list(); - PageInfo page = new PageInfo<>(list); - return PageUtils.getJsonObjectSdmResponse(list, page); + + Map userIdToNicknameMap = pageDataRespSdmResponse.getData().getData().stream().collect(Collectors.toMap(CIDUserResp::getUserId,Function.identity())); + + // 查询这些 userId 的配额信息,创建 userId -> quota 的映射 + Map quotaMap = fileStorageQuotaService.lambdaQuery() + .in(ObjectUtils.isNotEmpty(userIds), FileStorageQuota::getUserId, userIds) + .list().stream() + .collect(Collectors.toMap(FileStorageQuota::getUserId, Function.identity())); + + // fileStorageService 查询用户已使用的存储空间 + Map usedStorageMap = fileStorageService.getTotalFileSizeByCreator(userIds, null).stream() + .collect(Collectors.toMap(UserTotalFileSizeDTO::getUserId, Function.identity())); + + + // 构造最终结果,对于没有配额信息的用户添加默认值,并根据已使用存储量设置状态 + List fullList = userIds.stream().map(userId -> { + FileStorageQuota quota = quotaMap.getOrDefault(userId, createDefaultFileStorageQuota(userId)); + // 设置已使用值 + UserTotalFileSizeDTO usedStorage = usedStorageMap.get(userId); + if (usedStorage != null) { + quota.setUsedValue(usedStorage.getTotalSize()); + } + + // 根据配额和已使用量设置状态 + if (quota.getQuotaValue() != null && quota.getUsedValue() != null) { + // 将配额值转换为与已使用值相同的单位(字节)进行比较 + long quotaInBytes = convertToBytes(quota.getQuotaValue(), quota.getQuotaUnit()); + if (quotaInBytes <= quota.getUsedValue()) { + quota.setStatus("EXCEED"); + } else if (quotaInBytes * 0.8 <= quota.getUsedValue()) { + quota.setStatus("WARNING"); + } else { + quota.setStatus("NORMAL"); + } + } + return quota; + }).toList(); + + List result = new ArrayList<>(); + for (FileStorageQuota quota : fullList) { + FileStorageQuotaResp resp = new FileStorageQuotaResp(); + resp.setUserId(quota.getUserId().toString()); + CIDUserResp cidUserResp = userIdToNicknameMap.get(quota.getUserId()); + resp.setNickName(cidUserResp.getNickname()); + resp.setQuotaValueString(quota.getQuotaValue() + " " + quota.getQuotaUnit()); + BigDecimal usedValue = FileSizeUtils.convertToUnit(quota.getUsedValue(), quota.getQuotaUnit()); + resp.setUsedValueString(usedValue.toPlainString() + " " + quota.getQuotaUnit()); + // 设置状态为中文 + resp.setStatus(FileStorageQuotaStatusEnum.valueOf(quota.getStatus()).getDescription()); + result.add(resp); + } + // 使用 PageDataResp 中的数据构造 PageInfo + PageInfo page = new PageInfo<>(); + page.setTotal(pageDataRespSdmResponse.getData().getTotal()); // 设置总记录数 + page.setPageNum(pageDataRespSdmResponse.getData().getCurrentPage()); // 设置当前页码 + page.setPageSize(pageDataRespSdmResponse.getData().getPageSize()); // 设置每页记录数 + return PageUtils.getJsonObjectSdmResponse(result, page); + } + + // 辅助方法:创建默认的 FileStorageQuota 实例 + private FileStorageQuota createDefaultFileStorageQuota(Long userId) { + FileStorageQuota defaultQuota = new FileStorageQuota(); + defaultQuota.setUserId(userId); + defaultQuota.setQuotaValue(2L); // 默认存储阈值 + defaultQuota.setQuotaUnit("GB"); // 默认单位 + defaultQuota.setUsedValue(0L); // 默认已使用值 + defaultQuota.setStatus("NORMAL"); // 默认状态 + return defaultQuota; } @Override public SdmResponse batchUpdateUserQuota(List addUserQuota) { if (CollectionUtils.isEmpty(addUserQuota)) { - return SdmResponse.success(); + return SdmResponse.failed("配置参数不能为空"); } - List 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); - } + if(ObjectUtils.isEmpty(addUserQuotaEntity.getUserId()) || ObjectUtils.isEmpty(addUserQuotaEntity.getQuotaValue()) || ObjectUtils.isEmpty(addUserQuotaEntity.getQuotaUnit())){ + return SdmResponse.failed("配置参数不能为空"); + } - fileStorageQuotaService.saveBatch(fileStorageQuotas); - return SdmResponse.success(); + // 判断用户是否存在存储配额,如果不存在则新增 + FileStorageQuota existFileStorageQuota = fileStorageQuotaService.lambdaQuery().eq(FileStorageQuota::getUserId, addUserQuotaEntity.getUserId()).one(); + if (ObjectUtils.isEmpty(existFileStorageQuota)) { + FileStorageQuota fileStorageQuota = new FileStorageQuota(); + fileStorageQuota.setUserId(addUserQuotaEntity.getUserId()); + fileStorageQuota.setQuotaValue(addUserQuotaEntity.getQuotaValue()); + fileStorageQuota.setQuotaUnit(addUserQuotaEntity.getQuotaUnit()); + fileStorageQuotaService.save(fileStorageQuota); + } + + // 更新用户存储配额 + fileStorageQuotaService.lambdaUpdate() + .eq(FileStorageQuota::getUserId, addUserQuotaEntity.getUserId()) + .set(FileStorageQuota::getQuotaValue, addUserQuotaEntity.getQuotaValue()) + .set(FileStorageQuota::getQuotaUnit, addUserQuotaEntity.getQuotaUnit()) + .update(); + } + return SdmResponse.success("更新成功"); } /* diff --git a/data/src/main/java/com/sdm/data/service/impl/MinioFileIDataFileServiceImpl.java b/data/src/main/java/com/sdm/data/service/impl/MinioFileIDataFileServiceImpl.java index 168d0772..c1e73f56 100644 --- a/data/src/main/java/com/sdm/data/service/impl/MinioFileIDataFileServiceImpl.java +++ b/data/src/main/java/com/sdm/data/service/impl/MinioFileIDataFileServiceImpl.java @@ -401,8 +401,10 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService { fileMetadataExtensionService.saveBatch(fileMetadataExtensionList); //绑定文件和工况库的关系 - if(ObjectUtils.isNotEmpty(req.getSimulationPoolId()) && Objects.nonNull(req.getSimulationPoolVersion()) && CollectionUtils.isNotEmpty(req.getSimulationPoolTaskIds())){ - fileSimulationMappingService.saveFileSimulationMapping(fileInfo.getId(),req.getSimulationPoolId(),req.getSimulationPoolVersion(),req.getSimulationPoolTaskIds()); + if(CollectionUtils.isNotEmpty(req.getSimulationPoolInfoList())){ + for (SimulationPoolInfo simulationPoolInfo : req.getSimulationPoolInfoList()) { + fileSimulationMappingService.saveFileSimulationMapping(fileInfo.getId(),simulationPoolInfo.getSimulationPoolId(),simulationPoolInfo.getSimulationPoolVersion(),simulationPoolInfo.getSimulationPoolTaskIds()); + } } // 创建默认权限记录 @@ -1353,11 +1355,12 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService { fileMetadataExtensionService.saveBatch(fileMetadataExtensionList); //绑定文件和工况库的关系 - if(ObjectUtils.isNotEmpty(req.getSimulationPoolId()) && Objects.nonNull(req.getSimulationPoolVersion()) && CollectionUtils.isNotEmpty(req.getSimulationPoolTaskIds())){ - fileSimulationMappingService.saveFileSimulationMapping(fileInfo.getId(),req.getSimulationPoolId(),req.getSimulationPoolVersion(),req.getSimulationPoolTaskIds()); + if(CollectionUtils.isNotEmpty(req.getSimulationPoolInfoList())){ + for (SimulationPoolInfo simulationPoolInfo : req.getSimulationPoolInfoList()) { + fileSimulationMappingService.saveFileSimulationMapping(fileInfo.getId(),simulationPoolInfo.getSimulationPoolId(),simulationPoolInfo.getSimulationPoolVersion(),simulationPoolInfo.getSimulationPoolTaskIds()); + } } - // 创建默认权限记录 createFilePermission(fileInfo.getId());