用户数据存储配置
This commit is contained in:
@@ -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<String> simulationPoolTaskIds;
|
||||
}
|
||||
@@ -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<String> simulationPoolTaskIds;
|
||||
|
||||
@Schema(description = "删除文件和工况库关联")
|
||||
private List<Long> deleteFileSimulationMappingIds;
|
||||
@Schema(description = "关联工况库信息")
|
||||
private List<SimulationPoolInfo> simulationPoolInfoList;
|
||||
|
||||
/**
|
||||
* 关联分析项目id
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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<Long> userIds;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
//批量修改用户配额
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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<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);
|
||||
|
||||
Map<Long, CIDUserResp> userIdToNicknameMap = pageDataRespSdmResponse.getData().getData().stream().collect(Collectors.toMap(CIDUserResp::getUserId,Function.identity()));
|
||||
|
||||
// 查询这些 userId 的配额信息,创建 userId -> quota 的映射
|
||||
Map<Long, FileStorageQuota> quotaMap = fileStorageQuotaService.lambdaQuery()
|
||||
.in(ObjectUtils.isNotEmpty(userIds), FileStorageQuota::getUserId, userIds)
|
||||
.list().stream()
|
||||
.collect(Collectors.toMap(FileStorageQuota::getUserId, Function.identity()));
|
||||
|
||||
// fileStorageService 查询用户已使用的存储空间
|
||||
Map<Long,UserTotalFileSizeDTO> usedStorageMap = fileStorageService.getTotalFileSizeByCreator(userIds, null).stream()
|
||||
.collect(Collectors.toMap(UserTotalFileSizeDTO::getUserId, Function.identity()));
|
||||
|
||||
|
||||
// 构造最终结果,对于没有配额信息的用户添加默认值,并根据已使用存储量设置状态
|
||||
List<FileStorageQuota> 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<FileStorageQuotaResp> 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<FileStorageQuota> 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<AddUserQuotaEntity> addUserQuota) {
|
||||
if (CollectionUtils.isEmpty(addUserQuota)) {
|
||||
return SdmResponse.success();
|
||||
return SdmResponse.failed("配置参数不能为空");
|
||||
}
|
||||
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);
|
||||
}
|
||||
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("更新成功");
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user