feat:文件信息批量入库

This commit is contained in:
2025-11-24 16:02:02 +08:00
parent df815667f4
commit 87ef062f81
7 changed files with 194 additions and 0 deletions

View File

@@ -12,6 +12,12 @@ import java.util.List;
@Schema(description = "文件上传请求参数")
public class UploadFilesReq {
@Schema(description = "用户勾选的所有的文件的原始名称和大小,前端限制不能选择相同名称的文件,后端逻辑判断对应dirId下不能和历史文件名相同")
private List<UploadFilesReq> sourceFiles;
@Schema(description = "本次新增数据的任务id,毫秒值时间戳即可")
private String uploadTaskId;
@Schema(description = "文件路径")
private String path;

View File

@@ -0,0 +1,25 @@
package com.sdm.common.entity.resp.data;
import lombok.Data;
@Data
public class BatchAddFileInfoResp {
/**
* 这次任务上传的id 时间戳
*/
private String uploadTaskId;
/**
* 文件名
*/
private String sourceFileName;
/**
* 文件fileId
*/
private Long businessId;
/**
* MinIO的文件object_key 绝对路径名
*/
private String objectKey;
}

View File

@@ -4,6 +4,7 @@ import com.sdm.common.common.SdmResponse;
import com.sdm.common.entity.req.data.*;
import com.sdm.common.entity.req.system.LaunchApproveReq;
import com.sdm.common.entity.resp.PageDataResp;
import com.sdm.common.entity.resp.data.BatchAddFileInfoResp;
import com.sdm.common.entity.resp.data.ChunkUploadMinioFileResp;
import com.sdm.common.entity.resp.data.FileMetadataInfoResp;
import com.sdm.common.feign.inter.data.IDataFeignClient;
@@ -395,6 +396,15 @@ public class DataFileController implements IDataFeignClient {
return IDataFileService.chunkUploadToMinio(req);
}
/**
* 文件信息入库准备发起评审
*/
@PostMapping("/batchAddFileInfo")
@Operation(summary = "文件信息入库准备发起评审")
public SdmResponse<List<BatchAddFileInfoResp>> batchAddFileInfo(@RequestBody UploadFilesReq req) {
return IDataFileService.batchAddFileInfo(req);
}
}

View File

