fix:重构文件标签逻辑
This commit is contained in:
15
data/src/main/java/com/sdm/data/dao/FileTagRelMapper.java
Normal file
15
data/src/main/java/com/sdm/data/dao/FileTagRelMapper.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package com.sdm.data.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.sdm.data.model.entity.FileTagRel;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 文件标签关联表(合并目录冗余) Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author author
|
||||
* @since 2026-02-02
|
||||
*/
|
||||
public interface FileTagRelMapper extends BaseMapper<FileTagRel> {
|
||||
}
|
||||
70
data/src/main/java/com/sdm/data/model/entity/FileTagRel.java
Normal file
70
data/src/main/java/com/sdm/data/model/entity/FileTagRel.java
Normal file
@@ -0,0 +1,70 @@
|
||||
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;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 文件标签关联表(合并目录冗余)
|
||||
* </p>
|
||||
*
|
||||
* @author author
|
||||
* @since 2026-02-02
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Accessors(chain = true)
|
||||
@TableName("file_tag_rel")
|
||||
@ApiModel(value = "FileTagRel对象", description = "文件标签关联表(合并目录冗余)")
|
||||
public class FileTagRel implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty(value = "主键ID(自增)")
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "文件ID(file_metadata_info.id)")
|
||||
@TableField("fileId")
|
||||
private Long fileId;
|
||||
|
||||
@ApiModelProperty(value = "标签ID(file_tag.id)")
|
||||
@TableField("tagId")
|
||||
private Integer tagId;
|
||||
|
||||
@ApiModelProperty(value = "目录ID(父级冗余)")
|
||||
@TableField("dirId")
|
||||
private Long dirId;
|
||||
|
||||
|
||||
|
||||
@ApiModelProperty(value = "租户ID")
|
||||
@TableField("tenantId")
|
||||
private Long tenantId;
|
||||
|
||||
@ApiModelProperty(value = "创建者ID")
|
||||
@TableField("creatorId")
|
||||
private Long creatorId;
|
||||
|
||||
@ApiModelProperty(value = "文件大小(用于目录统计)")
|
||||
@TableField("fileSize")
|
||||
private Long fileSize;
|
||||
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
@TableField("createTime")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
@TableField("updateTime")
|
||||
private LocalDateTime updateTime;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.sdm.data.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.sdm.data.model.entity.FileTagRel;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 文件标签关联表(合并目录冗余) 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author author
|
||||
* @since 2026-02-02
|
||||
*/
|
||||
public interface IFileTagRelService extends IService<FileTagRel> {
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.sdm.data.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.sdm.data.dao.FileTagRelMapper;
|
||||
import com.sdm.data.model.entity.FileTagRel;
|
||||
import com.sdm.data.service.IFileTagRelService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 文件标签关联表(合并目录冗余) 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author author
|
||||
* @since 2026-02-02
|
||||
*/
|
||||
@Service
|
||||
public class FileTagRelServiceImpl extends ServiceImpl<FileTagRelMapper, FileTagRel> implements IFileTagRelService {
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import com.sdm.common.entity.enums.*;
|
||||
import com.sdm.common.entity.pojo.task.TaskBaseInfo;
|
||||
import com.sdm.common.entity.req.data.*;
|
||||
import com.sdm.common.entity.req.project.SpdmNodeListReq;
|
||||
import com.sdm.common.entity.req.system.DictTagReq;
|
||||
import com.sdm.common.entity.req.system.LaunchApproveReq;
|
||||
import com.sdm.common.entity.req.system.UserListReq;
|
||||
import com.sdm.common.entity.req.system.UserQueryReq;
|
||||
@@ -26,9 +27,11 @@ import com.sdm.common.entity.resp.data.*;
|
||||
import com.sdm.common.entity.resp.project.SimulationNodeResp;
|
||||
import com.sdm.common.entity.resp.system.CIDUserResp;
|
||||
import com.sdm.common.feign.impl.project.SimulationNodeFeignClientImpl;
|
||||
import com.sdm.common.feign.impl.system.SysConfigFeignClientImpl;
|
||||
import com.sdm.common.feign.impl.system.SysUserFeignClientImpl;
|
||||
import com.sdm.common.feign.inter.project.ISimulationNodeFeignClient;
|
||||
import com.sdm.common.feign.inter.system.IApproveFeignClient;
|
||||
import com.sdm.common.feign.inter.system.ISysConfigFeignClient;
|
||||
import com.sdm.common.feign.inter.task.ISimuluationTaskPoolFeignClient;
|
||||
import com.sdm.common.log.CoreLogger;
|
||||
import com.sdm.common.utils.*;
|
||||
@@ -114,6 +117,9 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
@Autowired
|
||||
private SysUserFeignClientImpl sysUserFeignClient;
|
||||
|
||||
@Autowired
|
||||
private ISysConfigFeignClient sysConfigFeignClient;
|
||||
|
||||
@Autowired
|
||||
private IMinioService minioService;
|
||||
|
||||
@@ -126,9 +132,13 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
@Autowired
|
||||
IFileStorageService fileStorageService;
|
||||
|
||||
@Autowired
|
||||
private IFileTagRelService fileTagRelService;
|
||||
|
||||
@Autowired
|
||||
ISimulationParameterLibraryCategoryObjectService paramObjectService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private ApproveStrategyFactory approveStrategyFactory;
|
||||
|
||||
@@ -163,6 +173,8 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
|
||||
private static final String TEMP_NG_URL = "http://192.168.65.161:10031/storage/";
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public SdmResponse createDir(CreateDirReq req) {
|
||||
@@ -1606,147 +1618,34 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public SdmResponse<List<BatchAddFileInfoResp>> batchAddFileInfo(UploadFilesReq req) {
|
||||
Long dirId = null;
|
||||
String uuid = req.getUuid();
|
||||
SdmResponse<FileMetadataInfo> dirResponse = resolveUploadDirectory(req);
|
||||
if (!dirResponse.isSuccess()) {
|
||||
return SdmResponse.failed(dirResponse.getMessage());
|
||||
}
|
||||
FileMetadataInfo dirMetadataInfo = dirResponse.getData();
|
||||
|
||||
if (uuid != null) {
|
||||
FileMetadataInfo nodeMetadataInfo = fileMetadataInfoService.lambdaQuery().eq(FileMetadataInfo::getRelatedResourceUuid, req.getUuid()).one();
|
||||
if (nodeMetadataInfo == null) {
|
||||
return SdmResponse.failed("根据UUID未找到对应的节点目录");
|
||||
SdmResponse<?> permissionResponse = checkUploadPermission(dirMetadataInfo);
|
||||
if (!permissionResponse.isSuccess()) {
|
||||
return SdmResponse.failed(permissionResponse.getMessage());
|
||||
}
|
||||
|
||||
if (CollectionUtils.isEmpty(req.getSourceFiles())) {
|
||||
return SdmResponse.success();
|
||||
}
|
||||
|
||||
List<BatchAddFileInfoResp> addFileInfoRespList = new ArrayList<>();
|
||||
for (UploadFilesReq fileReq : req.getSourceFiles()) {
|
||||
SdmResponse<BatchAddFileInfoResp> handleResponse = handleBatchFileInfo(req, fileReq, dirMetadataInfo);
|
||||
if (!handleResponse.isSuccess()) {
|
||||
return SdmResponse.failed(handleResponse.getMessage());
|
||||
}
|
||||
dirId = nodeMetadataInfo.getId();
|
||||
} else if (req.getDirId() != null) {
|
||||
dirId = req.getDirId();
|
||||
} else {
|
||||
return SdmResponse.failed("目录ID不能为空");
|
||||
addFileInfoRespList.add(handleResponse.getData());
|
||||
}
|
||||
FileMetadataInfo dirMetadataInfo = fileMetadataInfoService.lambdaQuery().eq(FileMetadataInfo::getId, dirId).eq(FileMetadataInfo::getDataType, DataTypeEnum.DIRECTORY.getValue()).one();
|
||||
if (dirMetadataInfo == null) {
|
||||
return SdmResponse.failed("目录不存在");
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(req.getSourceFiles())) {
|
||||
List<BatchAddFileInfoResp> addFileInfoRespList = new ArrayList<>();
|
||||
for (UploadFilesReq fileReq : req.getSourceFiles()) {
|
||||
String uploadFileId = fileReq.getUploadFileId();
|
||||
String originalName = fileReq.getFileName();
|
||||
String versionSuffix = "_V1";
|
||||
String modifiedFileName;
|
||||
|
||||
int dotIndex = originalName.lastIndexOf('.');
|
||||
if (dotIndex != -1) {
|
||||
// 如果文件有后缀,则在文件名和后缀之间插入版本号
|
||||
modifiedFileName = originalName.substring(0, dotIndex) + versionSuffix + originalName.substring(dotIndex);
|
||||
} else {
|
||||
log.error("文件没有后缀");
|
||||
return SdmResponse.failed("文件名没有后缀");
|
||||
}
|
||||
|
||||
String fileMinioObjectKey = getFileMinioObjectKey(dirMetadataInfo.getObjectKey() + modifiedFileName);
|
||||
// 检查此文件夹下是否有历史同名文件 提示
|
||||
List<FileMetadataInfo> fileMetadataInfoList = fileMetadataInfoService.lambdaQuery().eq(FileMetadataInfo::getObjectKey, fileMinioObjectKey).list();
|
||||
if(CollectionUtils.isNotEmpty(fileMetadataInfoList)){
|
||||
log.error("文件已存在");
|
||||
return SdmResponse.failed("文件已存在,请修改文件名后重新上传");
|
||||
}
|
||||
|
||||
boolean hasUploadPermission = fileUserPermissionService.hasFilePermission(dirMetadataInfo.getId(), ThreadLocalContext.getUserId(), FilePermissionEnum.UPLOAD);
|
||||
if (!hasUploadPermission) {
|
||||
return SdmResponse.failed("没有上传权限");
|
||||
}
|
||||
try {
|
||||
// 创建目录元数据并保存到数据库
|
||||
FileMetadataInfo fileInfo = createFileMetadata(fileMinioObjectKey, fileReq.getFileName(), fileReq.getFileType(),
|
||||
req.getProjectId(), req.getAnalysisDirectionId(), req.getRemarks(), dirMetadataInfo.getId(), fileReq.getSize());
|
||||
fileInfo.setUploadTaskId(req.getUploadTaskId());
|
||||
fileInfo.setTemplateId(req.getTemplateId());
|
||||
fileInfo.setTemplateName(req.getTemplateName());
|
||||
// 知识库和交付物的文件需要审核(12月2需求澄清:不在上传这一步审核)
|
||||
// 1 知识库文件夹 2 交付物属于项目文件夹
|
||||
boolean isknowledge = Objects.equals(DirTypeEnum.KNOWLEDGE_BASE_DIR.getValue(), dirMetadataInfo.getDirType());
|
||||
// boolean isDeliverable = Objects.equals(DirTypeEnum.PROJECT_NODE_DIR.getValue(), dirMetadataInfo.getDirType());
|
||||
if (isknowledge) {
|
||||
fileInfo.setApprovalStatus(ApprovalFileDataStatusEnum.PENDING.getKey());
|
||||
fileInfo.setApproveType(ApproveFileDataTypeEnum.UPLOAD_REVIEWING.getCode());
|
||||
}
|
||||
|
||||
fileMetadataInfoService.save(fileInfo);
|
||||
|
||||
// 需要保存文件的历史版本记录,同一文件的所有版本共享一个ID,
|
||||
fileInfo.setFileGroupId(fileInfo.getId());
|
||||
fileMetadataInfoService.updateById(fileInfo);
|
||||
|
||||
// 循环查询当前文件每一级父目录id,并保存为一条file_storage,用户后续文件搜索统计
|
||||
Long parentDirId = dirMetadataInfo.getId();
|
||||
FileStorage fileStorage = new FileStorage();
|
||||
|
||||
fileStorage.setFileId(fileInfo.getId());
|
||||
fileStorage.setFileName(fileInfo.getOriginalName());
|
||||
fileStorage.setUserId(ThreadLocalContext.getUserId());
|
||||
fileStorage.setTenantId(ThreadLocalContext.getTenantId());
|
||||
fileStorage.setFileBizType(fileInfo.getFileType());
|
||||
// 文件后缀
|
||||
fileStorage.setFileSuffix(getSuffixWithoutDot(fileInfo.getOriginalName()));
|
||||
fileStorage.setFileSize(fileReq.getSize());
|
||||
while (parentDirId != null) {
|
||||
fileStorage.setId(null);
|
||||
fileStorage.setDirId(parentDirId);
|
||||
fileStorageService.save(fileStorage);
|
||||
parentDirId = fileMetadataInfoService.lambdaQuery().eq(FileMetadataInfo::getId, parentDirId).oneOpt()
|
||||
.map(FileMetadataInfo::getParentId)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
// 创建文件扩展信息并保存到数据库
|
||||
List<FileMetadataExtension> fileMetadataExtensionList = new ArrayList<>();
|
||||
List<UploadFilesReq.FileMetadataExtensionRequest> fileMetadataExtensionRequestList = req.getFileMetadataExtensionRequest();
|
||||
if (fileMetadataExtensionRequestList != null && !fileMetadataExtensionRequestList.isEmpty()) {
|
||||
fileMetadataExtensionRequestList.forEach(extensionRequest -> {
|
||||
FileMetadataExtension fileMetadataExtension = new FileMetadataExtension();
|
||||
fileMetadataExtension.setTFilemetaId(fileInfo.getId());
|
||||
fileMetadataExtension.setExtensionKey(extensionRequest.getExtensionKey());
|
||||
fileMetadataExtension.setExtensionValue(extensionRequest.getExtensionValue());
|
||||
fileMetadataExtension.setDataType(Objects.toString(extensionRequest.getDataType(), "string")); // 默认为字符串类型,可根据需要调整
|
||||
fileMetadataExtensionList.add(fileMetadataExtension);
|
||||
});
|
||||
}
|
||||
fileMetadataExtensionService.saveBatch(fileMetadataExtensionList);
|
||||
|
||||
|
||||
//绑定文件和工况库的关系
|
||||
if (CollectionUtils.isNotEmpty(req.getSimulationPoolInfoList())) {
|
||||
for (SimulationPoolInfo simulationPoolInfo : req.getSimulationPoolInfoList()) {
|
||||
for (String simulationPoolTaskId : simulationPoolInfo.getSimulationPoolTaskIds()) {
|
||||
FileSimulationMapping fileSimulationMapping = new FileSimulationMapping();
|
||||
fileSimulationMapping.setFileId(fileInfo.getId());
|
||||
fileSimulationMapping.setSimulationPoolId(simulationPoolInfo.getSimulationPoolId());
|
||||
fileSimulationMapping.setSimulationPoolVersion(simulationPoolInfo.getSimulationPoolVersion());
|
||||
fileSimulationMapping.setSimulationPoolTaskId(simulationPoolTaskId);
|
||||
fileSimulationMappingService.save(fileSimulationMapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 创建默认权限记录
|
||||
createFilePermission(fileInfo.getId());
|
||||
|
||||
BatchAddFileInfoResp addFileInfoResp = new BatchAddFileInfoResp();
|
||||
addFileInfoResp.setSourceFileName(originalName);
|
||||
addFileInfoResp.setBusinessId(fileInfo.getId());
|
||||
addFileInfoResp.setUploadFileId(uploadFileId);
|
||||
addFileInfoResp.setUploadTaskId(req.getUploadTaskId());
|
||||
addFileInfoResp.setObjectKey(fileMinioObjectKey);
|
||||
addFileInfoRespList.add(addFileInfoResp);
|
||||
} catch (Exception e) {
|
||||
log.error("上传文件失败", e);
|
||||
throw new RuntimeException("上传文件失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return SdmResponse.success(addFileInfoRespList);
|
||||
}
|
||||
return SdmResponse.success();
|
||||
return SdmResponse.success(addFileInfoRespList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public SdmResponse chunkUploadCallback(KnowledgeCallBackReq req) {
|
||||
// 处理成功上传的数据
|
||||
@@ -1858,11 +1757,118 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public SdmResponse uploadFiles(UploadFilesReq req) {
|
||||
SdmResponse<FileMetadataInfo> dirResponse = resolveUploadDirectory(req);
|
||||
if (!dirResponse.isSuccess()) {
|
||||
return dirResponse;
|
||||
}
|
||||
FileMetadataInfo dirMetadataInfo = dirResponse.getData();
|
||||
|
||||
String originalName = resolveOriginalName(req);
|
||||
SdmResponse<String> versionedNameResponse = buildVersionedFileName(originalName);
|
||||
if (!versionedNameResponse.isSuccess()) {
|
||||
return versionedNameResponse;
|
||||
}
|
||||
String modifiedFileName = versionedNameResponse.getData();
|
||||
String fileMinioObjectKey = buildFileObjectKey(dirMetadataInfo, modifiedFileName);
|
||||
|
||||
SdmResponse<?> existsResponse = ensureFileNotExists(fileMinioObjectKey);
|
||||
if (!existsResponse.isSuccess()) {
|
||||
return existsResponse;
|
||||
}
|
||||
SdmResponse<?> permissionResponse = checkUploadPermission(dirMetadataInfo);
|
||||
if (!permissionResponse.isSuccess()) {
|
||||
return permissionResponse;
|
||||
}
|
||||
|
||||
try {
|
||||
minioService.uploadFile(req.getFile(), fileMinioObjectKey, null, dirMetadataInfo.getBucketName());
|
||||
|
||||
FileMetadataInfo fileInfo = createFileMetadata(fileMinioObjectKey, originalName, req.getFileType(),
|
||||
req.getProjectId(), req.getAnalysisDirectionId(), req.getRemarks(), dirMetadataInfo.getId(), req.getFile().getSize()
|
||||
);
|
||||
fileMetadataInfoService.save(fileInfo);
|
||||
|
||||
List<Long> ancestorDirIds = collectAncestorDirIds(dirMetadataInfo.getId());
|
||||
saveFileStorageStats(fileInfo, req, ancestorDirIds);
|
||||
saveFileTags(req, fileInfo, dirMetadataInfo, ancestorDirIds);
|
||||
bindSimulationPool(req, fileInfo);
|
||||
saveFileExtensions(req, fileInfo);
|
||||
createFilePermission(fileInfo.getId());
|
||||
triggerKnowledgeApproveIfNeeded(req, fileInfo, dirMetadataInfo);
|
||||
finalizeFileGroup(fileInfo);
|
||||
|
||||
return buildUploadSuccess(fileInfo);
|
||||
} catch (Exception e) {
|
||||
minioService.deleteFile(fileMinioObjectKey, dirMetadataInfo.getBucketName());
|
||||
log.error("上传文件失败", e);
|
||||
throw new RuntimeException("上传文件失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private SdmResponse<BatchAddFileInfoResp> handleBatchFileInfo(UploadFilesReq req, UploadFilesReq fileReq, FileMetadataInfo dirMetadataInfo) {
|
||||
String uploadFileId = fileReq.getUploadFileId();
|
||||
String originalName = fileReq.getFileName();
|
||||
|
||||
SdmResponse<String> versionedNameResponse = buildVersionedFileName(originalName);
|
||||
if (!versionedNameResponse.isSuccess()) {
|
||||
return SdmResponse.failed(versionedNameResponse.getMessage());
|
||||
}
|
||||
String modifiedFileName = versionedNameResponse.getData();
|
||||
String fileMinioObjectKey = buildFileObjectKey(dirMetadataInfo, modifiedFileName);
|
||||
|
||||
SdmResponse<?> existsResponse = ensureFileNotExists(fileMinioObjectKey);
|
||||
if (!existsResponse.isSuccess()) {
|
||||
return SdmResponse.failed(existsResponse.getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
FileMetadataInfo fileInfo = createFileMetadata(fileMinioObjectKey, fileReq.getFileName(), fileReq.getFileType(),
|
||||
req.getProjectId(), req.getAnalysisDirectionId(), req.getRemarks(), dirMetadataInfo.getId(), fileReq.getSize());
|
||||
fileInfo.setUploadTaskId(req.getUploadTaskId());
|
||||
fileInfo.setTemplateId(req.getTemplateId());
|
||||
fileInfo.setTemplateName(req.getTemplateName());
|
||||
|
||||
boolean isknowledge = Objects.equals(DirTypeEnum.KNOWLEDGE_BASE_DIR.getValue(), dirMetadataInfo.getDirType());
|
||||
if (isknowledge) {
|
||||
fileInfo.setApprovalStatus(ApprovalFileDataStatusEnum.PENDING.getKey());
|
||||
fileInfo.setApproveType(ApproveFileDataTypeEnum.UPLOAD_REVIEWING.getCode());
|
||||
}
|
||||
|
||||
fileMetadataInfoService.save(fileInfo);
|
||||
|
||||
fileInfo.setFileGroupId(fileInfo.getId());
|
||||
fileMetadataInfoService.updateById(fileInfo);
|
||||
|
||||
List<Long> ancestorDirIds = collectAncestorDirIds(dirMetadataInfo.getId());
|
||||
saveFileStorageStats(fileInfo, fileReq, ancestorDirIds);
|
||||
saveFileTags(req, fileInfo, dirMetadataInfo, ancestorDirIds);
|
||||
saveFileExtensions(req, fileInfo);
|
||||
bindSimulationPool(req, fileInfo);
|
||||
createFilePermission(fileInfo.getId());
|
||||
|
||||
BatchAddFileInfoResp addFileInfoResp = new BatchAddFileInfoResp();
|
||||
addFileInfoResp.setSourceFileName(originalName);
|
||||
addFileInfoResp.setBusinessId(fileInfo.getId());
|
||||
addFileInfoResp.setUploadFileId(uploadFileId);
|
||||
addFileInfoResp.setUploadTaskId(req.getUploadTaskId());
|
||||
addFileInfoResp.setObjectKey(fileMinioObjectKey);
|
||||
return SdmResponse.success(addFileInfoResp);
|
||||
} catch (Exception e) {
|
||||
log.error("上传文件失败", e);
|
||||
throw new RuntimeException("上传文件失败: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private SdmResponse<FileMetadataInfo> resolveUploadDirectory(UploadFilesReq req) {
|
||||
|
||||
Long dirId = null;
|
||||
String uuid = req.getUuid();
|
||||
|
||||
if (uuid != null) {
|
||||
FileMetadataInfo nodeMetadataInfo = fileMetadataInfoService.lambdaQuery().eq(FileMetadataInfo::getRelatedResourceUuid, req.getUuid()).one();
|
||||
FileMetadataInfo nodeMetadataInfo = fileMetadataInfoService.lambdaQuery()
|
||||
.eq(FileMetadataInfo::getRelatedResourceUuid, req.getUuid())
|
||||
.one();
|
||||
if (nodeMetadataInfo == null) {
|
||||
return SdmResponse.failed("根据UUID未找到对应的节点目录");
|
||||
}
|
||||
@@ -1872,135 +1878,226 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
} else {
|
||||
return SdmResponse.failed("目录ID不能为空");
|
||||
}
|
||||
FileMetadataInfo dirMetadataInfo = fileMetadataInfoService.lambdaQuery().eq(FileMetadataInfo::getId, dirId).eq(FileMetadataInfo::getDataType, DataTypeEnum.DIRECTORY.getValue()).one();
|
||||
|
||||
FileMetadataInfo dirMetadataInfo = fileMetadataInfoService.lambdaQuery()
|
||||
.eq(FileMetadataInfo::getId, dirId)
|
||||
.eq(FileMetadataInfo::getDataType, DataTypeEnum.DIRECTORY.getValue())
|
||||
.one();
|
||||
if (dirMetadataInfo == null) {
|
||||
return SdmResponse.failed("目录不存在");
|
||||
}
|
||||
return SdmResponse.success(dirMetadataInfo);
|
||||
}
|
||||
|
||||
private String resolveOriginalName(UploadFilesReq req) {
|
||||
return ObjectUtils.isNotEmpty(req.getFileName()) ? req.getFileName() : req.getFile().getOriginalFilename();
|
||||
}
|
||||
|
||||
String originalName = ObjectUtils.isNotEmpty(req.getFileName())?req.getFileName():req.getFile().getOriginalFilename();
|
||||
private SdmResponse<String> buildVersionedFileName(String originalName) {
|
||||
String versionSuffix = "_V1";
|
||||
String modifiedFileName;
|
||||
|
||||
int dotIndex = originalName.lastIndexOf('.');
|
||||
if (dotIndex != -1) {
|
||||
// 如果文件有后缀,则在文件名和后缀之间插入版本号
|
||||
modifiedFileName = originalName.substring(0, dotIndex) + versionSuffix + originalName.substring(dotIndex);
|
||||
} else {
|
||||
if (dotIndex == -1) {
|
||||
log.error("文件没有后缀");
|
||||
return SdmResponse.failed("文件名没有后缀");
|
||||
}
|
||||
String modifiedFileName = originalName.substring(0, dotIndex) + versionSuffix + originalName.substring(dotIndex);
|
||||
return SdmResponse.success(modifiedFileName);
|
||||
}
|
||||
|
||||
String fileMinioObjectKey = getFileMinioObjectKey(dirMetadataInfo.getObjectKey() + modifiedFileName);
|
||||
Optional<FileMetadataInfo> fileMetadataInfoOptional = fileMetadataInfoService.lambdaQuery().eq(FileMetadataInfo::getObjectKey, fileMinioObjectKey).oneOpt();
|
||||
if(fileMetadataInfoOptional.isPresent()){
|
||||
private String buildFileObjectKey(FileMetadataInfo dirMetadataInfo, String modifiedFileName) {
|
||||
return getFileMinioObjectKey(dirMetadataInfo.getObjectKey() + modifiedFileName);
|
||||
}
|
||||
|
||||
private SdmResponse<?> ensureFileNotExists(String fileMinioObjectKey) {
|
||||
Optional<FileMetadataInfo> fileMetadataInfoOptional = fileMetadataInfoService.lambdaQuery()
|
||||
.eq(FileMetadataInfo::getObjectKey, fileMinioObjectKey)
|
||||
.oneOpt();
|
||||
if (fileMetadataInfoOptional.isPresent()) {
|
||||
log.error("文件已存在");
|
||||
return SdmResponse.failed("文件已存在,请修改文件名后重新上传");
|
||||
}
|
||||
return SdmResponse.success();
|
||||
}
|
||||
|
||||
boolean hasUploadPermission = fileUserPermissionService.hasFilePermission(dirMetadataInfo.getId(), ThreadLocalContext.getUserId(), FilePermissionEnum.UPLOAD);
|
||||
private SdmResponse<?> checkUploadPermission(FileMetadataInfo dirMetadataInfo) {
|
||||
boolean hasUploadPermission = fileUserPermissionService.hasFilePermission(
|
||||
dirMetadataInfo.getId(), ThreadLocalContext.getUserId(), FilePermissionEnum.UPLOAD
|
||||
);
|
||||
if (!hasUploadPermission) {
|
||||
return SdmResponse.failed("没有上传权限");
|
||||
}
|
||||
try {
|
||||
minioService.uploadFile(req.getFile(), fileMinioObjectKey, null,dirMetadataInfo.getBucketName());
|
||||
return SdmResponse.success();
|
||||
}
|
||||
|
||||
// 创建目录元数据并保存到数据库
|
||||
FileMetadataInfo fileInfo = createFileMetadata(fileMinioObjectKey, originalName, req.getFileType(),
|
||||
req.getProjectId(), req.getAnalysisDirectionId(), req.getRemarks(), dirMetadataInfo.getId(), req.getFile().getSize()
|
||||
);
|
||||
fileMetadataInfoService.save(fileInfo);
|
||||
private List<Long> collectAncestorDirIds(Long dirId) {
|
||||
Long parentDirId = dirId;
|
||||
List<Long> ancestorDirIds = new ArrayList<>();
|
||||
while (parentDirId != null) {
|
||||
ancestorDirIds.add(parentDirId);
|
||||
parentDirId = fileMetadataInfoService.lambdaQuery().eq(FileMetadataInfo::getId, parentDirId).oneOpt()
|
||||
.map(FileMetadataInfo::getParentId)
|
||||
.orElse(null);
|
||||
}
|
||||
return ancestorDirIds;
|
||||
}
|
||||
|
||||
// 循环查询当前文件每一级父目录id,并保存为一条file_storage,用户后续文件搜索统计
|
||||
Long parentDirId = dirMetadataInfo.getId();
|
||||
FileStorage fileStorage = new FileStorage();
|
||||
|
||||
fileStorage.setFileId(fileInfo.getId());
|
||||
fileStorage.setFileName(fileInfo.getOriginalName());
|
||||
fileStorage.setUserId(ThreadLocalContext.getUserId());
|
||||
fileStorage.setTenantId(ThreadLocalContext.getTenantId());
|
||||
fileStorage.setFileBizType(fileInfo.getFileType());
|
||||
// 文件后缀
|
||||
fileStorage.setFileSuffix(getSuffixWithoutDot(fileInfo.getOriginalName()));
|
||||
fileStorage.setFileSize(req.getFile().getSize());
|
||||
while (parentDirId != null) {
|
||||
fileStorage.setId(null);
|
||||
fileStorage.setDirId(parentDirId);
|
||||
fileStorageService.save(fileStorage);
|
||||
parentDirId = fileMetadataInfoService.lambdaQuery().eq(FileMetadataInfo::getId, parentDirId).oneOpt()
|
||||
.map(FileMetadataInfo::getParentId)
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
|
||||
//绑定文件和工况库的关系
|
||||
if (CollectionUtils.isNotEmpty(req.getSimulationPoolInfoList())) {
|
||||
for (SimulationPoolInfo simulationPoolInfo : req.getSimulationPoolInfoList()) {
|
||||
for (String simulationPoolTaskId : simulationPoolInfo.getSimulationPoolTaskIds()) {
|
||||
FileSimulationMapping fileSimulationMapping = new FileSimulationMapping();
|
||||
fileSimulationMapping.setFileId(fileInfo.getId());
|
||||
fileSimulationMapping.setSimulationPoolId(simulationPoolInfo.getSimulationPoolId());
|
||||
fileSimulationMapping.setSimulationPoolVersion(simulationPoolInfo.getSimulationPoolVersion());
|
||||
fileSimulationMapping.setSimulationPoolTaskId(simulationPoolTaskId);
|
||||
fileSimulationMappingService.save(fileSimulationMapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 创建文件扩展信息并保存到数据库
|
||||
List<FileMetadataExtension> fileMetadataExtensionList = new ArrayList<>();
|
||||
List<UploadFilesReq.FileMetadataExtensionRequest> fileMetadataExtensionRequestList = req.getFileMetadataExtensionRequest();
|
||||
if (fileMetadataExtensionRequestList != null && !fileMetadataExtensionRequestList.isEmpty()) {
|
||||
fileMetadataExtensionRequestList.forEach(extensionRequest -> {
|
||||
FileMetadataExtension fileMetadataExtension = new FileMetadataExtension();
|
||||
fileMetadataExtension.setTFilemetaId(fileInfo.getId());
|
||||
fileMetadataExtension.setExtensionKey(extensionRequest.getExtensionKey());
|
||||
fileMetadataExtension.setExtensionValue(extensionRequest.getExtensionValue());
|
||||
fileMetadataExtension.setDataType(Objects.toString(extensionRequest.getDataType(), "string")); // 默认为字符串类型,可根据需要调整
|
||||
fileMetadataExtensionList.add(fileMetadataExtension);
|
||||
});
|
||||
}
|
||||
fileMetadataExtensionService.saveBatch(fileMetadataExtensionList);
|
||||
|
||||
// 创建默认权限记录
|
||||
createFilePermission(fileInfo.getId());
|
||||
|
||||
// 只有知识库的文件需要审核
|
||||
if( Objects.equals(DirTypeEnum.KNOWLEDGE_BASE_DIR.getValue(), dirMetadataInfo.getDirType())){
|
||||
FileApproveRequestBuilder uploadFileApproveRequestBuilder = FileApproveRequestBuilder.builder()
|
||||
.toUpdateFileIds(List.of(fileInfo.getId()))
|
||||
.contents("知识库文件新增")
|
||||
.approveType(ApproveTypeEnum.KNOWLEDGE_APPROVE)
|
||||
.approveFileActionENUM(ApproveFileActionENUM.ADD)
|
||||
.beforeData(List.of(fileInfo))
|
||||
.templateId(req.getTemplateId())
|
||||
.templateName(req.getTemplateName())
|
||||
.knowledgeBaseName(extractRelativePath(dirMetadataInfo))
|
||||
.build();
|
||||
if(CollectionUtils.isNotEmpty(uploadFileApproveRequestBuilder.getBeforeData())){
|
||||
setCreatorNames(uploadFileApproveRequestBuilder.getBeforeData());
|
||||
setProjectName(uploadFileApproveRequestBuilder.getBeforeData());
|
||||
setAnalysisDirectionName(uploadFileApproveRequestBuilder.getBeforeData());
|
||||
setSimulationPoolAndTaskInfo(uploadFileApproveRequestBuilder.getBeforeData());
|
||||
}
|
||||
|
||||
fileApproveExecutor.launchApproveAndUpdateStatus(uploadFileApproveRequestBuilder, ApproveFileDataTypeEnum.UPLOAD_REVIEWING);
|
||||
}
|
||||
|
||||
// 需要保存文件的历史版本记录,同一文件的所有版本共享一个ID,
|
||||
fileInfo.setFileGroupId(fileInfo.getId());
|
||||
fileMetadataInfoService.updateById(fileInfo);
|
||||
|
||||
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("fileId", fileInfo.getId());
|
||||
return SdmResponse.success(jsonObject);
|
||||
} catch (Exception e) {
|
||||
minioService.deleteFile(fileMinioObjectKey, dirMetadataInfo.getBucketName());
|
||||
log.error("上传文件失败", e);
|
||||
throw new RuntimeException("上传文件失败: " + e.getMessage(), e);
|
||||
private void saveFileStorageStats(FileMetadataInfo fileInfo, UploadFilesReq req, List<Long> ancestorDirIds) {
|
||||
long fileSize = resolveFileSize(req);
|
||||
FileStorage fileStorage = new FileStorage();
|
||||
fileStorage.setFileId(fileInfo.getId());
|
||||
fileStorage.setFileName(fileInfo.getOriginalName());
|
||||
fileStorage.setUserId(ThreadLocalContext.getUserId());
|
||||
fileStorage.setTenantId(ThreadLocalContext.getTenantId());
|
||||
fileStorage.setFileBizType(fileInfo.getFileType());
|
||||
fileStorage.setFileSuffix(getSuffixWithoutDot(fileInfo.getOriginalName()));
|
||||
fileStorage.setFileSize(fileSize);
|
||||
for (Long dirIdItem : ancestorDirIds) {
|
||||
fileStorage.setId(null);
|
||||
fileStorage.setDirId(dirIdItem);
|
||||
fileStorageService.save(fileStorage);
|
||||
}
|
||||
}
|
||||
|
||||
private long resolveFileSize(UploadFilesReq req) {
|
||||
if (req.getFile() != null) {
|
||||
return req.getFile().getSize();
|
||||
}
|
||||
return req.getSize() == null ? 0L : req.getSize();
|
||||
}
|
||||
|
||||
|
||||
private void saveFileTags(UploadFilesReq req, FileMetadataInfo fileInfo, FileMetadataInfo dirMetadataInfo,
|
||||
List<Long> ancestorDirIds) {
|
||||
List<DictTagReq> tags = req.getTags();
|
||||
if (CollectionUtils.isEmpty(tags)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Long tenantId = ThreadLocalContext.getTenantId();
|
||||
Long creatorId = ThreadLocalContext.getUserId();
|
||||
long fileSize = resolveFileSize(req);
|
||||
|
||||
DictTagReq.BatchDictIdQueryReq batchReq = new DictTagReq.BatchDictIdQueryReq();
|
||||
batchReq.setItems(tags);
|
||||
|
||||
SdmResponse<Map<String, Map<String, Integer>>> response = sysConfigFeignClient.batchQueryDictionaryIds(batchReq);
|
||||
if (!response.isSuccess() || response.getData() == null) {
|
||||
log.warn("Failed to query dictionary ids for tags");
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, Map<String, Integer>> dictIdMap = response.getData();
|
||||
List<FileTagRel> directRelList = new ArrayList<>();
|
||||
List<FileTagRel> derivedRelList = new ArrayList<>();
|
||||
|
||||
for (DictTagReq tag : tags) {
|
||||
Map<String, Integer> valueMap = dictIdMap.get(tag.getDictName());
|
||||
if (valueMap == null || valueMap.get(tag.getDictValue()) == null) {
|
||||
log.warn("Dictionary not found for dictName: {}, dictValue: {}", tag.getDictName(), tag.getDictValue());
|
||||
continue;
|
||||
}
|
||||
|
||||
Integer dictId = valueMap.get(tag.getDictValue());
|
||||
if (dictId == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FileTagRel directRel = new FileTagRel();
|
||||
directRel.setFileId(fileInfo.getId());
|
||||
directRel.setTagId(dictId);
|
||||
directRel.setDirId(dirMetadataInfo.getId());
|
||||
directRel.setTenantId(tenantId);
|
||||
directRel.setCreatorId(creatorId);
|
||||
directRel.setFileSize(fileSize);
|
||||
directRelList.add(directRel);
|
||||
|
||||
for (Long dirIdItem : ancestorDirIds) {
|
||||
FileTagRel derivedRel = new FileTagRel();
|
||||
derivedRel.setFileId(fileInfo.getId());
|
||||
derivedRel.setTagId(dictId);
|
||||
derivedRel.setDirId(dirIdItem);
|
||||
derivedRel.setTenantId(tenantId);
|
||||
derivedRel.setCreatorId(creatorId);
|
||||
derivedRel.setFileSize(fileSize);
|
||||
derivedRelList.add(derivedRel);
|
||||
}
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(directRelList)) {
|
||||
fileTagRelService.saveBatch(directRelList);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(derivedRelList)) {
|
||||
fileTagRelService.saveBatch(derivedRelList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void bindSimulationPool(UploadFilesReq req, FileMetadataInfo fileInfo) {
|
||||
if (CollectionUtils.isEmpty(req.getSimulationPoolInfoList())) {
|
||||
return;
|
||||
}
|
||||
for (SimulationPoolInfo simulationPoolInfo : req.getSimulationPoolInfoList()) {
|
||||
for (String simulationPoolTaskId : simulationPoolInfo.getSimulationPoolTaskIds()) {
|
||||
FileSimulationMapping fileSimulationMapping = new FileSimulationMapping();
|
||||
fileSimulationMapping.setFileId(fileInfo.getId());
|
||||
fileSimulationMapping.setSimulationPoolId(simulationPoolInfo.getSimulationPoolId());
|
||||
fileSimulationMapping.setSimulationPoolVersion(simulationPoolInfo.getSimulationPoolVersion());
|
||||
fileSimulationMapping.setSimulationPoolTaskId(simulationPoolTaskId);
|
||||
fileSimulationMappingService.save(fileSimulationMapping);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void saveFileExtensions(UploadFilesReq req, FileMetadataInfo fileInfo) {
|
||||
List<FileMetadataExtension> fileMetadataExtensionList = new ArrayList<>();
|
||||
List<UploadFilesReq.FileMetadataExtensionRequest> fileMetadataExtensionRequestList = req.getFileMetadataExtensionRequest();
|
||||
if (fileMetadataExtensionRequestList != null && !fileMetadataExtensionRequestList.isEmpty()) {
|
||||
fileMetadataExtensionRequestList.forEach(extensionRequest -> {
|
||||
FileMetadataExtension fileMetadataExtension = new FileMetadataExtension();
|
||||
fileMetadataExtension.setTFilemetaId(fileInfo.getId());
|
||||
fileMetadataExtension.setExtensionKey(extensionRequest.getExtensionKey());
|
||||
fileMetadataExtension.setExtensionValue(extensionRequest.getExtensionValue());
|
||||
fileMetadataExtension.setDataType(Objects.toString(extensionRequest.getDataType(), "string"));
|
||||
fileMetadataExtensionList.add(fileMetadataExtension);
|
||||
});
|
||||
}
|
||||
fileMetadataExtensionService.saveBatch(fileMetadataExtensionList);
|
||||
}
|
||||
|
||||
private void triggerKnowledgeApproveIfNeeded(UploadFilesReq req, FileMetadataInfo fileInfo, FileMetadataInfo dirMetadataInfo) {
|
||||
if (!Objects.equals(DirTypeEnum.KNOWLEDGE_BASE_DIR.getValue(), dirMetadataInfo.getDirType())) {
|
||||
return;
|
||||
}
|
||||
FileApproveRequestBuilder uploadFileApproveRequestBuilder = FileApproveRequestBuilder.builder()
|
||||
.toUpdateFileIds(List.of(fileInfo.getId()))
|
||||
.contents("知识库文件新增")
|
||||
.approveType(ApproveTypeEnum.KNOWLEDGE_APPROVE)
|
||||
.approveFileActionENUM(ApproveFileActionENUM.ADD)
|
||||
.beforeData(List.of(fileInfo))
|
||||
.templateId(req.getTemplateId())
|
||||
.templateName(req.getTemplateName())
|
||||
.knowledgeBaseName(extractRelativePath(dirMetadataInfo))
|
||||
.build();
|
||||
if (CollectionUtils.isNotEmpty(uploadFileApproveRequestBuilder.getBeforeData())) {
|
||||
setCreatorNames(uploadFileApproveRequestBuilder.getBeforeData());
|
||||
setProjectName(uploadFileApproveRequestBuilder.getBeforeData());
|
||||
setAnalysisDirectionName(uploadFileApproveRequestBuilder.getBeforeData());
|
||||
setSimulationPoolAndTaskInfo(uploadFileApproveRequestBuilder.getBeforeData());
|
||||
}
|
||||
fileApproveExecutor.launchApproveAndUpdateStatus(uploadFileApproveRequestBuilder, ApproveFileDataTypeEnum.UPLOAD_REVIEWING);
|
||||
}
|
||||
|
||||
private void finalizeFileGroup(FileMetadataInfo fileInfo) {
|
||||
fileInfo.setFileGroupId(fileInfo.getId());
|
||||
fileMetadataInfoService.updateById(fileInfo);
|
||||
}
|
||||
|
||||
private SdmResponse<JSONObject> buildUploadSuccess(FileMetadataInfo fileInfo) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("fileId", fileInfo.getId());
|
||||
return SdmResponse.success(jsonObject);
|
||||
}
|
||||
|
||||
public static String getSuffixWithoutDot(String fileName) {
|
||||
int lastDotIndex = fileName.lastIndexOf('.');
|
||||
if (lastDotIndex == -1) {
|
||||
@@ -2009,6 +2106,7 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
|
||||
return fileName.substring(lastDotIndex + 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 从目录的objectKey中提取相对路径(移除目录类型前缀)
|
||||
* 如:knowledge/知识库A/子目录/ → 知识库A/子目录
|
||||
|
||||
Reference in New Issue
Block a user