新增:文件分片上传成功后前端回调;知识库文件审批回调逻辑修改。

This commit is contained in:
yangyang01000846
2025-11-25 10:07:06 +08:00
parent 2ca489cc87
commit d5a37d8132
12 changed files with 202 additions and 38 deletions

View File

@@ -405,6 +405,13 @@ public class DataFileController implements IDataFeignClient {
return IDataFileService.batchAddFileInfo(req);
}
@PostMapping("/callBackknowledgeFile")
@Operation(summary = "文件分片上传成功后前端回调")
public SdmResponse callBackknowledgeFile(@RequestBody KnowledgeCallBackReq req) {
return IDataFileService.callBackknowledgeFile(req);
}
}

View File

@@ -3,17 +3,20 @@ package com.sdm.data.model.bo;
import com.sdm.data.model.entity.FileMetadataInfo;
import lombok.Data;
import java.util.List;
/* 知识库文件增加审批流程,传递给电子流平台内容变化的数据 */
@Data
public class ApprovalFileDataContentsModel {
private Long id; //待审批的原始数据
private List<Long> ids; //新增知识库待审批的原始数据的id集合
private String contents;//变更的描述
private int approveAction;// approveAction-- 1新增 2修改 3删除
private FileMetadataInfo beforeData;// 知识库文件变更的原始数据
private List<FileMetadataInfo> beforeData;// 知识库文件变更的原始数据
private FileMetadataInfo afterData;// 知识库文件变后的数据,只有 approveAction为2的时候才会有值
private List<FileMetadataInfo> afterData;// 知识库文件变后的数据,只有 approveAction为2的时候才会有值
}

View File

