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 1d1eea12..45b1c545 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 @@ -2455,150 +2455,201 @@ public class MinioFileIDataFileServiceImpl implements IDataFileService { } } + /** + * 更新文件。 + *

+ * 支持两类场景: + * 1) 仅更新元数据(项目/分析方向/备注/标签/工况绑定等),若目录类型要求审批则发起审批流程; + * 2) 上传新文件并生成新版本。 + *

+ * + * @param req 更新请求 + * @return 统一响应结果 + */ @Transactional(rollbackFor = Exception.class) @PermissionCheckAspect.FilePermissionCheck(value = FilePermissionEnum.UPLOAD, fileIdExpression = "#req.id") public SdmResponse updateFile(UpdateFileReq req) { + SdmResponse prepareResult = prepareUpdateReq(req); + if (prepareResult != null) { + return prepareResult; + } + + FileMetadataInfo fileMetadataInfo = fileMetadataInfoService.lambdaQuery() + .eq(FileMetadataInfo::getId, req.getId()) + .one(); + if (fileMetadataInfo == null) { + return SdmResponse.failed("文件不存在"); + } + + FileMetadataInfo dirMetadataInfo = fileMetadataInfoService.lambdaQuery() + .eq(FileMetadataInfo::getId, fileMetadataInfo.getParentId()) + .eq(FileMetadataInfo::getDataType, DataTypeEnum.DIRECTORY.getValue()) + .one(); + + if (ObjectUtils.isEmpty(req.getFile())) { + if (dirMetadataInfo != null && DirTypeEnum.isApprovalRequired(dirMetadataInfo.getDirType())) { + return handleMetadataApproval(req, fileMetadataInfo, dirMetadataInfo); + } + updateMetadataDirectly(req, fileMetadataInfo, dirMetadataInfo); + return SdmResponse.success("更新成功"); + } + + uploadAndUpdateFile(req, fileMetadataInfo, fileMetadataInfo.getVersionNo(), fileMetadataInfo.getFileGroupId(), dirMetadataInfo); + return SdmResponse.success("更新成功"); + } + + /** + * 更新前置处理: + *

+ * 1) 解析工况绑定入参(JSON 字符串); + * 2) 当未传递标签时,回填原文件标签; + * 3) 缓存/补齐标签对应的字典ID映射,供后续更新/审批写入使用。 + *

+ * + * @param req 更新请求 + * @return 参数不合法时返回失败响应;正常返回 null 表示继续执行主流程 + */ + private SdmResponse prepareUpdateReq(UpdateFileReq req) { if (StringUtils.hasText(req.getSimulationPoolInfoListStr())) { try { - List list = JSON.parseArray(req.getSimulationPoolInfoListStr(), SimulationPoolInfo.class); - req.setSimulationPoolInfoList(list); + req.setSimulationPoolInfoList(JSON.parseArray(req.getSimulationPoolInfoListStr(), SimulationPoolInfo.class)); } catch (Exception e) { return SdmResponse.failed("参数格式错误"); } } - // 如果未传递新的字典标签,则从原有文件获取并填充 if (CollectionUtils.isEmpty(req.getDictTags())) { fileDictTagQueryService.fillFileTagsForRespList(List.of(req), UpdateFileReq::getId); - - // 如果成功填充了标签值,则设置 dictTags 列表,以便 dictTagHelper 能够识别 List dictTags = buildDictTagsFromEnum(req); - if (!dictTags.isEmpty()) { req.setDictTags(dictTags); - // 强制刷新缓存,确保后续逻辑能获取到ID - // 保存标签缓存到 tempFileMetadataInfo(如果有) - if (CollectionUtils.isNotEmpty(req.getDictTags())) { - Map> dictIdMap = req.getDictTagIdsCache(); - if (dictIdMap == null || dictIdMap.isEmpty()) { - dictIdMap = dictTagHelper.queryAndCacheDictTagIds(req); - } - req.setDictTagIdsCache(dictIdMap); - } } } - FileMetadataInfo fileMetadataInfo = fileMetadataInfoService.lambdaQuery().eq(FileMetadataInfo::getId, req.getId()).one(); - if (fileMetadataInfo == null) { - return SdmResponse.failed("文件不存在"); - } - // 文件夹 - FileMetadataInfo dirMetadataInfo = fileMetadataInfoService.lambdaQuery().eq(FileMetadataInfo::getId, fileMetadataInfo.getParentId()).eq(FileMetadataInfo::getDataType, DataTypeEnum.DIRECTORY.getValue()).one(); - /* boolean hasUploadPermission = fileUserPermissionService.hasFilePermission(fileMetadataInfo.getId(), ThreadLocalContext.getUserId(), FilePermissionEnum.UPLOAD); - if (!hasUploadPermission) { - return SdmResponse.failed("没有更新权限"); - }*/ - Long fileGroupId = fileMetadataInfo.getFileGroupId(); - Long versionNo = fileMetadataInfo.getVersionNo(); - // 修改待审批的元数据主键id - if (ObjectUtils.isEmpty(req.getFile())) { - // 需要审批的目录类型,增加审批的逻辑,先将原始数据改成待审核状态 - if(dirMetadataInfo!=null && DirTypeEnum.isApprovalRequired(dirMetadataInfo.getDirType())){ - FileMetadataInfo tempFileMetadataInfo = new FileMetadataInfo(); - BeanUtils.copyProperties(fileMetadataInfo, tempFileMetadataInfo); - // 不需要上传minio新文件,只更新文件元数据 - // 本次待审核的数据 - tempFileMetadataInfo.setProjectId(req.getProjectId()); - tempFileMetadataInfo.setAnalysisDirectionId(req.getAnalysisDirectionId()); - tempFileMetadataInfo.setRemarks(req.getRemarks()); - tempFileMetadataInfo.setSimulationPoolInfoList(req.getSimulationPoolInfoList()); - tempFileMetadataInfo.setCreateTime(fileMetadataInfo.getCreateTime()); - tempFileMetadataInfo.setUpdaterId(ThreadLocalContext.getUserId()); - tempFileMetadataInfo.setUpdateTime(LocalDateTime.now()); - - // 保存标签缓存到 tempFileMetadataInfo(如果有) - if (CollectionUtils.isNotEmpty(req.getDictTags())) { - Map> dictIdMap = req.getDictTagIdsCache(); - if (dictIdMap == null || dictIdMap.isEmpty()) { - dictIdMap = dictTagHelper.queryAndCacheDictTagIds(req); - } - tempFileMetadataInfo.setDictTagIdsCache(dictIdMap); - } - - - fileMetadataInfo.setTempMetadata(JSONObject.toJSONString(tempFileMetadataInfo)); - fileMetadataInfo.setUpdateTime(LocalDateTime.now()); - fileMetadataInfo.setUpdaterId(ThreadLocalContext.getUserId()); - fileMetadataInfoService.updateById(fileMetadataInfo); - - //发起审批 - FileApproveRequestBuilder updateFileMetaIntoApproveRequestBuilder = FileApproveRequestBuilder.builder() - .toUpdateFileIds(List.of(fileMetadataInfo.getId())) - .contents(DirTypeEnum.buildApprovalTitle(dirMetadataInfo.getDirType(), "文件元数据修改")) - .approveType(ApproveTypeEnum.KNOWLEDGE_APPROVE) - .approveFileActionENUM(ApproveFileActionENUM.MODIFY) - .beforeData(List.of(fileMetadataInfo)) - .afterData(List.of(tempFileMetadataInfo)) - .templateId(req.getTemplateId()) - .templateName(req.getTemplateName()) - .knowledgeBaseName(extractRelativePath(dirMetadataInfo)) - .build(); - if(CollectionUtils.isNotEmpty(updateFileMetaIntoApproveRequestBuilder.getBeforeData())){ - setCreatorNames(updateFileMetaIntoApproveRequestBuilder.getBeforeData()); - setProjectName(updateFileMetaIntoApproveRequestBuilder.getBeforeData()); - setAnalysisDirectionName(updateFileMetaIntoApproveRequestBuilder.getBeforeData()); - setSimulationPoolAndTaskInfo(updateFileMetaIntoApproveRequestBuilder.getBeforeData()); - } - - // 只有修改有 afterData 值 - if (CollectionUtils.isNotEmpty(updateFileMetaIntoApproveRequestBuilder.getAfterData())) { - setCreatorNames(updateFileMetaIntoApproveRequestBuilder.getAfterData()); - setProjectName(updateFileMetaIntoApproveRequestBuilder.getAfterData()); - setAnalysisDirectionName(updateFileMetaIntoApproveRequestBuilder.getAfterData()); - setSimulationPoolAndTaskInfo(updateFileMetaIntoApproveRequestBuilder.getAfterData()); - } - fileApproveExecutor.launchApproveAndUpdateStatus(updateFileMetaIntoApproveRequestBuilder, ApproveFileDataTypeEnum.MODIFY_METADATA_REVIEWING); - - }else { - // 其他场景修改 - // 不需要上传minio新文件,只更新文件元数据 - fileMetadataInfo.setProjectId(req.getProjectId()); - fileMetadataInfo.setAnalysisDirectionId(req.getAnalysisDirectionId()); - fileMetadataInfo.setRemarks(req.getRemarks()); - fileMetadataInfo.setUpdateTime(LocalDateTime.now()); - fileMetadataInfo.setUpdaterId(ThreadLocalContext.getUserId()); - fileMetadataInfo.setFileType(req.getFileType()); - - //绑定文件和工况库的关系 - if (CollectionUtils.isNotEmpty(req.getSimulationPoolInfoList())) { - // 先删除原先所有的文件绑定关系 - fileSimulationMappingService.lambdaUpdate().eq(FileSimulationMapping::getFileId, fileMetadataInfo.getId()).remove(); - for (SimulationPoolInfo simulationPoolInfo : req.getSimulationPoolInfoList()) { - for (String simulationPoolTaskId : simulationPoolInfo.getSimulationPoolTaskIds()) { - FileSimulationMapping fileSimulationMapping = new FileSimulationMapping(); - fileSimulationMapping.setFileId(fileMetadataInfo.getId()); - fileSimulationMapping.setSimulationPoolId(simulationPoolInfo.getSimulationPoolId()); - fileSimulationMapping.setSimulationPoolVersion(simulationPoolInfo.getSimulationPoolVersion()); - fileSimulationMapping.setSimulationPoolTaskId(simulationPoolTaskId); - fileSimulationMappingService.save(fileSimulationMapping); - } - } - } - - // 更新标签(如果有) - if (CollectionUtils.isNotEmpty(req.getDictTags())) { - updateFileTags(req, fileMetadataInfo, dirMetadataInfo); - } - fileMetadataInfoService.updateById(fileMetadataInfo); + if (CollectionUtils.isNotEmpty(req.getDictTags())) { + Map> dictIdMap = req.getDictTagIdsCache(); + if (dictIdMap == null || dictIdMap.isEmpty()) { + dictIdMap = dictTagHelper.queryAndCacheDictTagIds(req); } - - } else { - // 需要上传minio新文件,更新文件元数据 - uploadAndUpdateFile(req, fileMetadataInfo, versionNo, fileGroupId,dirMetadataInfo); + req.setDictTagIdsCache(dictIdMap); } + + return null; + } + + /** + * 发起元数据更新审批: + *

+ * 1) 暂存待修改的元数据(JSONObject 序列化)到 tempMetadata 字段; + * 2) 构建审批请求对象,包含变更前后(Before/After)的数据及相关元信息(项目、人员等); + * 3) 提交审批中心,由其统一管理后续的文件状态流转。 + *