@@ -186,6 +186,14 @@ public class FileMetadataInfo implements Serializable {
@TableField(value = "cidFlowId")
private String cidFlowId;
@Schema(description= "uploadTaskId:上传新增数据的任务id,毫秒值时间戳")
@TableField(value = "uploadTaskId")
private String uploadTaskId;
@Schema(description= "uploadStatus:文件上传状态0上传中1上传完成")
@TableField(value = "uploadStatus")
private String uploadStatus;
@Schema(description= "cidFlowReviewer:cid审核电子流程里面的评审人,只有列表展示使用")
@TableField(value = "cidFlowReviewer", insertStrategy = FieldStrategy.NEVER,select = false,updateStrategy = FieldStrategy.NEVER)
private String cidFlowReviewer;

View File

@@ -4,6 +4,7 @@ import com.sdm.common.common.SdmResponse;
import com.sdm.common.entity.req.data.*;
import com.sdm.common.entity.req.system.LaunchApproveReq;
import com.sdm.common.entity.resp.PageDataResp;
import com.sdm.common.entity.resp.data.BatchAddFileInfoResp;
import com.sdm.common.entity.resp.data.ChunkUploadMinioFileResp;
import com.sdm.common.entity.resp.data.FileMetadataInfoResp;
import com.sdm.data.model.entity.FileMetadataInfo;
@@ -317,4 +318,6 @@ public interface IDataFileService {
SdmResponse<ChunkUploadMinioFileResp> chunkUploadToMinio(ChunkUploadMinioFileReq req);
SdmResponse<List<BatchAddFileInfoResp>> batchAddFileInfo(UploadFilesReq req);
}

View File

@@ -16,6 +16,7 @@ import com.sdm.common.entity.req.system.LaunchApproveReq;
import com.sdm.common.entity.req.system.UserListReq;
import com.sdm.common.entity.req.system.UserQueryReq;
import com.sdm.common.entity.resp.PageDataResp;
import com.sdm.common.entity.resp.data.BatchAddFileInfoResp;
import com.sdm.common.entity.resp.data.ChunkUploadMinioFileResp;
import com.sdm.common.entity.resp.data.FileMetadataInfoResp;
import com.sdm.common.entity.resp.project.SimulationNodeResp;
@@ -276,6 +277,141 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
return buildSuccessResponse(resp,finalFileName,filePath,chunkBucket);
}
@Override
@Transactional(rollbackFor = Exception.class)
public SdmResponse<List<BatchAddFileInfoResp>> batchAddFileInfo(UploadFilesReq req) {
Long dirId = null;
String uuid = req.getUuid();
if (uuid != null) {
FileMetadataInfo nodeMetadataInfo = fileMetadataInfoService.lambdaQuery().eq(FileMetadataInfo::getRelatedResourceUuid, req.getUuid()).one();
dirId = nodeMetadataInfo.getId();
} else if (req.getDirId() != null) {
dirId = req.getDirId();
} else {
return SdmResponse.failed("目录ID不能为空");
}
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 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);
// 检查此文件夹下是否有历史同名文件 提示
if (CollectionUtils.isNotEmpty(fileMetadataInfoService.lambdaQuery().eq(FileMetadataInfo::getObjectKey, fileMinioObjectKey).list())) {
return SdmResponse.failed("该文件夹下存在同名文件:" + fileReq.getFileName() + ",请确认是否覆盖");
}
boolean hasUploadPermission = fileUserPermissionService.hasFilePermission(dirMetadataInfo.getId(), ThreadLocalContext.getUserId(), FilePermissionEnum.UPLOAD);
if (!hasUploadPermission) {
return SdmResponse.failed("没有上传权限");
}
try {
// 创建目录元数据并保存到数据库
FileMetadataInfo fileInfo = createFileMetadata(fileMinioObjectKey, fileReq.getFileName(), req.getFileType(),
req.getProjectId(), req.getAnalysisDirectionId(), req.getRemarks(), dirMetadataInfo.getId(), fileReq.getSize());
fileInfo.setUploadTaskId(req.getUploadTaskId());
// 只有知识库的文件需要审核
// 1 知识库文件夹
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);
// 需要保存文件的历史版本记录同一文件的所有版本共享一个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.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);
}
// 调用审批流,开启审批; 上面先入库拿到主键id,审批流创建失败后再回退数据
// String templateId, String templateName,String approveContents,int approveAction1新增 2修改 3删除
// if(isknowledge){
// String approveContents = getApproveContents(fileInfo.getId(), "知识库文件新增", NumberConstants.ONE, fileInfo, null);
// Pair<Boolean,String> approvePair = launchFileDataApprove(req.getTemplateId(), req.getTemplateName(), approveContents, NumberConstants.ONE);
// if(!approvePair.getLeft()|| org.apache.commons.lang3.StringUtils.isBlank(approvePair.getRight())) {
// log.error("uploadFiles create approveInit failed, params :{}", JSONObject.toJSONString(req));
// // - 回退MinIO中已上传的文件删除该文件。catch 里统一操作了
// //- 新增 file_metadata_info 信息不入表。
// //- 向前端返回“上传文件失败”。
// throw new RuntimeException("文件上传,创建审批流失败,cidFlowId:"+approvePair.getRight());
// }
// // cid流程id
// fileInfo.setCidFlowId(approvePair.getRight());
// }
// 创建文件扩展信息并保存到数据库
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());
BatchAddFileInfoResp addFileInfoResp = new BatchAddFileInfoResp();
addFileInfoResp.setSourceFileName(originalName);
addFileInfoResp.setBusinessId(fileInfo.getId());
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();
}
/**
* 校验审批回调请求参数的合法性
* @param req 审批回调请求对象

View File

@@ -11,6 +11,7 @@ import com.sdm.common.entity.enums.UserRole;
import com.sdm.common.entity.pojo.system.SysCompany;
import com.sdm.common.entity.pojo.system.SysUserInfo;
import com.sdm.common.entity.req.data.*;
import com.sdm.common.entity.resp.data.BatchAddFileInfoResp;
import com.sdm.common.entity.resp.data.FileMetadataInfoResp;
import com.sdm.common.service.CommonService;
import com.sdm.common.utils.*;
@@ -1285,6 +1286,11 @@ public class SystemFileIDataFileServiceImpl implements IDataFileService {
return null;
}
@Override
public SdmResponse<List<BatchAddFileInfoResp>> batchAddFileInfo(UploadFilesReq req) {
return null;
}
@Override
public void downloadFile(DownloadFileReq req, HttpServletResponse response) {
if (StringUtils.isNotBlank(req.getPath()) && req.getPath().contains("..")) {