@@ -194,6 +194,14 @@ public class FileMetadataInfo implements Serializable {
@TableField(value = "uploadStatus")
private String uploadStatus;
@Schema(description= "templateName:审核模板名称")
@TableField(value = "templateName")
private String templateName;
@Schema(description= "templateId:审核模板Id")
@TableField(value = "templateId")
private String templateId;
@Schema(description= "cidFlowReviewer:cid审核电子流程里面的评审人,只有列表展示使用")
@TableField(value = "cidFlowReviewer", insertStrategy = FieldStrategy.NEVER,select = false,updateStrategy = FieldStrategy.NEVER)
private String cidFlowReviewer;
@@ -206,4 +214,5 @@ public class FileMetadataInfo implements Serializable {
@TableField(value = "analysisDirectionName", insertStrategy = FieldStrategy.NEVER,select = false,updateStrategy = FieldStrategy.NEVER)
private String analysisDirectionName;
}

View File

@@ -320,4 +320,6 @@ public interface IDataFileService {
SdmResponse<List<BatchAddFileInfoResp>> batchAddFileInfo(UploadFilesReq req);
SdmResponse callBackknowledgeFile(KnowledgeCallBackReq req);
}

View File

@@ -2,6 +2,7 @@ package com.sdm.data.service.impl;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
@@ -171,10 +172,10 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
// 前置校验
validateApproveRequest(req);
// id获取
Long id = parseAndValidateMetaId(req);
List<Long> ids = parseAndValidateMetaId(req);
// 查询待审批的db里的数据
FileMetadataInfo approveMetadataInfo = fileMetadataInfoService.lambdaQuery().eq(FileMetadataInfo::getId,id).one();
if(Objects.isNull(approveMetadataInfo)){
List<FileMetadataInfo> approveMetadataInfos = fileMetadataInfoService.lambdaQuery().in(FileMetadataInfo::getId, ids).list();
if(CollectionUtils.isEmpty(approveMetadataInfos)){
log.error("approveDataFile approveMetadataInfo null,param:{}", JSONObject.toJSONString(req));
throw new RuntimeException("仿真知识库审批回调修改失败,未找到待审批数据");
}
@@ -183,7 +184,7 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
try {
// 创建上下文
ApproveContext context = new ApproveContext(
approveMetadataInfo,
approveMetadataInfos,
approveStatus,
minioService,
fileMetadataInfoService,
@@ -193,7 +194,8 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
);
// 获取并执行审批结果
ApproveStrategy strategy = approveStrategyFactory.getStrategy(approveMetadataInfo.getApproveType());
Integer approveType = approveMetadataInfos.get(0).getApproveType();
ApproveStrategy strategy = approveStrategyFactory.getStrategy(approveType);
boolean result = strategy.handle(context);
return result ? SdmResponse.success("仿真知识库审批状态修改成功") :
@@ -226,8 +228,8 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
CoreLogger.error("validateReq error{}", e.getMessage());
return buildFailedResponse(resp,e.getMessage(),req);
}
// -1.确定文件夹
String timestamp = String.valueOf(System.currentTimeMillis());
// -1.确定文件夹,这个前端生成的随机时间戳,用于后面超时文件的回退
String timestamp = req.getUploadTaskId();
// 合并目录
String filePath = getMinioFolderPath(req.getObjectKey());
// 0. 一个文件直接传
@@ -318,6 +320,8 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
FileMetadataInfo fileInfo = createFileMetadata(fileMinioObjectKey, fileReq.getFileName(), req.getFileType(),
req.getProjectId(), req.getAnalysisDirectionId(), req.getRemarks(), dirMetadataInfo.getId(), fileReq.getSize());
fileInfo.setUploadTaskId(req.getUploadTaskId());
fileInfo.setTemplateId(req.getTemplateId());
fileInfo.setTemplateName(req.getTemplateName());
// 只有知识库的文件需要审核
// 1 知识库文件夹
boolean isknowledge = Objects.equals(DirTypeEnum.KNOWLEDGE_BASE_DIR.getValue(), dirMetadataInfo.getDirType());
@@ -402,6 +406,15 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
return SdmResponse.success();
}
@Override
public SdmResponse callBackknowledgeFile(KnowledgeCallBackReq req) {
// 处理成功上传的数据
handleSuccessFiles(req.getSuccBusinessIds());
// 处理失败上传的数据(回滚)
handleFailFiles(req.getFailBusinessIds());
return SdmResponse.success();
}
/**
* 校验审批回调请求参数的合法性
* @param req 审批回调请求对象
@@ -435,7 +448,7 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
* @return 解析后的有效 metaIdLong 类型,非 null
* @throws RuntimeException 若 id 为空、格式非法则抛出异常
*/
private Long parseAndValidateMetaId(LaunchApproveReq req) {
private List<Long> parseAndValidateMetaId(LaunchApproveReq req) {
// 1. 解析审批内容为 Map
String approveContents = req.approveContents;
ApprovalFileDataContentsModel approvalModel=null;
@@ -448,13 +461,13 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
}
// 2. 提取 "id" 字段并校验非空
Long metaId = approvalModel.getId();
if (Objects.isNull(metaId)) {
List<Long> metaIds = approvalModel.getIds();
if (CollectionUtils.isEmpty(metaIds)) {
String errorMsg = "仿真知识库审批回调修改失败审批参数id为空";
log.error("{}param:{}", errorMsg, JSONObject.toJSONString(req));
throw new RuntimeException(errorMsg);
}
return metaId;
return metaIds;
}
@@ -791,7 +804,7 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
if(dirMetadataInfo!=null&&Objects.equals(DirTypeEnum.KNOWLEDGE_BASE_DIR.getValue(), dirMetadataInfo.getDirType())){
// 发送审批电子流,成功继续西面操作,失败直接返回
// String templateId, String templateName,String approveContents,int approveAction1新增 2修改 3删除
String approveContents = getApproveContents(delFileId, "知识库文件删除", NumberConstants.THREE, deleteFileMetadataInfo, null);
String approveContents = getApproveContents(List.of(delFileId), "知识库文件删除", NumberConstants.THREE, List.of(deleteFileMetadataInfo), null);
Pair<Boolean, String> approvePair = launchFileDataApprove(req.getTemplateId(), req.getTemplateName(), approveContents, NumberConstants.THREE);
if(!approvePair.getLeft()|| org.apache.commons.lang3.StringUtils.isBlank(approvePair.getRight())) {
log.error("delFile approveInit failed, params :{}", JSONObject.toJSONString(req));
@@ -1274,7 +1287,7 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
// 调用审批流,开启审批; 上面先入库拿到主键id,审批流创建失败后再回退数据
// String templateId, String templateName,String approveContents,int approveAction1新增 2修改 3删除
if(isknowledge){
String approveContents = getApproveContents(fileInfo.getId(), "知识库文件新增", NumberConstants.ONE, fileInfo, null);
String approveContents = getApproveContents(List.of(fileInfo.getId()), "知识库文件新增", NumberConstants.ONE, List.of(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));
@@ -1417,8 +1430,8 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
fileMetadataInfo.setApprovalStatus(ApprovalFileDataStatusEnum.PENDING.getKey());
fileMetadataInfo.setApproveType(ApproveFileDataTypeEnum.MODIFY_METADATA_REVIEWING.getCode());
// 获取前后变化的file信息
String approveContents = getApproveContents(fileMetadataInfo.getId(), "知识库文件元数据修改",
NumberConstants.TWO, fileMetadataInfo, tempFileMetadataInfo);
String approveContents = getApproveContents(List.of(fileMetadataInfo.getId()), "知识库文件元数据修改",
NumberConstants.TWO, List.of(fileMetadataInfo), List.of(tempFileMetadataInfo));
// 本次待审核的数据
fileMetadataInfo.setTempMetadata(JSONObject.toJSONString(tempFileMetadataInfo));
// String templateId, String templateName,String approveContents,int approveAction1新增 2修改 3删除
@@ -1486,8 +1499,8 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
// 知识库创建审批流
if(dirMetadataInfo!=null&&Objects.equals(DirTypeEnum.KNOWLEDGE_BASE_DIR.getValue(), dirMetadataInfo.getDirType())){
// 获取前后变化的file信息
String approveContents = getApproveContents(fileInfo.getId(), "知识库文件修改",
NumberConstants.TWO,fileMetadataInfo , fileInfo);
String approveContents = getApproveContents(List.of(fileInfo.getId()), "知识库文件修改",
NumberConstants.TWO,List.of(fileMetadataInfo) , List.of(fileInfo));
Pair<Boolean, String> approvePair = launchFileDataApprove(req.getTemplateId(), req.getTemplateName(), approveContents, NumberConstants.TWO);
if(!approvePair.getLeft()||org.apache.commons.lang3.StringUtils.isBlank(approvePair.getRight())){
log.error("uploadAndUpdateFile updateFile approveInit failed, params :{}", JSONObject.toJSONString(req));
@@ -1959,21 +1972,22 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
/**
* 生成包含 id 和 contents 的 JSON 字符串--审批创建的 approveContents
*/
public String getApproveContents(Long id, String contents,Integer approveAction,FileMetadataInfo beforeData,FileMetadataInfo afterData) {
public String getApproveContents(List<Long> ids, String contents,Integer approveAction,List<FileMetadataInfo> beforeDatas,List<FileMetadataInfo> afterDatas) {
ApprovalFileDataContentsModel contentsModel = new ApprovalFileDataContentsModel();
contentsModel.setId(id);
contentsModel.setIds(ids);
contentsModel.setContents(contents);
contentsModel.setApproveAction(approveAction);
contentsModel.setBeforeData(beforeData);
contentsModel.setBeforeData(beforeDatas);
// 只有修改有 afterData 值
if(Objects.equals(NumberConstants.TWO,approveAction)){
contentsModel.setAfterData(afterData);
contentsModel.setAfterData(afterDatas);
}
// 转换为 JSON 字符串并返回
return JSONObject.toJSONString(contentsModel);
}
private void setCreatorNames(List<FileMetadataInfo> list) {
try {
if (ObjectUtils.isNotEmpty(list)) {
@@ -2205,4 +2219,91 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService {
}, nonSensitiveTaskPool);
}
/**
* 处理成功上传的文件:更新状态、发起审批(知识库场景)
* @param succBusinessIds 成功的文件ID列表
*/
private Boolean handleSuccessFiles(List<Long> succBusinessIds) {
if (CollectionUtils.isEmpty(succBusinessIds)) {
return true;
}
// 1. 查询成功的文件元数据
List<FileMetadataInfo> succFileMetadataInfos = fileMetadataInfoService.lambdaQuery()
.in(FileMetadataInfo::getId, succBusinessIds)
.list();
if (CollectionUtils.isEmpty(succFileMetadataInfos)) {
CoreLogger.warn("handleSuccessFiles succFileMetadataInfos null");
return true;
}
// 2. 知识库文件特殊处理:发起审批流
String cidFlowId = "";
FileMetadataInfo firstFile = succFileMetadataInfos.get(0);
Long parentId = firstFile.getParentId();
FileMetadataInfo dirMetadataInfo = fileMetadataInfoService.lambdaQuery()
.eq(FileMetadataInfo::getId, parentId)
.eq(FileMetadataInfo::getDataType, DataTypeEnum.DIRECTORY.getValue())
.one();
boolean isKnowledge = dirMetadataInfo != null &&
Objects.equals(DirTypeEnum.KNOWLEDGE_BASE_DIR.getValue(), dirMetadataInfo.getDirType());
if (isKnowledge) {
// 构建审批内容
String approveContents = getApproveContents(
succBusinessIds,"知识库文件批量新增", NumberConstants.ONE,succFileMetadataInfos,null );
// 发起审批
Pair<Boolean, String> approvePair = launchFileDataApprove(
firstFile.getTemplateId(),
firstFile.getTemplateName(),
approveContents,
NumberConstants.ONE
);
// 审批创建失败:抛出异常
if (!approvePair.getLeft() || org.apache.commons.lang3.StringUtils.isBlank(approvePair.getRight())) {
CoreLogger.error("callBackknowledgeFile create approveInit failed, params :{}", JSONObject.toJSONString(approvePair));
throw new RuntimeException("文件上传,创建审批流失败,cidFlowId:"+approvePair.getRight());
}
cidFlowId = approvePair.getRight();
}
// 3. 批量更新文件状态(上传完成)
FileMetadataInfo updateEntity = new FileMetadataInfo();
updateEntity.setUploadStatus(NumberConstants.ONE_STR);
// 知识库文件关联审批流ID
if (isKnowledge && org.apache.commons.lang3.StringUtils.isNotBlank(cidFlowId)) {
updateEntity.setCidFlowId(cidFlowId);
}
// 执行更新
fileMetadataInfoService.update(updateEntity, Wrappers.lambdaQuery(FileMetadataInfo.class)
.in(FileMetadataInfo::getId, succBusinessIds)
);
return true;
}
/**
* 处理失败上传的文件:删除数据库相关记录(元数据、存储、权限等)
* @param failBusinessIds 失败的文件ID列表
*/
private Boolean handleFailFiles(List<Long> failBusinessIds) {
if (CollectionUtils.isEmpty(failBusinessIds)) {
return true;
}
try {
// 1. 删除文件元数据扩展表
fileMetadataExtensionService.remove(Wrappers.lambdaQuery(FileMetadataExtension.class)
.in(FileMetadataExtension::getTFilemetaId, failBusinessIds));
// 2. 删除文件权限表
fileUserPermissionService.remove(Wrappers.lambdaQuery(FileUserPermission.class)
.in(FileUserPermission::getTFilemetaId, failBusinessIds));
// 3. 删除文件存储表
fileStorageService.remove(Wrappers.lambdaQuery(FileStorage.class)
.in(FileStorage::getFileId, failBusinessIds));
// 4. 删除文件元数据表(最后删除主表)
fileMetadataInfoService.removeBatchByIds(failBusinessIds);
return true;
} catch (Exception e) {
CoreLogger.error("handleFailFiles error{}", e.getMessage());
return false;
}
}
}

View File

@@ -1291,6 +1291,12 @@ public class SystemFileIDataFileServiceImpl implements IDataFileService {
return null;
}
// 未实现,勿使用
@Override
public SdmResponse callBackknowledgeFile(KnowledgeCallBackReq req) {
return null;
}
@Override
public void downloadFile(DownloadFileReq req, HttpServletResponse response) {
if (StringUtils.isNotBlank(req.getPath()) && req.getPath().contains("..")) {

View File

@@ -5,10 +5,12 @@ import com.sdm.data.service.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
@Data
@AllArgsConstructor
public class ApproveContext {
private FileMetadataInfo approveMetadataInfo;
private List<FileMetadataInfo> approveMetadataInfos;
private int approveStatus;
private IMinioService minioService;
private IFileMetadataInfoService fileMetadataInfoService;

View File

@@ -18,7 +18,8 @@ import java.time.LocalDateTime;
public class DeleteApproveStrategy implements ApproveStrategy {
@Override
public boolean handle(ApproveContext context) {
FileMetadataInfo metadata = context.getApproveMetadataInfo();
// FileMetadataInfo metadata = context.getApproveMetadataInfo();
FileMetadataInfo metadata = context.getApproveMetadataInfos().get(0);
int status = context.getApproveStatus();
IFileMetadataInfoService service = context.getFileMetadataInfoService();
IMinioService minioService = context.getMinioService();

View File

@@ -20,7 +20,8 @@ import java.time.LocalDateTime;
public class ModifyFileApproveStrategy implements ApproveStrategy {
@Override
public boolean handle(ApproveContext context) {
FileMetadataInfo metadata = context.getApproveMetadataInfo();
// FileMetadataInfo metadata = context.getApproveMetadataInfo();
FileMetadataInfo metadata = context.getApproveMetadataInfos().get(0);
int status = context.getApproveStatus();
IFileMetadataInfoService service = context.getFileMetadataInfoService();
IMinioService minioService = context.getMinioService();

View File

@@ -13,7 +13,8 @@ import org.springframework.stereotype.Service;
public class ModifyMetadataApproveStrategy implements ApproveStrategy {
@Override
public boolean handle(ApproveContext context) {
FileMetadataInfo metadata = context.getApproveMetadataInfo();
// FileMetadataInfo metadata = context.getApproveMetadataInfo();
FileMetadataInfo metadata = context.getApproveMetadataInfos().get(0);
int status = context.getApproveStatus();
IFileMetadataInfoService service = context.getFileMetadataInfoService();

View File

@@ -11,12 +11,16 @@ import com.sdm.data.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
@Slf4j
public class UploadApproveStrategy implements ApproveStrategy {
@Override
public boolean handle(ApproveContext context) {
FileMetadataInfo metadata = context.getApproveMetadataInfo();
// FileMetadataInfo metadata = context.getApproveMetadataInfo();
List<FileMetadataInfo> approveMetadataInfos = context.getApproveMetadataInfos();
int status = context.getApproveStatus();
IFileMetadataInfoService service = context.getFileMetadataInfoService();
IMinioService minioService = context.getMinioService();
@@ -24,24 +28,29 @@ public class UploadApproveStrategy implements ApproveStrategy {
IFileUserPermissionService fileUserPermissionService = context.getFileUserPermissionService();
IFileStorageService fileStorageService = context.getFileStorageService();
// 审批通过
if (NumberConstants.TWO == status) {
metadata.setApprovalStatus(null);
metadata.setApproveType(ApproveFileDataTypeEnum.COMPLETED.getCode());
service.updateById(metadata);
approveMetadataInfos.forEach(metadata -> {
metadata.setApprovalStatus(null);
metadata.setApproveType(ApproveFileDataTypeEnum.COMPLETED.getCode());
});
service.updateBatchById(approveMetadataInfos);
return true;
}
// 审批不通过
if (NumberConstants.THREE == status) {
// 删除MinIO文件
minioService.deleteFile(metadata.getObjectKey());
List<Long>removeIds = new ArrayList<>();
approveMetadataInfos.forEach(metadata -> {
minioService.deleteFile(metadata.getObjectKey());
removeIds.add(metadata.getId());
});
// 删除数据库记录
service.removeById(metadata.getId());
fileStorageService.remove(new LambdaQueryWrapper<FileStorage>().eq(FileStorage::getFileId, metadata.getId()));
fileMetadataExtensionService.remove(new LambdaQueryWrapper<FileMetadataExtension>().eq(FileMetadataExtension::getTFilemetaId, metadata.getId()));
fileUserPermissionService.remove(new LambdaQueryWrapper<FileUserPermission>().eq(FileUserPermission::getTFilemetaId, metadata.getId()));
service.removeBatchByIds(removeIds);
fileStorageService.remove(new LambdaQueryWrapper<FileStorage>().in(FileStorage::getFileId, removeIds));
fileMetadataExtensionService.remove(new LambdaQueryWrapper<FileMetadataExtension>().in(FileMetadataExtension::getTFilemetaId, removeIds));
fileUserPermissionService.remove(new LambdaQueryWrapper<FileUserPermission>().in(FileUserPermission::getTFilemetaId, removeIds));
return true;
}
return false;