+ * + * @param req 更新请求 + * @param fileMetadataInfo 当前生效的元数据 + * @param dirMetadataInfo 父目录元数据(提供审批模板及路径上下文) + * @return 成功响应 + */ + private SdmResponse handleMetadataApproval(UpdateFileReq req, FileMetadataInfo fileMetadataInfo, FileMetadataInfo dirMetadataInfo) { + FileMetadataInfo tempInfo = new FileMetadataInfo(); + BeanUtils.copyProperties(fileMetadataInfo, tempInfo); + tempInfo.setProjectId(req.getProjectId()); + tempInfo.setAnalysisDirectionId(req.getAnalysisDirectionId()); + tempInfo.setRemarks(req.getRemarks()); + tempInfo.setSimulationPoolInfoList(req.getSimulationPoolInfoList()); + tempInfo.setCreateTime(fileMetadataInfo.getCreateTime()); + tempInfo.setUpdaterId(ThreadLocalContext.getUserId()); + tempInfo.setUpdateTime(LocalDateTime.now()); + + if (CollectionUtils.isNotEmpty(req.getDictTags())) { + Map> dictIdMap = req.getDictTagIdsCache(); + if (dictIdMap == null || dictIdMap.isEmpty()) { + dictIdMap = dictTagHelper.queryAndCacheDictTagIds(req); + } + tempInfo.setDictTagIdsCache(dictIdMap); + } + + fileMetadataInfo.setTempMetadata(JSONObject.toJSONString(tempInfo)); + fileMetadataInfo.setUpdateTime(LocalDateTime.now()); + fileMetadataInfo.setUpdaterId(ThreadLocalContext.getUserId()); + fileMetadataInfoService.updateById(fileMetadataInfo); + + FileApproveRequestBuilder builder = FileApproveRequestBuilder.builder() + .toUpdateFileIds(List.of(fileMetadataInfo.getId())) + .contents(DirTypeEnum.buildApprovalTitle(dirMetadataInfo.getDirType(), "文件元数据修改")) + .approveType(ApproveTypeEnum.KNOWLEDGE_APPROVE) + .approveFileActionENUM(ApproveFileActionENUM.MODIFY) + .beforeData(List.of(fileMetadataInfo)) + .afterData(List.of(tempInfo)) + .templateId(req.getTemplateId()) + .templateName(req.getTemplateName()) + .knowledgeBaseName(extractRelativePath(dirMetadataInfo)) + .build(); + + if (CollectionUtils.isNotEmpty(builder.getBeforeData())) { + setCreatorNames(builder.getBeforeData()); + setProjectName(builder.getBeforeData()); + setAnalysisDirectionName(builder.getBeforeData()); + setSimulationPoolAndTaskInfo(builder.getBeforeData()); + } + + if (CollectionUtils.isNotEmpty(builder.getAfterData())) { + setCreatorNames(builder.getAfterData()); + setProjectName(builder.getAfterData()); + setAnalysisDirectionName(builder.getAfterData()); + setSimulationPoolAndTaskInfo(builder.getAfterData()); + } + + fileApproveExecutor.launchApproveAndUpdateStatus(builder, ApproveFileDataTypeEnum.MODIFY_METADATA_REVIEWING); return SdmResponse.success("更新成功"); } + /** + * 直接更新元数据(无需审批、无需上传新文件)。 + *

+ * 包含:基础字段更新、工况库绑定关系同步、标签关系更新。 + *

+ * + * @param req 更新请求 + * @param fileMetadataInfo 当前文件元数据 + * @param dirMetadataInfo 父目录元数据(用于标签更新时的目录上下文) + */ + private void updateMetadataDirectly(UpdateFileReq req, FileMetadataInfo fileMetadataInfo, FileMetadataInfo dirMetadataInfo) { + fileMetadataInfo.setProjectId(req.getProjectId()); + fileMetadataInfo.setAnalysisDirectionId(req.getAnalysisDirectionId()); + fileMetadataInfo.setRemarks(req.getRemarks()); + fileMetadataInfo.setUpdateTime(LocalDateTime.now()); + fileMetadataInfo.setUpdaterId(ThreadLocalContext.getUserId()); + fileMetadataInfo.setFileType(req.getFileType()); + + if (CollectionUtils.isNotEmpty(req.getSimulationPoolInfoList())) { + fileSimulationMappingService.lambdaUpdate().eq(FileSimulationMapping::getFileId, fileMetadataInfo.getId()).remove(); + for (SimulationPoolInfo poolInfo : req.getSimulationPoolInfoList()) { + for (String taskId : poolInfo.getSimulationPoolTaskIds()) { + FileSimulationMapping mapping = new FileSimulationMapping(); + mapping.setFileId(fileMetadataInfo.getId()); + mapping.setSimulationPoolId(poolInfo.getSimulationPoolId()); + mapping.setSimulationPoolVersion(poolInfo.getSimulationPoolVersion()); + mapping.setSimulationPoolTaskId(taskId); + fileSimulationMappingService.save(mapping); + } + } + } + + if (CollectionUtils.isNotEmpty(req.getDictTags())) { + updateFileTags(req, fileMetadataInfo, dirMetadataInfo); + } + fileMetadataInfoService.updateById(fileMetadataInfo); + } + + /** + * 上传文件并更新元数据。 + * @param req + * @param oldFileMetadataInfo + * @param versionNo + * @param fileGroupId + * @param dirMetadataInfo + */ public void uploadAndUpdateFile(UpdateFileReq req, FileMetadataInfo oldFileMetadataInfo, Long versionNo, Long fileGroupId,FileMetadataInfo dirMetadataInfo) { String newFileMinioObjectKey = ""; try {