From 10e746abd43afda1a36f63208771a0aee627166e Mon Sep 17 00:00:00 2001 From: xudawei Date: Mon, 10 Mar 2025 19:55:02 +0800 Subject: [PATCH 01/15] =?UTF-8?q?feat:(REQ-3540)=20=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=A4=8D=E5=88=B6=E6=8E=A5=E5=8F=A3=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ServerFileController.java | 26 +++-- .../oss/http/api/ServerFileServiceApi.java | 8 ++ .../ServerFileBatchCopyObjectRequest.java | 79 +++++++++++++ .../ServerFileBatchCopyObjectResponse.java | 53 +++++++++ .../oss/integration/s3/AliOssService.java | 6 + .../integration/s3/HuaWeiCloudService.java | 5 +- .../s3/impl/AliOssServiceImpl.java | 14 +++ .../s3/impl/HuaWeiCloudServiceImpl.java | 16 +-- .../cn/axzo/oss/manager/api/FileManager.java | 11 ++ .../api/dto/request/CopyObjectCloudDto.java | 84 ++++++++++++++ .../api/dto/request/FileCopyObjectDto.java | 63 ++++++++++ .../dto/response/FileCopyObjectResponse.java | 71 ++++++++++++ .../oss/manager/impl/FileManagerImpl.java | 36 +++++- .../cn/axzo/oss/service/api/FileService.java | 9 ++ .../oss/service/impl/FileServiceImpl.java | 109 +++++++++++++++++- 15 files changed, 565 insertions(+), 25 deletions(-) create mode 100644 oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java create mode 100644 oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectResponse.java create mode 100644 oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java create mode 100644 oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/FileCopyObjectDto.java create mode 100644 oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/response/FileCopyObjectResponse.java diff --git a/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java b/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java index fd63d7c..bc4a34e 100644 --- a/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java +++ b/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java @@ -1,12 +1,9 @@ package cn.axzo.oss.client.controller; +import cn.axzo.basics.common.util.AssertUtil; import cn.axzo.core.utils.converter.BeanConverter; import cn.axzo.framework.auth.domain.ContextInfo; -import cn.axzo.oss.common.enums.ChannelTypeEnum; -import cn.axzo.oss.common.enums.CodeEnum; -import cn.axzo.oss.common.exception.BizException; import cn.axzo.oss.common.utils.BeanConvertUtil; -import cn.axzo.oss.common.utils.UrlUtil; import cn.axzo.oss.http.api.ServerFileServiceApi; import cn.axzo.oss.http.model.ApiSignUrlDownloadRequest; import cn.axzo.oss.http.model.ApiSignUrlDownloadResponse; @@ -30,27 +27,28 @@ import cn.axzo.oss.http.model.ServerFileUploadByUrlRequest; import cn.axzo.oss.http.model.ServerFileUploadRequest; import cn.axzo.oss.http.model.ServerFileUploadResponse; import cn.axzo.oss.http.model.ServerFileUploadV2Request; +import cn.axzo.oss.http.model.copyobject.ServerFileBatchCopyObjectRequest; +import cn.axzo.oss.http.model.copyobject.ServerFileBatchCopyObjectResponse; +import cn.axzo.oss.manager.api.dto.request.FileCopyObjectDto; import cn.axzo.oss.manager.api.dto.request.FindFileKeyDto; import cn.axzo.oss.manager.api.dto.request.FindFileUrlDto; -import cn.axzo.oss.manager.api.dto.request.ServerFileCopyToDictDto; import cn.axzo.oss.manager.api.dto.request.GetObjectMetaDto; +import cn.axzo.oss.manager.api.dto.request.ServerFileCopyToDictDto; import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto; import cn.axzo.oss.manager.api.dto.request.ServerFileUploadByUrlDto; import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlDownloadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto; -import cn.axzo.oss.manager.api.dto.response.ManaGetObjectMetaResponse; +import cn.axzo.oss.manager.api.dto.response.FileCopyObjectResponse; import cn.axzo.oss.service.api.FileByUrlService; import cn.axzo.oss.service.api.FileCopyToDictService; import cn.axzo.oss.service.api.FileService; import cn.azxo.framework.common.model.CommonResponse; +import cn.hutool.core.bean.BeanUtil; import cn.hutool.json.JSONUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; @@ -231,4 +229,14 @@ public class ServerFileController implements ServerFileServiceApi { dto.setBizScene(dto.getAppCode() + "-public"); return CommonResponse.success(BeanConverter.convert(fileService.signUrlUpload(dto, ContextInfo.LiteSaasContext.builder().build()), FetchUploadSignUrlToPublishResponse.class)); } + + /** + * 复制文件 + */ + public CommonResponse batchCopyObject(ServerFileBatchCopyObjectRequest request) { + AssertUtil.isFalse(Objects.isNull(request) || CollectionUtils.isEmpty(request.getCopyObjects()), "入参为空"); + List fileCopyObjectDtos = BeanUtil.copyToList(request.getCopyObjects(), FileCopyObjectDto.class); + List fileCopyObjectResponses = fileService.batchCopyObject(fileCopyObjectDtos, request.getAppCode()); + return CommonResponse.success(ServerFileBatchCopyObjectResponse.builder().responses(BeanUtil.copyToList(fileCopyObjectResponses, ServerFileBatchCopyObjectResponse.ServerFileCopyObjectResponse.class)).build()); + } } diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java b/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java index d2ae113..09ac9b4 100644 --- a/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java @@ -22,6 +22,8 @@ import cn.axzo.oss.http.model.ServerFileUploadByUrlRequest; import cn.axzo.oss.http.model.ServerFileUploadRequest; import cn.axzo.oss.http.model.ServerFileUploadResponse; import cn.axzo.oss.http.model.ServerFileUploadV2Request; +import cn.axzo.oss.http.model.copyobject.ServerFileBatchCopyObjectRequest; +import cn.axzo.oss.http.model.copyobject.ServerFileBatchCopyObjectResponse; import cn.azxo.framework.common.model.CommonResponse; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.RequestBody; @@ -135,4 +137,10 @@ public interface ServerFileServiceApi { @RequestMapping(value = "/api/server/copyToDict", method = RequestMethod.POST) CommonResponse copyToDict(ServerFileCopyToDictRequest request); + /** + * 复制文件 + */ + @RequestMapping(value = "/api/server/batchCopyObject", method = RequestMethod.POST) + CommonResponse batchCopyObject(ServerFileBatchCopyObjectRequest request); + } diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java new file mode 100644 index 0000000..61b6dce --- /dev/null +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java @@ -0,0 +1,79 @@ +package cn.axzo.oss.http.model.copyobject; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import java.util.Set; + +/** + * 批量复制对象 + * + * @author xudawei + * @date 2025-03-07 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ServerFileBatchCopyObjectRequest { + + @NotBlank(message = "appCode must not be null") + private String appCode; + + @NotEmpty(message = "集合对象不能为空") + private Set copyObjects; + + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class ServerFileCopyObjectRequest { + /** + * 唯一标识 + * 没有唯一标识,可以与fileKey一致 + */ + @NotBlank(message = "唯一性标识不能为空") + private String fileUuid; + + /** + * 目标桶 + * 如果目标桶为空,则默认取源桶 + */ + private String targetBucketName; + + /** + * 目标目录 + * 如果目标目录为空,则默认在源目录同级 + */ + private String targetDict; + + /** + * 目标通道 + * 如果目标通道为空,则默认源通道 + */ + private String targetChannelCode; + + /** + * 文件名称 + */ + private String targetFileName; + + /** + * 桶名称 + */ + private String srcBucketName; + /** + * 桶文件目录 + */ + private String srcBucketKey; + /** + * 文件对象key + */ + private String srcFileKey; + + } +} diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectResponse.java b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectResponse.java new file mode 100644 index 0000000..e86ff71 --- /dev/null +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectResponse.java @@ -0,0 +1,53 @@ +package cn.axzo.oss.http.model.copyobject; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 复制至指定目录下 + * + * @author xudawei + * @date 2024-07-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class ServerFileBatchCopyObjectResponse { + + private List responses; + + @Data + @AllArgsConstructor + @NoArgsConstructor + @Builder + public static class ServerFileCopyObjectResponse { + /** + * 与入参中的id一致 + */ + private String id; + + /** + * 原文件的fileKey + */ + private String oldFileKey; + + /** + * 原文件的url + */ + private String oldFileUrl; + + /** + * 新文件的filekey + */ + private String newFileKey; + + private String newUrl; + + } + +} diff --git a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/AliOssService.java b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/AliOssService.java index 2d9dd56..ad323db 100644 --- a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/AliOssService.java +++ b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/AliOssService.java @@ -1,6 +1,7 @@ package cn.axzo.oss.integration.s3; import cn.axzo.oss.integration.s3.base.BaseS3Service; +import com.aliyun.oss.model.CopyObjectResult; import com.aliyun.oss.model.SimplifiedObjectMeta; /** @@ -40,4 +41,9 @@ public interface AliOssService extends BaseS3Service { * 通过url上传至OBS */ String uploadByUrl(String bucketName, String tgtFileKey, String fileName, String url); + + /** + * 复制对象 + */ + CopyObjectResult copyObject(String bucketName, String key, String targetBucketName, String targetKey); } diff --git a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/HuaWeiCloudService.java b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/HuaWeiCloudService.java index efe3385..8f9ea90 100644 --- a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/HuaWeiCloudService.java +++ b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/HuaWeiCloudService.java @@ -1,5 +1,6 @@ package cn.axzo.oss.integration.s3; +import com.obs.services.model.CopyObjectResult; import com.obs.services.model.ObjectMetadata; import com.obs.services.model.TemporarySignatureResponse; @@ -53,7 +54,7 @@ public interface HuaWeiCloudService { ObjectMetadata getObjectMeta(String bucketName, String key, String url); /** - * 元数据 + * 复制对象 */ - boolean copyToDict(String bucketName, String key, String targetBucketName, String targetKey); + CopyObjectResult copyObject(String bucketName, String key, String targetBucketName, String targetKey); } diff --git a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/AliOssServiceImpl.java b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/AliOssServiceImpl.java index e33c963..08b74a9 100644 --- a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/AliOssServiceImpl.java +++ b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/AliOssServiceImpl.java @@ -11,6 +11,7 @@ import com.aliyun.oss.HttpMethod; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSException; import com.aliyun.oss.model.CompleteMultipartUploadRequest; +import com.aliyun.oss.model.CopyObjectResult; import com.aliyun.oss.model.GeneratePresignedUrlRequest; import com.aliyun.oss.model.GetObjectRequest; import com.aliyun.oss.model.InitiateMultipartUploadRequest; @@ -415,4 +416,17 @@ public class AliOssServiceImpl implements AliOssService { return getUrl(bucketName, tgtFileKey); } + + /** + * 复制对象 + */ + @Override + public CopyObjectResult copyObject(String bucketName, String key, String targetBucketName, String targetKey) { + try { + return aliOssClient.getClient().copyObject(bucketName, key, targetBucketName, targetKey); + } catch (Exception e) { + log.warn("aliyun-copyObject-exception, bucketName:{}, key:{}", bucketName, key, e); + return null; + } + } } diff --git a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/HuaWeiCloudServiceImpl.java b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/HuaWeiCloudServiceImpl.java index 2a5697e..6ffe292 100644 --- a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/HuaWeiCloudServiceImpl.java +++ b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/HuaWeiCloudServiceImpl.java @@ -15,7 +15,7 @@ import com.obs.services.ObsClient; import com.obs.services.exception.ObsException; import com.obs.services.model.CompleteMultipartUploadRequest; import com.obs.services.model.CompleteMultipartUploadResult; -import com.obs.services.model.CopyObjectRequest; +import com.obs.services.model.CopyObjectResult; import com.obs.services.model.DeleteObjectResult; import com.obs.services.model.DownloadFileRequest; import com.obs.services.model.DownloadFileResult; @@ -475,21 +475,15 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService { } /** - * 元数据 + * 复制对象 */ @Override - public boolean copyToDict(String bucketName, String key, String targetBucketName, String targetKey) { + public CopyObjectResult copyObject(String bucketName, String key, String targetBucketName, String targetKey) { try { - CopyObjectRequest request = new CopyObjectRequest(); - request.setSourceBucketName(bucketName); - request.setSourceObjectKey(key); - request.setDestinationBucketName(targetBucketName); - request.setDestinationObjectKey(targetKey); - huaWeiCloudObsClient.getClient().copyObject(request); - return true; + return huaWeiCloudObsClient.getClient().copyObject(bucketName, key, targetBucketName, targetKey); } catch (Exception e) { log.warn("huaweicloud-copyToDict-exception, bucketName:{}, key:{}", bucketName, key, e); - return false; + return null; } } diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/FileManager.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/FileManager.java index 1f4cb88..a53a04e 100644 --- a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/FileManager.java +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/FileManager.java @@ -1,6 +1,7 @@ package cn.axzo.oss.manager.api; import cn.axzo.oss.manager.api.dto.PartETag; +import cn.axzo.oss.manager.api.dto.request.CopyObjectCloudDto; import cn.axzo.oss.manager.api.dto.request.MultipartUploadDto; import cn.axzo.oss.manager.api.dto.response.ManaGetObjectMetaResponse; import cn.axzo.oss.manager.api.dto.response.SignUrlDownloadResponse; @@ -95,4 +96,14 @@ public interface FileManager { * 构建公开Style */ String buildPublicXImageProcess(String url, String style); + + /** + * 复制对象 + */ + Boolean copyObjects(CopyObjectCloudDto dto); + + /** + * 相同的通道-对象复制 + */ + Boolean copyObjectWhenSameChannel(CopyObjectCloudDto dto); } diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java new file mode 100644 index 0000000..f0cdd21 --- /dev/null +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java @@ -0,0 +1,84 @@ +package cn.axzo.oss.manager.api.dto.request; + +import cn.axzo.oss.common.utils.Utility; +import cn.axzo.oss.dal.entity.File; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + +/** + * @author xudawei@axzo.cn + * @date 2025/3/10 + * @description 对象复制Dto + */ +@Builder +@Data +@AllArgsConstructor +@NoArgsConstructor +public class CopyObjectCloudDto { + + /** + * 源桶名称 + * 比如:axzo-oss + */ + private String srcBucketName; + /** + * 源桶key(三方的桶上的目录+文件名称) + * 比如 zeus/recruit_collect/93248404217a4576ba2698183c3fc7a1.xlsx + */ + private String srcBucketKey; + /** + * 源通道 + */ + private String srcChannelCode; + /** + * 源Url + */ + private String srcUrl; + + /** + * 目的桶名称 + */ + private String targetBucketName; + /** + * 目的桶key(三方的桶上的目录+文件名称) + */ + private String targetBucketKey; + /** + * 目的key(文件唯一标识) + * 比如:93248404217a4576ba2698183c3fc7a1 + */ + private String targetKey; + private String targetChannelCode; + + private String fileName; + + private File file; + private String fileUuid; + + public static CopyObjectCloudDto create(FileCopyObjectDto fileCopyObjectRequest, File file) { + // 入参中有通道,则优先取入参;否则取源通道 + String targetChannelCode = StringUtils.isBlank(fileCopyObjectRequest.getTargetChannelCode()) ? file.getChannelCode() : fileCopyObjectRequest.getTargetChannelCode(); + String targetBucketName = StringUtils.isBlank(fileCopyObjectRequest.getTargetBucketName()) ? file.getBucketName() : fileCopyObjectRequest.getTargetBucketName(); + String targetBucketDict = StringUtils.isBlank(fileCopyObjectRequest.getTargetDict()) ? file.getDirectory() : fileCopyObjectRequest.getTargetDict(); + String fileName = StringUtils.isBlank(fileCopyObjectRequest.getTargetFileName()) ? file.getFileName() : fileCopyObjectRequest.getTargetFileName(); + + String uuid = Utility.getUUID(); + + return CopyObjectCloudDto.builder() + .srcBucketName(file.getBucketName()) + .srcBucketKey(Utility.generateFileKey(file.getDirectory(), file.getFileUuid(), file.getFileFormat())) + .srcChannelCode(file.getChannelCode()) + .targetBucketName(targetBucketName) + .targetBucketKey(Utility.generateFileKey(targetBucketDict, uuid, file.getFileFormat())) + .targetKey(uuid) + .targetChannelCode(targetChannelCode) + .fileName(fileName) + .file(file) + .fileUuid(fileCopyObjectRequest.getFileUuid()) + .build(); + } + +} diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/FileCopyObjectDto.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/FileCopyObjectDto.java new file mode 100644 index 0000000..6aa248a --- /dev/null +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/FileCopyObjectDto.java @@ -0,0 +1,63 @@ +package cn.axzo.oss.manager.api.dto.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; + +/** + * @author xudawei@axzo.cn + * @date 2025/3/10 + * @description 对象复制DTO + */ +@Builder +@Data +@AllArgsConstructor +@NoArgsConstructor +public class FileCopyObjectDto { + + /** + * 唯一标识 + * 没有唯一标识,可以与fileKey一致 + */ + private String fileUuid; + + /** + * 目标桶 + * 如果目标桶为空,则默认取源桶 + */ + private String targetBucketName; + + /** + * 目标目录 + * 如果目标目录为空,则默认在源目录同级 + */ + private String targetDict; + + /** + * 目标通道 + * 如果目标通道为空,则默认源通道 + */ + private String targetChannelCode; + + /** + * 文件名称 + */ + private String targetFileName; + + /** + * 桶名称 + */ + private String srcBucketName; + /** + * 桶文件目录 + */ + private String srcBucketKey; + /** + * 文件对象key + */ + private String srcFileKey; + +} diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/response/FileCopyObjectResponse.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/response/FileCopyObjectResponse.java new file mode 100644 index 0000000..1066216 --- /dev/null +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/response/FileCopyObjectResponse.java @@ -0,0 +1,71 @@ +package cn.axzo.oss.manager.api.dto.response; + +import cn.axzo.oss.manager.api.dto.request.CopyObjectCloudDto; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; + +/** + * @author xudawei@axzo.cn + * @date 2025/3/10 + * @description 对象复制DTO + */ +@Builder +@Data +@AllArgsConstructor +@NoArgsConstructor +public class FileCopyObjectResponse { + + /** + * 唯一标识,没有唯一标识,可以与fileKey一致 + */ + @NotBlank(message = "唯一性标识不能为空") + private String fileUuid; + + /** + * 目标桶 + * 如果目标桶为空,则默认取源桶 + */ + private String targetFileKey; + + /** + * 目标通道 + * 如果目标通道为空,则默认源通道 + */ + private String targetChannelCode; + + /** + * 桶名称 + */ + private String bucketName; + /** + * 桶文件目录 + */ + private String bucketDict; + /** + * 文件对象key + */ + private String fileKey; + + /** + * 文件名称 + */ + private String fileName; + + public static FileCopyObjectResponse create(CopyObjectCloudDto item) { + return FileCopyObjectResponse.builder() + .fileUuid(item.getFileUuid()) + .targetFileKey(item.getTargetKey()) + .targetChannelCode(item.getTargetChannelCode()) +// .targetDownloadUrl(this.fileManager.fetchDownloadUrl(item.getFile().getb)) + .bucketName(item.getFile().getBucketName()) + .bucketDict(item.getFile().getDirectory()) + .fileKey(item.getFile().getFileUuid()) + .fileName(item.getFileName()) + .build(); + } + +} diff --git a/oss-manager/src/main/java/cn/axzo/oss/manager/impl/FileManagerImpl.java b/oss-manager/src/main/java/cn/axzo/oss/manager/impl/FileManagerImpl.java index 89833a6..6b69777 100644 --- a/oss-manager/src/main/java/cn/axzo/oss/manager/impl/FileManagerImpl.java +++ b/oss-manager/src/main/java/cn/axzo/oss/manager/impl/FileManagerImpl.java @@ -12,12 +12,13 @@ import cn.axzo.oss.integration.s3.AliOssService; import cn.axzo.oss.integration.s3.HuaWeiCloudService; import cn.axzo.oss.manager.api.FileManager; import cn.axzo.oss.manager.api.dto.PartETag; +import cn.axzo.oss.manager.api.dto.request.CopyObjectCloudDto; import cn.axzo.oss.manager.api.dto.request.MultipartUploadDto; import cn.axzo.oss.manager.api.dto.response.ManaGetObjectMetaResponse; import cn.axzo.oss.manager.api.dto.response.SignUrlDownloadResponse; import cn.axzo.oss.manager.api.vo.SignUrlUploadVo; -import com.alibaba.fastjson.JSON; import com.aliyun.oss.model.SimplifiedObjectMeta; +import com.obs.services.model.CopyObjectResult; import com.obs.services.model.ObjectMetadata; import com.obs.services.model.TemporarySignatureResponse; import lombok.extern.slf4j.Slf4j; @@ -346,4 +347,37 @@ public class FileManagerImpl implements FileManager { return url; } + /** + * 复制对象 + */ + @Override + public Boolean copyObjects(CopyObjectCloudDto dto) { + // 相同的通道-对象复制 + if (dto.getSrcChannelCode().equals(dto.getTargetChannelCode())) { + return this.copyObjectWhenSameChannel(dto); + } + // 不同的通道,通过url上传至云(通过url复制至云) + String url = this.uploadByUrl(dto.getTargetBucketName(), dto.getTargetKey(), dto.getFileName(), dto.getSrcUrl(), dto.getTargetChannelCode()); + return StringUtils.isBlank(url) ? false : true; + } + + /** + * 相同的通道-对象复制 + */ + public Boolean copyObjectWhenSameChannel(CopyObjectCloudDto dto) { + ChannelTypeEnum typeEnum = ChannelTypeEnum.getChannelTypeByChannelCode(dto.getSrcChannelCode()); + switch (typeEnum) { + case OBS:// 华为云 + CopyObjectResult huaweiResult = huaWeiCloudService.copyObject(dto.getSrcBucketName(), dto.getSrcBucketKey(), dto.getTargetBucketName(), dto.getTargetKey()); + return Objects.isNull(huaweiResult) ? false : true; + case OSS:// 阿里云 + com.aliyun.oss.model.CopyObjectResult aliResult = aliOssService.copyObject(dto.getSrcBucketName(), dto.getSrcBucketKey(), dto.getTargetBucketName(), dto.getTargetKey()); + return Objects.isNull(aliResult) ? false : true; + default: + BizException.error(CodeEnum.CHANNEL_TYPE_NOT_EXIST); + } + return false; + } + + } diff --git a/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileService.java b/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileService.java index 441ee11..2194d9f 100644 --- a/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileService.java +++ b/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileService.java @@ -4,6 +4,7 @@ import cn.axzo.framework.auth.domain.ContextInfo; import cn.axzo.oss.dal.entity.AppChannelBucket; import cn.axzo.oss.dal.entity.FileUploadConfig; import cn.axzo.oss.manager.api.dto.request.DeleteFileDto; +import cn.axzo.oss.manager.api.dto.request.FileCopyObjectDto; import cn.axzo.oss.manager.api.dto.request.FindFileKeyDto; import cn.axzo.oss.manager.api.dto.request.FindFileUrlDto; import cn.axzo.oss.manager.api.dto.request.GetObjectMetaDto; @@ -16,6 +17,7 @@ import cn.axzo.oss.manager.api.dto.request.ServerFileDownloadDto; import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlDownloadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto; +import cn.axzo.oss.manager.api.dto.response.FileCopyObjectResponse; import cn.axzo.oss.manager.api.dto.response.FileInformationResponse; import cn.axzo.oss.manager.api.dto.response.FindFileKeyResponse; import cn.axzo.oss.manager.api.dto.response.FindFileUrlResponse; @@ -117,4 +119,11 @@ public interface FileService { * 授权给第三方下载 */ List signUrlDownloadNoFile(SignUrlDownloadDto dto); + + /** + * 复制文件 + * 1 不同通道,则通过url进行复制 + * 2 相同通道,则直接调用复制方法 + */ + List batchCopyObject(List dtoList, String appCode); } diff --git a/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java index d89782d..16c454a 100644 --- a/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java +++ b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java @@ -1,5 +1,6 @@ package cn.axzo.oss.service.impl; +import cn.axzo.basics.common.util.AssertUtil; import cn.axzo.core.utils.converter.BeanConverter; import cn.axzo.framework.auth.domain.ContextInfo; import cn.axzo.log.platform.client.LogPlatClient; @@ -31,7 +32,9 @@ import cn.axzo.oss.manager.api.FileBusinessSceneManager; import cn.axzo.oss.manager.api.FileManager; import cn.axzo.oss.manager.api.FileUploadConfigManager; import cn.axzo.oss.manager.api.dto.PartETag; +import cn.axzo.oss.manager.api.dto.request.CopyObjectCloudDto; import cn.axzo.oss.manager.api.dto.request.DeleteFileDto; +import cn.axzo.oss.manager.api.dto.request.FileCopyObjectDto; import cn.axzo.oss.manager.api.dto.request.FindFileKeyDto; import cn.axzo.oss.manager.api.dto.request.FindFileUrlDto; import cn.axzo.oss.manager.api.dto.request.GetObjectMetaDto; @@ -44,6 +47,7 @@ import cn.axzo.oss.manager.api.dto.request.ServerFileDownloadDto; import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlDownloadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto; +import cn.axzo.oss.manager.api.dto.response.FileCopyObjectResponse; import cn.axzo.oss.manager.api.dto.response.FileInformationResponse; import cn.axzo.oss.manager.api.dto.response.FindFileKeyResponse; import cn.axzo.oss.manager.api.dto.response.FindFileUrlResponse; @@ -54,11 +58,9 @@ import cn.axzo.oss.manager.api.dto.response.ServerFileDownloadResponse; import cn.axzo.oss.manager.api.dto.response.ServerFileUploadResponse; import cn.axzo.oss.manager.api.dto.response.SignUrlDownloadResponse; import cn.axzo.oss.manager.api.dto.response.SignUrlUploadResponse; -import cn.axzo.oss.manager.api.vo.SignUrlUploadVo; import cn.axzo.oss.service.api.FileService; import cn.axzo.oss.service.metafile.WithFileFactory; import cn.axzo.oss.service.metafile.WithFileService; -import cn.azxo.framework.common.model.CommonResponse; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.lang.Pair; @@ -89,6 +91,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.CompletableFuture; +import java.util.function.Function; import java.util.stream.Collectors; import static cn.axzo.oss.common.constans.CommonConstants.APP_PRO_BUCKET_NAME; @@ -1258,4 +1261,106 @@ public class FileServiceImpl implements FileService { }).collect(Collectors.toList()); } + /** + * 复制文件 + * 1 不同通道,则通过url进行复制 + * 2 相同通道,则直接调用复制方法 + */ + public List batchCopyObject(List dtoList, String appCode) { + AssertUtil.isFalse(CollectionUtils.isEmpty(dtoList), "请求入参为空"); + //校验appCode + this.checkAppCode(appCode); + //通过fileKeys复制文件 + List cloudDtos = this.batchCopyObjectByFileKeys(dtoList); + //保存文件表 + return this.saveFiles(cloudDtos); + } + + /** + * 保存文件表 + */ + private List saveFiles(List cloudDtos) { + List responses = new ArrayList<>(); + + List fileList = cloudDtos.stream().map(item -> { + //复制文件-构建file对象 + File ossFile = this.buildFileWhenCopyObject(item); + //构建返回对象 + responses.add(FileCopyObjectResponse.create(item)); + return ossFile; + }).collect(Collectors.toList()); + + if (CollectionUtil.isEmpty(cloudDtos)) { + return Lists.newArrayList(); + } + this.fileDao.saveBatch(fileList); + return responses; + } + + /** + * 复制文件-构建file对象 + */ + private File buildFileWhenCopyObject(CopyObjectCloudDto item) { + File ossFile = new File(); + ossFile.setAppChannelBucketNo(item.getFile().getAppChannelBucketNo()); + ossFile.setAppCode(item.getFile().getAppCode()); + ossFile.setChannelCode(item.getTargetChannelCode()); + ossFile.setBucketName(item.getTargetBucketName()); + ossFile.setDirectory(item.getTargetBucketKey()); + ossFile.setStorageUnit(item.getFile().getStorageUnit()); + ossFile.setStorageSize(item.getFile().getStorageSize()); + ossFile.setFileFormat(item.getFile().getFileFormat()); + ossFile.setFileUuid(item.getTargetKey()); + ossFile.setFileUrl(this.fileManager.fetchDownloadUrl(item.getTargetBucketName(), Utility.generateFileKey(item.getTargetBucketKey(), item.getTargetKey(), item.getFile().getFileFormat()), item.getTargetChannelCode())); + ossFile.setUrlMd5(Utility.getMd5(ossFile.getFileUrl())); + ossFile.setStatus(FileStatusEnum.STATUS_UPLOAD_SUCCESS.getCode()); + ossFile.setFileName(item.getFileName()); + ossFile.setFileMd5(Utility.getMd5(ossFile.getFileUrl())); + return ossFile; + } + + /** + * 通过fileKeys复制文件 + */ + private List batchCopyObjectByFileKeys(List dtoList) { + List fileKeys = dtoList.stream() + .filter(item -> StringUtils.isNotBlank(item.getSrcFileKey())) + .map(FileCopyObjectDto::getSrcFileKey).collect(Collectors.toList()); + + Map reqFileKeyMap = dtoList.stream() + .filter(item -> StringUtils.isNotBlank(item.getSrcFileKey())) + .collect(Collectors.toMap(item -> item.getSrcFileKey(), Function.identity())); + //查询file数据表获取源对象 + List fileList = fileDao.getByFileUuids(fileKeys); + + if (CollectionUtil.isEmpty(fileList)) { + return Lists.newArrayList(); + } + //通过文件表,完成文件对象复制 + return this.doBatchCopyObjectByFiles(reqFileKeyMap, fileList); + } + + /** + * 通过文件表-文件对象复制 + * 注意,此方法是根据业务文件复制 + * 底层通用方法fileManager.copyObjects(dto); + */ + private List doBatchCopyObjectByFiles(Map reqFileKeyMap, List fileList) { + List returnList = Lists.newArrayList(); + for (File file : fileList) { + if (Objects.isNull(reqFileKeyMap.get(file.getFileUuid()))) { + continue; + } + FileCopyObjectDto fileCopyObjectRequest = reqFileKeyMap.get(file.getFileUuid()); + if (Objects.isNull(fileCopyObjectRequest)) { + continue; + } + CopyObjectCloudDto dto = CopyObjectCloudDto.create(fileCopyObjectRequest, file); + + this.fileManager.copyObjects(dto); + returnList.add(dto); + } + return returnList; + } + } From 503826f5cab88bca96837dc3f635297a3d0b9821 Mon Sep 17 00:00:00 2001 From: xudawei Date: Tue, 11 Mar 2025 11:45:16 +0800 Subject: [PATCH 02/15] =?UTF-8?q?feat:(REQ-3540)=20=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=A4=8D=E5=88=B6=E6=8E=A5=E5=8F=A3-=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ServerFileController.java | 2 +- .../oss/http/api/ServerFileServiceApi.java | 2 +- .../ServerFileBatchCopyObjectRequest.java | 2 +- .../ServerFileBatchCopyObjectResponse.java | 31 +++++++++++++------ .../api/dto/request/CopyObjectCloudDto.java | 11 +++++-- .../api/dto/request/SignUrlDownloadDto.java | 2 -- .../dto/response/FileCopyObjectResponse.java | 16 +++++----- .../oss/manager/impl/FileManagerImpl.java | 4 +-- .../oss/service/impl/FileServiceImpl.java | 4 +-- 9 files changed, 46 insertions(+), 28 deletions(-) diff --git a/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java b/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java index bc4a34e..f4fbe75 100644 --- a/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java +++ b/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java @@ -233,7 +233,7 @@ public class ServerFileController implements ServerFileServiceApi { /** * 复制文件 */ - public CommonResponse batchCopyObject(ServerFileBatchCopyObjectRequest request) { + public CommonResponse batchCopyObject(@Valid @RequestBody ServerFileBatchCopyObjectRequest request) { AssertUtil.isFalse(Objects.isNull(request) || CollectionUtils.isEmpty(request.getCopyObjects()), "入参为空"); List fileCopyObjectDtos = BeanUtil.copyToList(request.getCopyObjects(), FileCopyObjectDto.class); List fileCopyObjectResponses = fileService.batchCopyObject(fileCopyObjectDtos, request.getAppCode()); diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java b/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java index 09ac9b4..3694a53 100644 --- a/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java @@ -141,6 +141,6 @@ public interface ServerFileServiceApi { * 复制文件 */ @RequestMapping(value = "/api/server/batchCopyObject", method = RequestMethod.POST) - CommonResponse batchCopyObject(ServerFileBatchCopyObjectRequest request); + CommonResponse batchCopyObject(@Valid @RequestBody ServerFileBatchCopyObjectRequest request); } diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java index 61b6dce..d41fac4 100644 --- a/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java @@ -67,7 +67,7 @@ public class ServerFileBatchCopyObjectRequest { */ private String srcBucketName; /** - * 桶文件目录 + * 桶文件路径(目录+文件) */ private String srcBucketKey; /** diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectResponse.java b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectResponse.java index e86ff71..e7dc4dc 100644 --- a/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectResponse.java +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectResponse.java @@ -27,26 +27,39 @@ public class ServerFileBatchCopyObjectResponse { @Builder public static class ServerFileCopyObjectResponse { /** - * 与入参中的id一致 + * 唯一标识,没有唯一标识,可以与fileKey一致 */ - private String id; + private String fileUuid; /** - * 原文件的fileKey + * 目标桶 + * 如果目标桶为空,则默认取源桶 */ - private String oldFileKey; + private String targetFileKey; /** - * 原文件的url + * 目标通道 + * 如果目标通道为空,则默认源通道 */ - private String oldFileUrl; + private String targetChannelCode; /** - * 新文件的filekey + * 桶名称 */ - private String newFileKey; + private String srcBucketName; + /** + * 桶文件目录 + */ + private String srcBucketDict; + /** + * 文件对象key + */ + private String srcFileKey; - private String newUrl; + /** + * 文件名称 + */ + private String srcFileName; } diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java index f0cdd21..90375ca 100644 --- a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java @@ -42,6 +42,12 @@ public class CopyObjectCloudDto { * 目的桶名称 */ private String targetBucketName; + + /** + * 目的桶目录 + */ + private String targetBucketDict; + /** * 目的桶key(三方的桶上的目录+文件名称) */ @@ -53,7 +59,7 @@ public class CopyObjectCloudDto { private String targetKey; private String targetChannelCode; - private String fileName; + private String targetFileName; private File file; private String fileUuid; @@ -72,10 +78,11 @@ public class CopyObjectCloudDto { .srcBucketKey(Utility.generateFileKey(file.getDirectory(), file.getFileUuid(), file.getFileFormat())) .srcChannelCode(file.getChannelCode()) .targetBucketName(targetBucketName) + .targetBucketDict(targetBucketDict) .targetBucketKey(Utility.generateFileKey(targetBucketDict, uuid, file.getFileFormat())) .targetKey(uuid) .targetChannelCode(targetChannelCode) - .fileName(fileName) + .targetFileName(fileName) .file(file) .fileUuid(fileCopyObjectRequest.getFileUuid()) .build(); diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/SignUrlDownloadDto.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/SignUrlDownloadDto.java index 078fc8e..007222a 100644 --- a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/SignUrlDownloadDto.java +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/SignUrlDownloadDto.java @@ -5,9 +5,7 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import java.util.List; diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/response/FileCopyObjectResponse.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/response/FileCopyObjectResponse.java index 1066216..76773b8 100644 --- a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/response/FileCopyObjectResponse.java +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/response/FileCopyObjectResponse.java @@ -40,20 +40,20 @@ public class FileCopyObjectResponse { /** * 桶名称 */ - private String bucketName; + private String srcBucketName; /** * 桶文件目录 */ - private String bucketDict; + private String srcBucketDict; /** * 文件对象key */ - private String fileKey; + private String srcFileKey; /** * 文件名称 */ - private String fileName; + private String srcFileName; public static FileCopyObjectResponse create(CopyObjectCloudDto item) { return FileCopyObjectResponse.builder() @@ -61,10 +61,10 @@ public class FileCopyObjectResponse { .targetFileKey(item.getTargetKey()) .targetChannelCode(item.getTargetChannelCode()) // .targetDownloadUrl(this.fileManager.fetchDownloadUrl(item.getFile().getb)) - .bucketName(item.getFile().getBucketName()) - .bucketDict(item.getFile().getDirectory()) - .fileKey(item.getFile().getFileUuid()) - .fileName(item.getFileName()) + .srcBucketName(item.getFile().getBucketName()) + .srcBucketDict(item.getFile().getDirectory()) + .srcFileKey(item.getFile().getFileUuid()) + .srcFileName(item.getTargetFileName()) .build(); } diff --git a/oss-manager/src/main/java/cn/axzo/oss/manager/impl/FileManagerImpl.java b/oss-manager/src/main/java/cn/axzo/oss/manager/impl/FileManagerImpl.java index 6b69777..692e647 100644 --- a/oss-manager/src/main/java/cn/axzo/oss/manager/impl/FileManagerImpl.java +++ b/oss-manager/src/main/java/cn/axzo/oss/manager/impl/FileManagerImpl.java @@ -357,7 +357,7 @@ public class FileManagerImpl implements FileManager { return this.copyObjectWhenSameChannel(dto); } // 不同的通道,通过url上传至云(通过url复制至云) - String url = this.uploadByUrl(dto.getTargetBucketName(), dto.getTargetKey(), dto.getFileName(), dto.getSrcUrl(), dto.getTargetChannelCode()); + String url = this.uploadByUrl(dto.getTargetBucketName(), dto.getTargetKey(), dto.getTargetFileName(), dto.getSrcUrl(), dto.getTargetChannelCode()); return StringUtils.isBlank(url) ? false : true; } @@ -368,7 +368,7 @@ public class FileManagerImpl implements FileManager { ChannelTypeEnum typeEnum = ChannelTypeEnum.getChannelTypeByChannelCode(dto.getSrcChannelCode()); switch (typeEnum) { case OBS:// 华为云 - CopyObjectResult huaweiResult = huaWeiCloudService.copyObject(dto.getSrcBucketName(), dto.getSrcBucketKey(), dto.getTargetBucketName(), dto.getTargetKey()); + CopyObjectResult huaweiResult = huaWeiCloudService.copyObject(dto.getSrcBucketName(), dto.getSrcBucketKey(), dto.getTargetBucketName(), dto.getTargetBucketKey()); return Objects.isNull(huaweiResult) ? false : true; case OSS:// 阿里云 com.aliyun.oss.model.CopyObjectResult aliResult = aliOssService.copyObject(dto.getSrcBucketName(), dto.getSrcBucketKey(), dto.getTargetBucketName(), dto.getTargetKey()); diff --git a/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java index 16c454a..81d9dd0 100644 --- a/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java +++ b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java @@ -1306,7 +1306,7 @@ public class FileServiceImpl implements FileService { ossFile.setAppCode(item.getFile().getAppCode()); ossFile.setChannelCode(item.getTargetChannelCode()); ossFile.setBucketName(item.getTargetBucketName()); - ossFile.setDirectory(item.getTargetBucketKey()); + ossFile.setDirectory(item.getTargetBucketDict()); ossFile.setStorageUnit(item.getFile().getStorageUnit()); ossFile.setStorageSize(item.getFile().getStorageSize()); ossFile.setFileFormat(item.getFile().getFileFormat()); @@ -1314,7 +1314,7 @@ public class FileServiceImpl implements FileService { ossFile.setFileUrl(this.fileManager.fetchDownloadUrl(item.getTargetBucketName(), Utility.generateFileKey(item.getTargetBucketKey(), item.getTargetKey(), item.getFile().getFileFormat()), item.getTargetChannelCode())); ossFile.setUrlMd5(Utility.getMd5(ossFile.getFileUrl())); ossFile.setStatus(FileStatusEnum.STATUS_UPLOAD_SUCCESS.getCode()); - ossFile.setFileName(item.getFileName()); + ossFile.setFileName(item.getTargetFileName()); ossFile.setFileMd5(Utility.getMd5(ossFile.getFileUrl())); return ossFile; } From a4c336b4cb412727433517efecd6737cbfe92f8a Mon Sep 17 00:00:00 2001 From: xudawei Date: Tue, 11 Mar 2025 13:47:23 +0800 Subject: [PATCH 03/15] =?UTF-8?q?feat:(REQ-3540)=20=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=A4=8D=E5=88=B6=E6=8E=A5=E5=8F=A3=E4=B8=8E=E9=98=BF=E9=87=8C?= =?UTF-8?q?=E4=BA=91/=E5=8D=8E=E4=B8=BA=E4=BA=91=E5=AF=B9=E6=8E=A5?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../axzo/oss/integration/s3/impl/AliOssServiceImpl.java | 6 +++++- .../oss/integration/s3/impl/HuaWeiCloudServiceImpl.java | 8 ++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/AliOssServiceImpl.java b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/AliOssServiceImpl.java index 08b74a9..16093e2 100644 --- a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/AliOssServiceImpl.java +++ b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/AliOssServiceImpl.java @@ -7,6 +7,7 @@ import cn.axzo.oss.integration.s3.AliOssService; import cn.axzo.oss.integration.s3.client.AliOssAppProClient; import cn.axzo.oss.integration.s3.client.AliOssClient; import cn.azxo.framework.common.utils.LogUtil; +import com.alibaba.fastjson.JSON; import com.aliyun.oss.HttpMethod; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSException; @@ -423,7 +424,10 @@ public class AliOssServiceImpl implements AliOssService { @Override public CopyObjectResult copyObject(String bucketName, String key, String targetBucketName, String targetKey) { try { - return aliOssClient.getClient().copyObject(bucketName, key, targetBucketName, targetKey); + log.info("aliOssService#copyObject,params bucketName:{}, key:{}, targetBucketName:{}, targetKey:{}", bucketName, key, targetBucketName, targetKey); + CopyObjectResult copyObjectResult = aliOssClient.getClient().copyObject(bucketName, key, targetBucketName, targetKey); + log.info("aliOssService#copyObject,bucketName:{}, key:{},result:{}", bucketName, key, JSON.toJSONString(copyObjectResult)); + return copyObjectResult; } catch (Exception e) { log.warn("aliyun-copyObject-exception, bucketName:{}, key:{}", bucketName, key, e); return null; diff --git a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/HuaWeiCloudServiceImpl.java b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/HuaWeiCloudServiceImpl.java index 6ffe292..dce2bae 100644 --- a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/HuaWeiCloudServiceImpl.java +++ b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/HuaWeiCloudServiceImpl.java @@ -10,6 +10,7 @@ import cn.axzo.oss.integration.s3.config.HuaWeiCloudObsConfig; import cn.azxo.framework.common.utils.LogUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson.JSON; import com.google.common.collect.Maps; import com.obs.services.ObsClient; import com.obs.services.exception.ObsException; @@ -480,9 +481,12 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService { @Override public CopyObjectResult copyObject(String bucketName, String key, String targetBucketName, String targetKey) { try { - return huaWeiCloudObsClient.getClient().copyObject(bucketName, key, targetBucketName, targetKey); + log.info("huaWeiCloudService#copyObject,params bucketName:{},key:{},targetBucketName:{},targetKey:{}", bucketName, key, targetBucketName, targetKey); + CopyObjectResult copyObjectResult = huaWeiCloudObsClient.getClient().copyObject(bucketName, key, targetBucketName, targetKey); + log.info("huaWeiCloudService#copyObject,params,bucketName:{},key:{},result:{}", bucketName, key, JSON.toJSONString(copyObjectResult)); + return copyObjectResult; } catch (Exception e) { - log.warn("huaweicloud-copyToDict-exception, bucketName:{}, key:{}", bucketName, key, e); + log.warn("huaweicloud-copyToDict-exception, bucketName:{}, key:{},targetBucketName:{},targetKey:{}", bucketName, key, targetBucketName,targetKey, e); return null; } } From 5d03e66a005a5401c1ff50669e0d6913c28611ec Mon Sep 17 00:00:00 2001 From: xudawei Date: Wed, 12 Mar 2025 17:41:12 +0800 Subject: [PATCH 04/15] =?UTF-8?q?feat:(REQ-3540)=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E6=8E=A5=E5=8F=A3=E6=B7=BB=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ServerFileController.java | 11 ++++ .../cn/axzo/oss/dal/repository/FileDao.java | 6 ++ .../oss/dal/repository/impl/FileDaoImpl.java | 16 ++++++ .../oss/http/api/ServerFileServiceApi.java | 8 +++ .../model/file/UpdateFileInfoRequest.java | 44 +++++++++++++++ .../model/file/UpdateFileInfoResponse.java | 27 +++++++++ .../dto/request/file/UpdateFileInfoDto.java | 55 +++++++++++++++++++ .../cn/axzo/oss/service/api/FileService.java | 6 ++ .../oss/service/impl/FileServiceImpl.java | 38 +++++++++++++ 9 files changed, 211 insertions(+) create mode 100644 oss-http-api/src/main/java/cn/axzo/oss/http/model/file/UpdateFileInfoRequest.java create mode 100644 oss-http-api/src/main/java/cn/axzo/oss/http/model/file/UpdateFileInfoResponse.java create mode 100644 oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/file/UpdateFileInfoDto.java diff --git a/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java b/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java index f4fbe75..bfbbacd 100644 --- a/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java +++ b/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java @@ -29,6 +29,8 @@ import cn.axzo.oss.http.model.ServerFileUploadResponse; import cn.axzo.oss.http.model.ServerFileUploadV2Request; import cn.axzo.oss.http.model.copyobject.ServerFileBatchCopyObjectRequest; import cn.axzo.oss.http.model.copyobject.ServerFileBatchCopyObjectResponse; +import cn.axzo.oss.http.model.file.UpdateFileInfoRequest; +import cn.axzo.oss.http.model.file.UpdateFileInfoResponse; import cn.axzo.oss.manager.api.dto.request.FileCopyObjectDto; import cn.axzo.oss.manager.api.dto.request.FindFileKeyDto; import cn.axzo.oss.manager.api.dto.request.FindFileUrlDto; @@ -39,6 +41,7 @@ import cn.axzo.oss.manager.api.dto.request.ServerFileUploadByUrlDto; import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlDownloadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto; +import cn.axzo.oss.manager.api.dto.request.file.UpdateFileInfoDto; import cn.axzo.oss.manager.api.dto.response.FileCopyObjectResponse; import cn.axzo.oss.service.api.FileByUrlService; import cn.axzo.oss.service.api.FileCopyToDictService; @@ -239,4 +242,12 @@ public class ServerFileController implements ServerFileServiceApi { List fileCopyObjectResponses = fileService.batchCopyObject(fileCopyObjectDtos, request.getAppCode()); return CommonResponse.success(ServerFileBatchCopyObjectResponse.builder().responses(BeanUtil.copyToList(fileCopyObjectResponses, ServerFileBatchCopyObjectResponse.ServerFileCopyObjectResponse.class)).build()); } + + /** + * 更新文件信息 + */ + public CommonResponse updateFileInfo(@Valid @RequestBody UpdateFileInfoRequest request) { + UpdateFileInfoDto updateFileInfoDto = BeanUtil.copyProperties(request, UpdateFileInfoDto.class); + return CommonResponse.success(UpdateFileInfoResponse.builder().updateFlag(this.fileService.updateFileInfo(updateFileInfoDto)).build()); + } } diff --git a/oss-dal/src/main/java/cn/axzo/oss/dal/repository/FileDao.java b/oss-dal/src/main/java/cn/axzo/oss/dal/repository/FileDao.java index 94afb29..a66d9f6 100644 --- a/oss-dal/src/main/java/cn/axzo/oss/dal/repository/FileDao.java +++ b/oss-dal/src/main/java/cn/axzo/oss/dal/repository/FileDao.java @@ -32,4 +32,10 @@ public interface FileDao extends IService { File getByUrlMd5(String urlMd5); boolean deleteFile(String fileUuid); + + /** + * 更新文件 + * 目前只有文件名称更新,后续有其他属性可以添加 + */ + boolean updateFileById(File file); } diff --git a/oss-dal/src/main/java/cn/axzo/oss/dal/repository/impl/FileDaoImpl.java b/oss-dal/src/main/java/cn/axzo/oss/dal/repository/impl/FileDaoImpl.java index d371845..1db07d7 100644 --- a/oss-dal/src/main/java/cn/axzo/oss/dal/repository/impl/FileDaoImpl.java +++ b/oss-dal/src/main/java/cn/axzo/oss/dal/repository/impl/FileDaoImpl.java @@ -10,9 +10,11 @@ import cn.axzo.oss.dal.repository.FileDao; import cn.hutool.core.collection.CollectionUtil; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.google.common.collect.Lists; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Repository; import java.util.List; +import java.util.Objects; /** *

@@ -75,4 +77,18 @@ public class FileDaoImpl extends ServiceImpl implements FileDa .set(File::getStatus, FileStatusEnum.STATUS_DELETE.getCode()) .set(File::getIsDelete, IsDeleteEnum.YES.getCode()).update(); } + + /** + * 更新文件 + * 目前只有文件名称更新,后续有其他属性可以添加 + */ + @Override + public boolean updateFileById(File file) { + if (Objects.isNull(file) || Objects.isNull(file.getId()) || StringUtils.isBlank(file.getFileUuid())) { + return false; + } + return lambdaUpdate().eq(File::getId, file.getId()) + .set(StringUtils.isNotBlank(file.getFileName()), File::getFileName, file.getFileName()) + .update(); + } } diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java b/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java index 3694a53..02574f0 100644 --- a/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java @@ -24,6 +24,8 @@ import cn.axzo.oss.http.model.ServerFileUploadResponse; import cn.axzo.oss.http.model.ServerFileUploadV2Request; import cn.axzo.oss.http.model.copyobject.ServerFileBatchCopyObjectRequest; import cn.axzo.oss.http.model.copyobject.ServerFileBatchCopyObjectResponse; +import cn.axzo.oss.http.model.file.UpdateFileInfoRequest; +import cn.axzo.oss.http.model.file.UpdateFileInfoResponse; import cn.azxo.framework.common.model.CommonResponse; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.RequestBody; @@ -143,4 +145,10 @@ public interface ServerFileServiceApi { @RequestMapping(value = "/api/server/batchCopyObject", method = RequestMethod.POST) CommonResponse batchCopyObject(@Valid @RequestBody ServerFileBatchCopyObjectRequest request); + /** + * 更新文件信息 + */ + @RequestMapping(value = "/api/server/batchCopyObject", method = RequestMethod.POST) + CommonResponse updateFileInfo(@Valid @RequestBody UpdateFileInfoRequest request); + } diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/model/file/UpdateFileInfoRequest.java b/oss-http-api/src/main/java/cn/axzo/oss/http/model/file/UpdateFileInfoRequest.java new file mode 100644 index 0000000..fee9c47 --- /dev/null +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/model/file/UpdateFileInfoRequest.java @@ -0,0 +1,44 @@ +package cn.axzo.oss.http.model.file; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 更新文件请求 + * + * @author xudawei + * @date 2025-03-12 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class UpdateFileInfoRequest { + /** + * 文件Id + */ + private Long fileId; + /** + * 文件fileKey + */ + private String fileKey; + + /** + * 需要更新属性 + */ + private UpdateFileInfo updateFileInfo; + + @Data + @AllArgsConstructor + @NoArgsConstructor + @Builder + public static class UpdateFileInfo{ + /** + * 文件名称 + */ + private String fileName; + } + +} diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/model/file/UpdateFileInfoResponse.java b/oss-http-api/src/main/java/cn/axzo/oss/http/model/file/UpdateFileInfoResponse.java new file mode 100644 index 0000000..23489e9 --- /dev/null +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/model/file/UpdateFileInfoResponse.java @@ -0,0 +1,27 @@ +package cn.axzo.oss.http.model.file; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 文件更新返回 + * + * @author xudawei + * @date 2025-03-12 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class UpdateFileInfoResponse { + + /** + * 文件Id + */ + private boolean updateFlag; + +} diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/file/UpdateFileInfoDto.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/file/UpdateFileInfoDto.java new file mode 100644 index 0000000..c73d4d7 --- /dev/null +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/file/UpdateFileInfoDto.java @@ -0,0 +1,55 @@ +package cn.axzo.oss.manager.api.dto.request.file; + +import cn.axzo.oss.dal.entity.File; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author xudawei@axzo.cn + * @date 2025/3/12 + * @description 更新文件信息 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class UpdateFileInfoDto { + + /** + * 文件Id + */ + private Long fileId; + /** + * 文件fileKey + */ + private String fileKey; + + /** + * 需要更新属性 + */ + private UpdateFileInfo updateFileInfo; + + @Data + @AllArgsConstructor + @NoArgsConstructor + @Builder + public static class UpdateFileInfo{ + /** + * 文件名称 + */ + private String fileName; + } + + /** + * 创建文件 + */ + public static File create(Long id, UpdateFileInfo updateFileInfo){ + File file = new File(); + file.setId(id); + file.setFileName(updateFileInfo.getFileName()); + return file; + } + +} diff --git a/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileService.java b/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileService.java index 2194d9f..d16738a 100644 --- a/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileService.java +++ b/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileService.java @@ -17,6 +17,7 @@ import cn.axzo.oss.manager.api.dto.request.ServerFileDownloadDto; import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlDownloadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto; +import cn.axzo.oss.manager.api.dto.request.file.UpdateFileInfoDto; import cn.axzo.oss.manager.api.dto.response.FileCopyObjectResponse; import cn.axzo.oss.manager.api.dto.response.FileInformationResponse; import cn.axzo.oss.manager.api.dto.response.FindFileKeyResponse; @@ -126,4 +127,9 @@ public interface FileService { * 2 相同通道,则直接调用复制方法 */ List batchCopyObject(List dtoList, String appCode); + + /** + * 更新文件信息 + */ + boolean updateFileInfo(UpdateFileInfoDto updateFileInfoDto); } diff --git a/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java index 81d9dd0..5b88c29 100644 --- a/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java +++ b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java @@ -47,6 +47,7 @@ import cn.axzo.oss.manager.api.dto.request.ServerFileDownloadDto; import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlDownloadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto; +import cn.axzo.oss.manager.api.dto.request.file.UpdateFileInfoDto; import cn.axzo.oss.manager.api.dto.response.FileCopyObjectResponse; import cn.axzo.oss.manager.api.dto.response.FileInformationResponse; import cn.axzo.oss.manager.api.dto.response.FindFileKeyResponse; @@ -1363,4 +1364,41 @@ public class FileServiceImpl implements FileService { return returnList; } + /** + * 更新文件信息 + */ + @Override + public boolean updateFileInfo(UpdateFileInfoDto updateFileInfoDto) { + //构建需要更新的信息 + //1 fileId有值,则用fileId直接更新文件信息 + //2 fileId无值,fileKey有值,则用fileKey查询file信息 + File file = this.buildUpdateFileInfo(updateFileInfoDto); + if (Objects.isNull(file)) { + return false; + } + return this.fileDao.updateFileById(file); + } + + /** + * 构建需要更新的信息 + * 1 fileId有值,则用fileId直接更新文件信息 + * 2 fileId无值,fileKey有值,则用fileKey查询file信息 + */ + private File buildUpdateFileInfo(UpdateFileInfoDto updateFileInfoDto) { + //fileId有值,则用fileId直接更新文件信息 + if (Objects.nonNull(updateFileInfoDto.getFileId())) { + return UpdateFileInfoDto.create(updateFileInfoDto.getFileId(), updateFileInfoDto.getUpdateFileInfo()); + } else { + //fileId无值,fileKey有值,则用fileKey查询file信息 + //根据查询file信息更新文件 + if (StringUtils.isNotBlank(updateFileInfoDto.getFileKey())) { + File byFileUuid = this.fileDao.getByFileUuid(updateFileInfoDto.getFileKey()); + if (Objects.isNull(byFileUuid)) { + return null; + } + return UpdateFileInfoDto.create(byFileUuid.getId(), updateFileInfoDto.getUpdateFileInfo()); + } + } + return null; + } } From 8329be13efe4990fd87e31fabaf4a4c6c916973a Mon Sep 17 00:00:00 2001 From: xudawei Date: Thu, 13 Mar 2025 15:51:47 +0800 Subject: [PATCH 05/15] =?UTF-8?q?feat:(REQ-3540)=20=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E5=9C=B0=E5=9D=80=EF=BC=8C=E5=A6=82=E6=9E=9C?= =?UTF-8?q?=E5=85=A5=E5=8F=82=E4=B8=AD=E6=9C=89fileKey?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http/model/ApiSignUrlUploadRequest.java | 5 +++ .../api/dto/request/SignUrlUploadDto.java | 5 +++ .../metafile/impl/HandleFileService.java | 44 +++++++++++-------- 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/model/ApiSignUrlUploadRequest.java b/oss-http-api/src/main/java/cn/axzo/oss/http/model/ApiSignUrlUploadRequest.java index 9a4a93a..e65c9b7 100644 --- a/oss-http-api/src/main/java/cn/axzo/oss/http/model/ApiSignUrlUploadRequest.java +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/model/ApiSignUrlUploadRequest.java @@ -65,4 +65,9 @@ public class ApiSignUrlUploadRequest { * 桶key */ private String bucketKey; + + /** + * 文件key + */ + private String fileKey; } diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/SignUrlUploadDto.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/SignUrlUploadDto.java index 2bcd299..05e47b4 100644 --- a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/SignUrlUploadDto.java +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/SignUrlUploadDto.java @@ -67,4 +67,9 @@ public class SignUrlUploadDto { * 桶key */ private String bucketKey; + + /** + * 文件key + */ + private String fileKey; } diff --git a/oss-service/src/main/java/cn/axzo/oss/service/metafile/impl/HandleFileService.java b/oss-service/src/main/java/cn/axzo/oss/service/metafile/impl/HandleFileService.java index 4692980..8c21242 100644 --- a/oss-service/src/main/java/cn/axzo/oss/service/metafile/impl/HandleFileService.java +++ b/oss-service/src/main/java/cn/axzo/oss/service/metafile/impl/HandleFileService.java @@ -37,6 +37,10 @@ public class HandleFileService extends WithFileService{ public SignUrlUploadResponse doSaveFile(SignUrlUploadDto dto, FileUploadConfig fileUploadConfig, FileBusinessScene scene, AppChannelBucket appChannelBucket, String fileFormat) { String uuid = Utility.getUUID(); + //如果fileKey不为空,则以fileKey为准 + if (StringUtils.isNotBlank(dto.getFileKey())) { + uuid = dto.getFileKey(); + } // 生成上传文件的唯一key String tgtFileKey = Utility.generateFileKey(fileUploadConfig.getDirectory(), uuid, fileFormat); // 失效时间 @@ -68,24 +72,28 @@ public class HandleFileService extends WithFileService{ private File saveOssFile(FileUploadConfig fileUploadConfig, String fileName, String fileConform, String uuid, String fileUrl, String fileMd5, Long expiration) { - File ossFile = new File(); - ossFile.setAppChannelBucketNo(fileUploadConfig.getAppChannelBucketNo()); - ossFile.setAppCode(fileUploadConfig.getAppCode()); - ossFile.setChannelCode(fileUploadConfig.getChannelCode()); - ossFile.setBucketName(fileUploadConfig.getBucketName()); - ossFile.setDirectory(fileUploadConfig.getDirectory()); - ossFile.setStatus(FileStatusEnum.STATUS_UPLOAD_FAIL.getCode()); - ossFile.setStorageUnit(fileUploadConfig.getStorageUnit()); - ossFile.setStorageSize(fileUploadConfig.getStorageSize()); - ossFile.setFileFormat(fileConform); - ossFile.setFileUuid(uuid); - ossFile.setFileUrl(fileUrl); - ossFile.setUrlMd5(Utility.getMd5(fileUrl)); - ossFile.setStatus(FileStatusEnum.STATUS_UPLOAD_SUCCESS.getCode()); - ossFile.setFileName(fileName); - ossFile.setFileMd5(fileMd5); - fileDao.save(ossFile); - return ossFile; + File byFileUuid = this.fileDao.getByFileUuid(uuid); + if (Objects.isNull(byFileUuid) || Objects.isNull(byFileUuid.getId())) { + File ossFile = new File(); + ossFile.setAppChannelBucketNo(fileUploadConfig.getAppChannelBucketNo()); + ossFile.setAppCode(fileUploadConfig.getAppCode()); + ossFile.setChannelCode(fileUploadConfig.getChannelCode()); + ossFile.setBucketName(fileUploadConfig.getBucketName()); + ossFile.setDirectory(fileUploadConfig.getDirectory()); + ossFile.setStatus(FileStatusEnum.STATUS_UPLOAD_FAIL.getCode()); + ossFile.setStorageUnit(fileUploadConfig.getStorageUnit()); + ossFile.setStorageSize(fileUploadConfig.getStorageSize()); + ossFile.setFileFormat(fileConform); + ossFile.setFileUuid(uuid); + ossFile.setFileUrl(fileUrl); + ossFile.setUrlMd5(Utility.getMd5(fileUrl)); + ossFile.setStatus(FileStatusEnum.STATUS_UPLOAD_SUCCESS.getCode()); + ossFile.setFileName(fileName); + ossFile.setFileMd5(fileMd5); + fileDao.save(ossFile); + return ossFile; + } + return byFileUuid; } From b222989f0ad2f6525ba8017d98491a96cce64e9f Mon Sep 17 00:00:00 2001 From: xudawei Date: Thu, 13 Mar 2025 17:43:12 +0800 Subject: [PATCH 06/15] =?UTF-8?q?feat:(REQ-3540)=20=E5=A4=8D=E5=88=B6?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E5=87=BA=E5=8F=82=E6=B3=A8=E9=87=8A=E6=9B=B4?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../model/copyobject/ServerFileBatchCopyObjectResponse.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectResponse.java b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectResponse.java index e7dc4dc..ff23781 100644 --- a/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectResponse.java +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectResponse.java @@ -32,14 +32,12 @@ public class ServerFileBatchCopyObjectResponse { private String fileUuid; /** - * 目标桶 - * 如果目标桶为空,则默认取源桶 + * 目标文件fileKey */ private String targetFileKey; /** * 目标通道 - * 如果目标通道为空,则默认源通道 */ private String targetChannelCode; From c732476716893961fbd06d337c618801e94ceed1 Mon Sep 17 00:00:00 2001 From: xudawei Date: Thu, 13 Mar 2025 17:44:17 +0800 Subject: [PATCH 07/15] =?UTF-8?q?feat:(REQ-3540)=20=E5=A4=8D=E5=88=B6?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E5=87=BA=E5=8F=82=E6=B3=A8=E9=87=8A=E6=9B=B4?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http/model/copyobject/ServerFileBatchCopyObjectRequest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java index d41fac4..3b85a78 100644 --- a/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java @@ -58,7 +58,7 @@ public class ServerFileBatchCopyObjectRequest { private String targetChannelCode; /** - * 文件名称 + * 文件名称(包含后缀) */ private String targetFileName; From ee81f7d7d64431c9b320a10908f2c40289e3c5ec Mon Sep 17 00:00:00 2001 From: xudawei Date: Thu, 13 Mar 2025 18:16:28 +0800 Subject: [PATCH 08/15] =?UTF-8?q?feat:(REQ-3540)=20=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E9=87=8D=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ServerFileController.java | 13 ++++++++ .../http/model/file/FileRenameRequest.java | 32 +++++++++++++++++++ .../http/model/file/FileRenameResponse.java | 23 +++++++++++++ .../dto/request/file/UpdateFileInfoDto.java | 2 +- 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 oss-http-api/src/main/java/cn/axzo/oss/http/model/file/FileRenameRequest.java create mode 100644 oss-http-api/src/main/java/cn/axzo/oss/http/model/file/FileRenameResponse.java diff --git a/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java b/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java index bfbbacd..521376e 100644 --- a/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java +++ b/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java @@ -29,6 +29,8 @@ import cn.axzo.oss.http.model.ServerFileUploadResponse; import cn.axzo.oss.http.model.ServerFileUploadV2Request; import cn.axzo.oss.http.model.copyobject.ServerFileBatchCopyObjectRequest; import cn.axzo.oss.http.model.copyobject.ServerFileBatchCopyObjectResponse; +import cn.axzo.oss.http.model.file.FileRenameRequest; +import cn.axzo.oss.http.model.file.FileRenameResponse; import cn.axzo.oss.http.model.file.UpdateFileInfoRequest; import cn.axzo.oss.http.model.file.UpdateFileInfoResponse; import cn.axzo.oss.manager.api.dto.request.FileCopyObjectDto; @@ -250,4 +252,15 @@ public class ServerFileController implements ServerFileServiceApi { UpdateFileInfoDto updateFileInfoDto = BeanUtil.copyProperties(request, UpdateFileInfoDto.class); return CommonResponse.success(UpdateFileInfoResponse.builder().updateFlag(this.fileService.updateFileInfo(updateFileInfoDto)).build()); } + + /** + * 更新文件信息 + */ + public CommonResponse rename(@Valid @RequestBody FileRenameRequest request) { + UpdateFileInfoDto updateFileInfoDto = UpdateFileInfoDto.builder() + .fileKey(request.getFileKey()) + .fileId(request.getFileId()) + .updateFileInfo(UpdateFileInfoDto.UpdateFileInfo.builder().fileName(request.getNewName()).build()).build(); + return CommonResponse.success(FileRenameResponse.builder().updateFlag(this.fileService.updateFileInfo(updateFileInfoDto)).build()); + } } diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/model/file/FileRenameRequest.java b/oss-http-api/src/main/java/cn/axzo/oss/http/model/file/FileRenameRequest.java new file mode 100644 index 0000000..368e0c3 --- /dev/null +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/model/file/FileRenameRequest.java @@ -0,0 +1,32 @@ +package cn.axzo.oss.http.model.file; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 更新文件请求 + * + * @author xudawei + * @date 2025-03-12 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class FileRenameRequest { + /** + * 文件Id + */ + private Long fileId; + /** + * 文件fileKey + */ + private String fileKey; + + /** + * 新名称 + */ + private String newName; +} diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/model/file/FileRenameResponse.java b/oss-http-api/src/main/java/cn/axzo/oss/http/model/file/FileRenameResponse.java new file mode 100644 index 0000000..3e1d4bb --- /dev/null +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/model/file/FileRenameResponse.java @@ -0,0 +1,23 @@ +package cn.axzo.oss.http.model.file; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 更新文件请求 + * + * @author xudawei + * @date 2025-03-12 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class FileRenameResponse { + /** + * 文件Id + */ + private boolean updateFlag; +} diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/file/UpdateFileInfoDto.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/file/UpdateFileInfoDto.java index c73d4d7..42e6375 100644 --- a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/file/UpdateFileInfoDto.java +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/file/UpdateFileInfoDto.java @@ -35,7 +35,7 @@ public class UpdateFileInfoDto { @AllArgsConstructor @NoArgsConstructor @Builder - public static class UpdateFileInfo{ + public static class UpdateFileInfo { /** * 文件名称 */ From fc348855a1724d5e01f997111d9e95ef5c8648eb Mon Sep 17 00:00:00 2001 From: xudawei Date: Fri, 14 Mar 2025 14:40:45 +0800 Subject: [PATCH 09/15] =?UTF-8?q?feat:(REQ-3540)=20=E5=8A=A0=E4=B8=8A?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=96=87=E4=BB=B6api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ServerFileController.java | 45 ++++++++++ .../cn/axzo/oss/dal/repository/FileDao.java | 5 ++ .../oss/dal/repository/impl/FileDaoImpl.java | 14 ++++ .../oss/http/api/ServerFileServiceApi.java | 15 +++- .../ServerFileBatchDeleteObjectRequest.java | 42 ++++++++++ .../ServerFileBatchDeleteObjectResponse.java | 42 ++++++++++ .../oss/integration/s3/AliOssService.java | 8 ++ .../integration/s3/HuaWeiCloudService.java | 7 ++ .../s3/impl/AliOssServiceImpl.java | 20 +++++ .../s3/impl/HuaWeiCloudServiceImpl.java | 25 ++++++ .../cn/axzo/oss/manager/api/FileManager.java | 8 ++ .../request/file/DeleteObjectsFileDto.java | 48 +++++++++++ .../response/BatchDeleteObjectsResponse.java | 47 +++++++++++ .../oss/manager/impl/FileManagerImpl.java | 66 +++++++++++++++ .../cn/axzo/oss/service/api/FileService.java | 6 ++ .../oss/service/impl/FileServiceImpl.java | 83 +++++++++++++++++++ 16 files changed, 478 insertions(+), 3 deletions(-) create mode 100644 oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchDeleteObjectRequest.java create mode 100644 oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchDeleteObjectResponse.java create mode 100644 oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/file/DeleteObjectsFileDto.java create mode 100644 oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/response/BatchDeleteObjectsResponse.java diff --git a/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java b/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java index 521376e..6ca999c 100644 --- a/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java +++ b/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java @@ -29,6 +29,8 @@ import cn.axzo.oss.http.model.ServerFileUploadResponse; import cn.axzo.oss.http.model.ServerFileUploadV2Request; import cn.axzo.oss.http.model.copyobject.ServerFileBatchCopyObjectRequest; import cn.axzo.oss.http.model.copyobject.ServerFileBatchCopyObjectResponse; +import cn.axzo.oss.http.model.copyobject.ServerFileBatchDeleteObjectRequest; +import cn.axzo.oss.http.model.copyobject.ServerFileBatchDeleteObjectResponse; import cn.axzo.oss.http.model.file.FileRenameRequest; import cn.axzo.oss.http.model.file.FileRenameResponse; import cn.axzo.oss.http.model.file.UpdateFileInfoRequest; @@ -43,6 +45,7 @@ import cn.axzo.oss.manager.api.dto.request.ServerFileUploadByUrlDto; import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlDownloadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto; +import cn.axzo.oss.manager.api.dto.request.file.DeleteObjectsFileDto; import cn.axzo.oss.manager.api.dto.request.file.UpdateFileInfoDto; import cn.axzo.oss.manager.api.dto.response.FileCopyObjectResponse; import cn.axzo.oss.service.api.FileByUrlService; @@ -263,4 +266,46 @@ public class ServerFileController implements ServerFileServiceApi { .updateFileInfo(UpdateFileInfoDto.UpdateFileInfo.builder().fileName(request.getNewName()).build()).build(); return CommonResponse.success(FileRenameResponse.builder().updateFlag(this.fileService.updateFileInfo(updateFileInfoDto)).build()); } + + /** + * 删除文件 + */ + public CommonResponse batchDeleteObject(@Valid @RequestBody ServerFileBatchDeleteObjectRequest request) { + AssertUtil.isFalse(Objects.isNull(request) || CollectionUtils.isEmpty(request.getDeleteObjects()), "参数为空"); + //构建删除对象 + DeleteObjectsFileDto deleteObjectsFileDto = this.buildDeleteObjects(request); + //删除逻辑 + this.fileService.deleteObject(deleteObjectsFileDto); + //构建删除对象返回 + return CommonResponse.success(this.buildDeleteResponse(deleteObjectsFileDto)); + } + + /** + * 构建删除对象返回 + */ + private ServerFileBatchDeleteObjectResponse buildDeleteResponse(DeleteObjectsFileDto deleteObjectsFileDto) { + List responses + = deleteObjectsFileDto.getDeleteFiles().stream().map(item -> { + return ServerFileBatchDeleteObjectResponse.ServerFileDeleteObjectResponse.builder() + .fileKey(item.getFileKey()) + .errorCode(item.getErrorCode()).build(); + }).collect(Collectors.toList()); + + return ServerFileBatchDeleteObjectResponse.builder().responses(responses).build(); + } + + /** + * 构建删除对象 + */ + private DeleteObjectsFileDto buildDeleteObjects(ServerFileBatchDeleteObjectRequest request) { + List fileKeys = request.getDeleteObjects().stream().map(ServerFileBatchDeleteObjectRequest.ServerFileDeleteObjectRequest::getFileKey).collect(Collectors.toList()); + + AssertUtil.isFalse(Objects.isNull(request) || CollectionUtils.isEmpty(fileKeys), "参数为空"); + + List deleteObjectFileDtos = fileKeys.stream().map(item -> { + return DeleteObjectsFileDto.DeleteObjectFileDto.builder().fileKey(item).build(); + }).collect(Collectors.toList()); + AssertUtil.isFalse(CollectionUtils.isEmpty(deleteObjectFileDtos), "参数为空"); + return DeleteObjectsFileDto.builder().deleteFiles(deleteObjectFileDtos).build(); + } } diff --git a/oss-dal/src/main/java/cn/axzo/oss/dal/repository/FileDao.java b/oss-dal/src/main/java/cn/axzo/oss/dal/repository/FileDao.java index a66d9f6..255055d 100644 --- a/oss-dal/src/main/java/cn/axzo/oss/dal/repository/FileDao.java +++ b/oss-dal/src/main/java/cn/axzo/oss/dal/repository/FileDao.java @@ -38,4 +38,9 @@ public interface FileDao extends IService { * 目前只有文件名称更新,后续有其他属性可以添加 */ boolean updateFileById(File file); + + /** + * 根据fileKeys删除 + */ + boolean deleteByFileKeys(List fileKeys); } diff --git a/oss-dal/src/main/java/cn/axzo/oss/dal/repository/impl/FileDaoImpl.java b/oss-dal/src/main/java/cn/axzo/oss/dal/repository/impl/FileDaoImpl.java index 1db07d7..f139101 100644 --- a/oss-dal/src/main/java/cn/axzo/oss/dal/repository/impl/FileDaoImpl.java +++ b/oss-dal/src/main/java/cn/axzo/oss/dal/repository/impl/FileDaoImpl.java @@ -91,4 +91,18 @@ public class FileDaoImpl extends ServiceImpl implements FileDa .set(StringUtils.isNotBlank(file.getFileName()), File::getFileName, file.getFileName()) .update(); } + + /** + * 根据fileKeys删除 + */ + @Override + public boolean deleteByFileKeys(List fileKeys) { + if (CollectionUtil.isEmpty(fileKeys)) { + return false; + } + return lambdaUpdate().in(File::getFileUuid, fileKeys) + .eq(File::getStatus, FileStatus.SUCCESS) + .eq(File::getIsDelete, TableDelete.UN_DELETED) + .set(File::getIsDelete, TableDelete.DELETED).update(); + } } diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java b/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java index 02574f0..b6669fe 100644 --- a/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java @@ -24,6 +24,8 @@ import cn.axzo.oss.http.model.ServerFileUploadResponse; import cn.axzo.oss.http.model.ServerFileUploadV2Request; import cn.axzo.oss.http.model.copyobject.ServerFileBatchCopyObjectRequest; import cn.axzo.oss.http.model.copyobject.ServerFileBatchCopyObjectResponse; +import cn.axzo.oss.http.model.copyobject.ServerFileBatchDeleteObjectRequest; +import cn.axzo.oss.http.model.copyobject.ServerFileBatchDeleteObjectResponse; import cn.axzo.oss.http.model.file.UpdateFileInfoRequest; import cn.axzo.oss.http.model.file.UpdateFileInfoResponse; import cn.azxo.framework.common.model.CommonResponse; @@ -65,10 +67,10 @@ public interface ServerFileServiceApi { CommonResponse uploadV2(ServerFileUploadV2Request request); /** - * 删除文件 - * @param request - * @return + * 删除文件-方法已废弃 + * 建议换成ServerFileServiceApi#deleteObject() */ + @Deprecated @RequestMapping(value = "/api/v1/server/delete", method = RequestMethod.POST) CommonResponse delete(ServerFileDeleteRequest request); @@ -151,4 +153,11 @@ public interface ServerFileServiceApi { @RequestMapping(value = "/api/server/batchCopyObject", method = RequestMethod.POST) CommonResponse updateFileInfo(@Valid @RequestBody UpdateFileInfoRequest request); + /** + * 删除文件 + */ + @RequestMapping(value = "/api/server/deleteObject", method = RequestMethod.POST) + CommonResponse batchDeleteObject(@Valid @RequestBody ServerFileBatchDeleteObjectRequest request); + + } diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchDeleteObjectRequest.java b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchDeleteObjectRequest.java new file mode 100644 index 0000000..e191b42 --- /dev/null +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchDeleteObjectRequest.java @@ -0,0 +1,42 @@ +package cn.axzo.oss.http.model.copyobject; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotEmpty; +import java.util.Set; + +/** + * 批量删除对象 + * + * @author xudawei + * @date 2025-03-07 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ServerFileBatchDeleteObjectRequest { + + @NotBlank(message = "appCode must not be null") + private String appCode; + + @NotEmpty(message = "集合对象不能为空") + private Set deleteObjects; + + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class ServerFileDeleteObjectRequest { + /** + * 文件标识 + */ + @NotBlank(message = "fileKey不能为空") + private String fileKey; + + } +} diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchDeleteObjectResponse.java b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchDeleteObjectResponse.java new file mode 100644 index 0000000..b435aee --- /dev/null +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchDeleteObjectResponse.java @@ -0,0 +1,42 @@ +package cn.axzo.oss.http.model.copyobject; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * 删除文件返回 + * + * @author xudawei + * @date 2025-03-14 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class ServerFileBatchDeleteObjectResponse { + + private List responses; + + @Data + @AllArgsConstructor + @NoArgsConstructor + @Builder + public static class ServerFileDeleteObjectResponse { + /** + * 文件标识 + */ + private String fileKey; + + /** + * 删除标识 + * true:删除成功;false:删除失败 + */ + private String errorCode; + + } + +} diff --git a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/AliOssService.java b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/AliOssService.java index ad323db..2bf10b7 100644 --- a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/AliOssService.java +++ b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/AliOssService.java @@ -2,8 +2,11 @@ package cn.axzo.oss.integration.s3; import cn.axzo.oss.integration.s3.base.BaseS3Service; import com.aliyun.oss.model.CopyObjectResult; +import com.aliyun.oss.model.DeleteObjectsResult; import com.aliyun.oss.model.SimplifiedObjectMeta; +import java.util.List; + /** * @program: oss * @description: 阿里云oss服务 @@ -46,4 +49,9 @@ public interface AliOssService extends BaseS3Service { * 复制对象 */ CopyObjectResult copyObject(String bucketName, String key, String targetBucketName, String targetKey); + + /** + * 批量删除File + */ + DeleteObjectsResult batchDeleteFile(String bucketName, List keys); } diff --git a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/HuaWeiCloudService.java b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/HuaWeiCloudService.java index 8f9ea90..f4b27f5 100644 --- a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/HuaWeiCloudService.java +++ b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/HuaWeiCloudService.java @@ -1,10 +1,12 @@ package cn.axzo.oss.integration.s3; import com.obs.services.model.CopyObjectResult; +import com.obs.services.model.DeleteObjectsResult; import com.obs.services.model.ObjectMetadata; import com.obs.services.model.TemporarySignatureResponse; import java.io.InputStream; +import java.util.List; /** * 华为云obs @@ -57,4 +59,9 @@ public interface HuaWeiCloudService { * 复制对象 */ CopyObjectResult copyObject(String bucketName, String key, String targetBucketName, String targetKey); + + /** + * 删除File + */ + DeleteObjectsResult batchDeleteFile(String bucketName, List keyAndVersions); } diff --git a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/AliOssServiceImpl.java b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/AliOssServiceImpl.java index 16093e2..3a957b3 100644 --- a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/AliOssServiceImpl.java +++ b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/AliOssServiceImpl.java @@ -13,6 +13,8 @@ import com.aliyun.oss.OSS; import com.aliyun.oss.OSSException; import com.aliyun.oss.model.CompleteMultipartUploadRequest; import com.aliyun.oss.model.CopyObjectResult; +import com.aliyun.oss.model.DeleteObjectsRequest; +import com.aliyun.oss.model.DeleteObjectsResult; import com.aliyun.oss.model.GeneratePresignedUrlRequest; import com.aliyun.oss.model.GetObjectRequest; import com.aliyun.oss.model.InitiateMultipartUploadRequest; @@ -433,4 +435,22 @@ public class AliOssServiceImpl implements AliOssService { return null; } } + + /** + * 批量删除File + */ + @Override + public DeleteObjectsResult batchDeleteFile(String bucketName, List keys) { + try { + log.info("aliyun batchDeleteFile params, bucketName:{}, keys:{}", bucketName, JSON.toJSONString(keys)); + DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName); + deleteObjectsRequest.setKeys(keys); + DeleteObjectsResult deleteObjectsResult = aliOssClient.getClient().deleteObjects(deleteObjectsRequest); + log.info("aliyun batchDeleteFile result, bucketName:{}, keys:{}, deleteObjectsResult:{}", bucketName, JSON.toJSONString(keys),JSON.toJSONString(deleteObjectsResult)); + return deleteObjectsResult; + } catch (Exception e) { + log.warn("aliyun batchDeleteFile exception, bucketName:{}, keys:{}", bucketName, JSON.toJSONString(keys), e); + throw new BizException(CodeEnum.DELETE_FILE_FAIL); + } + } } diff --git a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/HuaWeiCloudServiceImpl.java b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/HuaWeiCloudServiceImpl.java index dce2bae..99e7d12 100644 --- a/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/HuaWeiCloudServiceImpl.java +++ b/oss-integration/src/main/java/cn/axzo/oss/integration/s3/impl/HuaWeiCloudServiceImpl.java @@ -18,12 +18,15 @@ import com.obs.services.model.CompleteMultipartUploadRequest; import com.obs.services.model.CompleteMultipartUploadResult; import com.obs.services.model.CopyObjectResult; import com.obs.services.model.DeleteObjectResult; +import com.obs.services.model.DeleteObjectsRequest; +import com.obs.services.model.DeleteObjectsResult; import com.obs.services.model.DownloadFileRequest; import com.obs.services.model.DownloadFileResult; import com.obs.services.model.GetObjectRequest; import com.obs.services.model.HttpMethodEnum; import com.obs.services.model.InitiateMultipartUploadRequest; import com.obs.services.model.InitiateMultipartUploadResult; +import com.obs.services.model.KeyAndVersion; import com.obs.services.model.ObjectMetadata; import com.obs.services.model.ObsObject; import com.obs.services.model.PartEtag; @@ -422,6 +425,28 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService { } } + /** + * 删除File + */ + @Override + public DeleteObjectsResult batchDeleteFile(String bucketName, List keys) { + try { + if (CollectionUtils.isEmpty(keys)) { + return new DeleteObjectsResult(); + } + log.info("huawei cloud batchDeleteFile params, bucketName:{}, keyAndVersions:{}", bucketName, JSON.toJSONString(keys)); + DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(bucketName); + deleteObjectsRequest.setKeyAndVersions(keys.toArray(new KeyAndVersion[keys.size()])); + + DeleteObjectsResult result = huaWeiCloudObsClient.getClient().deleteObjects(deleteObjectsRequest); + log.info("huawei cloud batchDeleteFile result, bucketName:{},deleteObjectResult:{}", bucketName, JsonUtil.obj2Str(result)); + return result; + } catch (Exception e) { + log.warn("huawei cloud batchDeleteFile exception, bucketName:{}", bucketName, e); + throw new BizException(CodeEnum.DELETE_FILE_FAIL); + } + } + public String getUrl(String bucketName, String tgtFileKey) { StringBuilder allBuilder = new StringBuilder(); allBuilder.append("https://"); diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/FileManager.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/FileManager.java index a53a04e..22332f9 100644 --- a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/FileManager.java +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/FileManager.java @@ -3,6 +3,7 @@ package cn.axzo.oss.manager.api; import cn.axzo.oss.manager.api.dto.PartETag; import cn.axzo.oss.manager.api.dto.request.CopyObjectCloudDto; import cn.axzo.oss.manager.api.dto.request.MultipartUploadDto; +import cn.axzo.oss.manager.api.dto.request.file.DeleteObjectsFileDto; import cn.axzo.oss.manager.api.dto.response.ManaGetObjectMetaResponse; import cn.axzo.oss.manager.api.dto.response.SignUrlDownloadResponse; import cn.axzo.oss.manager.api.vo.SignUrlUploadVo; @@ -106,4 +107,11 @@ public interface FileManager { * 相同的通道-对象复制 */ Boolean copyObjectWhenSameChannel(CopyObjectCloudDto dto); + + /** + * 批量删除对象 + * 1 华为云删除失败的会返回在errorResults中 + * 2 阿里云删除成功的会返回在errorResults中 + */ + DeleteObjectsFileDto batchDeleteObjects(DeleteObjectsFileDto dto, String bucketName, String channelCode); } diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/file/DeleteObjectsFileDto.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/file/DeleteObjectsFileDto.java new file mode 100644 index 0000000..d87768b --- /dev/null +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/file/DeleteObjectsFileDto.java @@ -0,0 +1,48 @@ +package cn.axzo.oss.manager.api.dto.request.file; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @author xudawei@axzo.cn + * @date 2025/3/12 + * @description 删除文件信息 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class DeleteObjectsFileDto { + + /** + * 文件集合 + */ + private List deleteFiles; + + @Data + @Builder + @AllArgsConstructor + @NoArgsConstructor + public static class DeleteObjectFileDto { + + /** + * fileKey + */ + private String fileKey; + /** + * 桶key + */ + private String bucketKey; + + /** + * 错误编码 + */ + private String errorCode; + } + + +} diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/response/BatchDeleteObjectsResponse.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/response/BatchDeleteObjectsResponse.java new file mode 100644 index 0000000..04f688e --- /dev/null +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/response/BatchDeleteObjectsResponse.java @@ -0,0 +1,47 @@ +package cn.axzo.oss.manager.api.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +/** + * @Author: xudawei + * @Date: 2024/03/12 + * @Description: 授权给第三方下载 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class BatchDeleteObjectsResponse { + + + private List deleteObjects; + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class DeleteObjectResponse { + /** + * 文件 Key + */ + private String fileKey; + + /** + * 桶名称 + */ + private String bucketName; + + /** + * 桶key + */ + private String bucketKey; + } + + + +} diff --git a/oss-manager/src/main/java/cn/axzo/oss/manager/impl/FileManagerImpl.java b/oss-manager/src/main/java/cn/axzo/oss/manager/impl/FileManagerImpl.java index 692e647..d09bd6f 100644 --- a/oss-manager/src/main/java/cn/axzo/oss/manager/impl/FileManagerImpl.java +++ b/oss-manager/src/main/java/cn/axzo/oss/manager/impl/FileManagerImpl.java @@ -14,11 +14,13 @@ import cn.axzo.oss.manager.api.FileManager; import cn.axzo.oss.manager.api.dto.PartETag; import cn.axzo.oss.manager.api.dto.request.CopyObjectCloudDto; import cn.axzo.oss.manager.api.dto.request.MultipartUploadDto; +import cn.axzo.oss.manager.api.dto.request.file.DeleteObjectsFileDto; import cn.axzo.oss.manager.api.dto.response.ManaGetObjectMetaResponse; import cn.axzo.oss.manager.api.dto.response.SignUrlDownloadResponse; import cn.axzo.oss.manager.api.vo.SignUrlUploadVo; import com.aliyun.oss.model.SimplifiedObjectMeta; import com.obs.services.model.CopyObjectResult; +import com.obs.services.model.DeleteObjectsResult; import com.obs.services.model.ObjectMetadata; import com.obs.services.model.TemporarySignatureResponse; import lombok.extern.slf4j.Slf4j; @@ -33,7 +35,10 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.function.Function; +import java.util.stream.Collectors; /** * @Author admin @@ -379,5 +384,66 @@ public class FileManagerImpl implements FileManager { return false; } + /** + * 批量删除对象 + * 1 华为云删除失败的会返回在errorResults中 + * 2 阿里云删除成功的会返回在errorResults中 + */ + public DeleteObjectsFileDto batchDeleteObjects(DeleteObjectsFileDto dto, String bucketName, String channelCode) { + if (StringUtils.isBlank(bucketName) + || StringUtils.isBlank(channelCode) + || Objects.isNull(dto) + || CollectionUtils.isEmpty(dto.getDeleteFiles())) { + return DeleteObjectsFileDto.builder().build(); + } + List bucketKeys = dto.getDeleteFiles().stream().map(DeleteObjectsFileDto.DeleteObjectFileDto::getBucketKey).collect(Collectors.toList()); + ChannelTypeEnum typeEnum = ChannelTypeEnum.getChannelTypeByChannelCode(channelCode); + switch (typeEnum) { + case OBS:// 华为云 + this.deleteToHuaweiCloud(dto, bucketName, bucketKeys); + break; + case OSS:// 阿里云 + this.deleteToAliyun(dto, bucketName, bucketKeys); + default: + BizException.error(CodeEnum.CHANNEL_TYPE_NOT_EXIST); + } + return dto; + } + + /** + * 删除阿里云文件 + */ + private void deleteToAliyun(DeleteObjectsFileDto dto, String bucketName, List bucketKeys) { + com.aliyun.oss.model.DeleteObjectsResult aliResult = aliOssService.batchDeleteFile(bucketName, bucketKeys); + Map deleteMap = aliResult.getDeletedObjects().stream().collect(Collectors.toMap(item -> item, Function.identity(), (x, y) -> x)); + + //阿里云删除成功的会返回在errorResults中 + dto.getDeleteFiles().stream().forEach(item -> { + if (StringUtils.isNotBlank(deleteMap.get(item.getBucketKey()))) { + item.setErrorCode(CodeEnum.SUCCESS.getCode().toString()); + } else { + item.setErrorCode(CodeEnum.DELETE_FILE_FAIL.getCode().toString()); + } + }); + } + + /** + * 删除华为云文件 + */ + private void deleteToHuaweiCloud(DeleteObjectsFileDto dto, String bucketName, List bucketKeys) { + DeleteObjectsResult huaweiResult = huaWeiCloudService.batchDeleteFile(bucketName, bucketKeys); + List errorResults = huaweiResult.getErrorResults(); + + Map errorMap = errorResults.stream().collect(Collectors.toMap(item -> item.getObjectKey(), value -> value.getErrorCode(), (x, y) -> x)); + //华为云删除失败的会返回在errorResults中 + dto.getDeleteFiles().stream().forEach(item -> { + if (StringUtils.isNotBlank(errorMap.get(item.getBucketKey()))) { + item.setErrorCode(errorMap.get(item.getBucketKey())); + } else { + item.setErrorCode(CodeEnum.SUCCESS.getCode().toString()); + } + }); + } + } diff --git a/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileService.java b/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileService.java index d16738a..0523cdb 100644 --- a/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileService.java +++ b/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileService.java @@ -17,6 +17,7 @@ import cn.axzo.oss.manager.api.dto.request.ServerFileDownloadDto; import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlDownloadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto; +import cn.axzo.oss.manager.api.dto.request.file.DeleteObjectsFileDto; import cn.axzo.oss.manager.api.dto.request.file.UpdateFileInfoDto; import cn.axzo.oss.manager.api.dto.response.FileCopyObjectResponse; import cn.axzo.oss.manager.api.dto.response.FileInformationResponse; @@ -132,4 +133,9 @@ public interface FileService { * 更新文件信息 */ boolean updateFileInfo(UpdateFileInfoDto updateFileInfoDto); + + /** + * 删除文件信息 + */ + void deleteObject(DeleteObjectsFileDto dto); } diff --git a/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java index 5b88c29..607ba84 100644 --- a/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java +++ b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java @@ -47,6 +47,7 @@ import cn.axzo.oss.manager.api.dto.request.ServerFileDownloadDto; import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlDownloadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto; +import cn.axzo.oss.manager.api.dto.request.file.DeleteObjectsFileDto; import cn.axzo.oss.manager.api.dto.request.file.UpdateFileInfoDto; import cn.axzo.oss.manager.api.dto.response.FileCopyObjectResponse; import cn.axzo.oss.manager.api.dto.response.FileInformationResponse; @@ -1401,4 +1402,86 @@ public class FileServiceImpl implements FileService { } return null; } + + /** + * 删除文件信息 + */ + @Override + public void deleteObject(DeleteObjectsFileDto dto) { + if (Objects.isNull(dto) || CollectionUtils.isEmpty(dto.getDeleteFiles())) { + return; + } + // 构建fileKey与bucketKey对象集合 + Pair, File> deletePair = this.buildFileKeyAndBucketKeyList(dto); + + if (Objects.isNull(deletePair)) { + return; + } + // 删除云文件和file表 + DeleteObjectsFileDto deleteObjectsFileDto = this.deleteYunAndFile(deletePair); + + // 重新填充dto中的errorcode + this.rechangeDeleteObjectsFileDto(deleteObjectsFileDto, dto); + } + + /** + * 删除云文件和file表 + */ + private DeleteObjectsFileDto deleteYunAndFile(Pair, File> deletePair) { + // 删除云文件 + DeleteObjectsFileDto deleteObjectsFileDto = this.fileManager.batchDeleteObjects(DeleteObjectsFileDto.builder() + .deleteFiles(deletePair.getKey()).build() + , deletePair.getValue().getBucketName() + , deletePair.getValue().getChannelCode()); + // 删除file文件 + this.deleteFiles(deleteObjectsFileDto); + return deleteObjectsFileDto; + } + + /** + * 重新填充dto中的errorcode + */ + private void rechangeDeleteObjectsFileDto(DeleteObjectsFileDto deleteObjectsFileDto, DeleteObjectsFileDto dto) { + Map fileKeyMap = deleteObjectsFileDto.getDeleteFiles().stream() + .filter(item -> Objects.nonNull(item)) + .collect(Collectors.toMap(key -> key.getFileKey(), Function.identity())); + + dto.getDeleteFiles().stream().forEach(item -> { + if (Objects.nonNull(fileKeyMap.get(item.getFileKey()))) { + item.setErrorCode(fileKeyMap.get(item.getFileKey()).getErrorCode()); + } + }); + } + + /** + * 删除file文件 + */ + private void deleteFiles(DeleteObjectsFileDto deleteObjectsFileDto) { + List delSuccessFileKeys = deleteObjectsFileDto.getDeleteFiles().stream() + .filter(item -> Objects.nonNull(item) && item.getErrorCode().equals(CodeEnum.SUCCESS.getCode().toString())) + .map(DeleteObjectsFileDto.DeleteObjectFileDto::getFileKey).collect(Collectors.toList()); + + this.fileDao.deleteByFileKeys(delSuccessFileKeys); + } + + /** + * 构建fileKey与bucketKey对象集合 + * 1 根据fileKey,查询file表,最终构建fileKey与bucketKey对象集合 + * 2 阿里云与华为云删除最终需要bucketKey,故需要构建bucketKey + */ + private Pair, File> buildFileKeyAndBucketKeyList(DeleteObjectsFileDto dto) { + List fileKeys = dto.getDeleteFiles().stream().map(item -> item.getFileKey()).collect(Collectors.toList()); + List byFileUuids = this.fileDao.getByFileUuids(fileKeys); + if (CollectionUtil.isEmpty(byFileUuids)) { + return null; + } + List deleteObjectFileDtos = byFileUuids.stream().map(item -> { + return DeleteObjectsFileDto.DeleteObjectFileDto.builder() + .fileKey(item.getFileUuid()) + .bucketKey(Utility.generateFileKey(item.getDirectory(), item.getFileUuid(), item.getFileFormat())) + .build(); + }).collect(Collectors.toList()); + File file = byFileUuids.get(0); + return Pair.of(deleteObjectFileDtos, file); + } } From 8407627e17851df9a94cb99d4e1cb319cb74acce Mon Sep 17 00:00:00 2001 From: xudawei Date: Mon, 17 Mar 2025 14:21:57 +0800 Subject: [PATCH 10/15] =?UTF-8?q?feat:(REQ-3540)=20rename=E5=8A=A0?= =?UTF-8?q?=E4=B8=8Aapi?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/axzo/oss/http/api/ServerFileServiceApi.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java b/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java index b6669fe..e869d8e 100644 --- a/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java @@ -26,6 +26,8 @@ import cn.axzo.oss.http.model.copyobject.ServerFileBatchCopyObjectRequest; import cn.axzo.oss.http.model.copyobject.ServerFileBatchCopyObjectResponse; import cn.axzo.oss.http.model.copyobject.ServerFileBatchDeleteObjectRequest; import cn.axzo.oss.http.model.copyobject.ServerFileBatchDeleteObjectResponse; +import cn.axzo.oss.http.model.file.FileRenameRequest; +import cn.axzo.oss.http.model.file.FileRenameResponse; import cn.axzo.oss.http.model.file.UpdateFileInfoRequest; import cn.axzo.oss.http.model.file.UpdateFileInfoResponse; import cn.azxo.framework.common.model.CommonResponse; @@ -153,6 +155,12 @@ public interface ServerFileServiceApi { @RequestMapping(value = "/api/server/batchCopyObject", method = RequestMethod.POST) CommonResponse updateFileInfo(@Valid @RequestBody UpdateFileInfoRequest request); + /** + * 重命名 + */ + @RequestMapping(value = "/api/server/rename", method = RequestMethod.POST) + CommonResponse rename(@Valid @RequestBody FileRenameRequest request); + /** * 删除文件 */ From 54d8ffb985bab9d60952a3311a19cf0c103663aa Mon Sep 17 00:00:00 2001 From: xudawei Date: Tue, 18 Mar 2025 14:09:04 +0800 Subject: [PATCH 11/15] =?UTF-8?q?feat:(REQ-3540)=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E4=BF=A1=E6=81=AF=E6=9B=B4=E6=94=B9path?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java b/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java index e869d8e..096a5aa 100644 --- a/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java @@ -152,7 +152,7 @@ public interface ServerFileServiceApi { /** * 更新文件信息 */ - @RequestMapping(value = "/api/server/batchCopyObject", method = RequestMethod.POST) + @RequestMapping(value = "/api/server/updateFileInfo", method = RequestMethod.POST) CommonResponse updateFileInfo(@Valid @RequestBody UpdateFileInfoRequest request); /** From 6a5e42c6531fb7fd217416f88c17bed6ce92ba88 Mon Sep 17 00:00:00 2001 From: xudawei Date: Thu, 20 Mar 2025 17:10:11 +0800 Subject: [PATCH 12/15] =?UTF-8?q?feat:(REQ-3540)=20=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=85=8B=E9=9A=86-=E5=8A=A0=E4=B8=8AbizScene,=E4=B8=8D?= =?UTF-8?q?=E4=BC=A0=E7=9B=AE=E6=A0=87=E6=A1=B6=E4=B8=8Ekey=EF=BC=8C?= =?UTF-8?q?=E5=88=99=E6=8C=89=E7=85=A7appCode=E4=B8=8EbizScene=E7=9A=84?= =?UTF-8?q?=E4=B8=BA=E5=87=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ServerFileController.java | 3 +- .../dal/repository/FileBusinessSceneDao.java | 3 ++ .../impl/FileBusinessSceneDaoImpl.java | 9 ++++++ .../axzo/oss/dal/vo/FileBusinessSceneVo.java | 20 +++++++++++++ .../ServerFileBatchCopyObjectRequest.java | 3 ++ .../manager/api/FileBusinessSceneManager.java | 3 ++ .../manager/api/dto/request/AppInfoDto.java | 28 +++++++++++++++++ .../api/dto/request/CopyObjectCloudDto.java | 9 +++--- .../api/dto/request/FileBusinessSceneDto.java | 30 +++++++++++++++++++ .../impl/FileBusinessSceneManagerImpl.java | 7 ++++- .../cn/axzo/oss/service/api/FileService.java | 3 +- .../oss/service/impl/FileServiceImpl.java | 27 ++++++++++++----- 12 files changed, 131 insertions(+), 14 deletions(-) create mode 100644 oss-dal/src/main/java/cn/axzo/oss/dal/vo/FileBusinessSceneVo.java create mode 100644 oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/AppInfoDto.java create mode 100644 oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/FileBusinessSceneDto.java diff --git a/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java b/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java index 6ca999c..5160c98 100644 --- a/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java +++ b/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java @@ -35,6 +35,7 @@ import cn.axzo.oss.http.model.file.FileRenameRequest; import cn.axzo.oss.http.model.file.FileRenameResponse; import cn.axzo.oss.http.model.file.UpdateFileInfoRequest; import cn.axzo.oss.http.model.file.UpdateFileInfoResponse; +import cn.axzo.oss.manager.api.dto.request.AppInfoDto; import cn.axzo.oss.manager.api.dto.request.FileCopyObjectDto; import cn.axzo.oss.manager.api.dto.request.FindFileKeyDto; import cn.axzo.oss.manager.api.dto.request.FindFileUrlDto; @@ -244,7 +245,7 @@ public class ServerFileController implements ServerFileServiceApi { public CommonResponse batchCopyObject(@Valid @RequestBody ServerFileBatchCopyObjectRequest request) { AssertUtil.isFalse(Objects.isNull(request) || CollectionUtils.isEmpty(request.getCopyObjects()), "入参为空"); List fileCopyObjectDtos = BeanUtil.copyToList(request.getCopyObjects(), FileCopyObjectDto.class); - List fileCopyObjectResponses = fileService.batchCopyObject(fileCopyObjectDtos, request.getAppCode()); + List fileCopyObjectResponses = fileService.batchCopyObject(fileCopyObjectDtos, AppInfoDto.builder().appCode(request.getAppCode()).bizScene(request.getBizScene()).build()); return CommonResponse.success(ServerFileBatchCopyObjectResponse.builder().responses(BeanUtil.copyToList(fileCopyObjectResponses, ServerFileBatchCopyObjectResponse.ServerFileCopyObjectResponse.class)).build()); } diff --git a/oss-dal/src/main/java/cn/axzo/oss/dal/repository/FileBusinessSceneDao.java b/oss-dal/src/main/java/cn/axzo/oss/dal/repository/FileBusinessSceneDao.java index 293be8e..a3c9c04 100644 --- a/oss-dal/src/main/java/cn/axzo/oss/dal/repository/FileBusinessSceneDao.java +++ b/oss-dal/src/main/java/cn/axzo/oss/dal/repository/FileBusinessSceneDao.java @@ -1,6 +1,7 @@ package cn.axzo.oss.dal.repository; import cn.axzo.oss.dal.entity.FileBusinessScene; +import cn.axzo.oss.dal.vo.FileBusinessSceneVo; import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; @@ -30,4 +31,6 @@ public interface FileBusinessSceneDao extends IService { * 根据bucketNo与场景,获取批量FileBusinessScene对象 */ List queryByBucketNoAndScene(Set bucketNoList, String bizScen); + + List findByCondition(FileBusinessSceneVo vo); } diff --git a/oss-dal/src/main/java/cn/axzo/oss/dal/repository/impl/FileBusinessSceneDaoImpl.java b/oss-dal/src/main/java/cn/axzo/oss/dal/repository/impl/FileBusinessSceneDaoImpl.java index 92b5279..6bcf72e 100644 --- a/oss-dal/src/main/java/cn/axzo/oss/dal/repository/impl/FileBusinessSceneDaoImpl.java +++ b/oss-dal/src/main/java/cn/axzo/oss/dal/repository/impl/FileBusinessSceneDaoImpl.java @@ -4,6 +4,7 @@ import cn.axzo.oss.common.enums.IsDeleteEnum; import cn.axzo.oss.dal.entity.FileBusinessScene; import cn.axzo.oss.dal.mapper.FileBusinessSceneMapper; import cn.axzo.oss.dal.repository.FileBusinessSceneDao; +import cn.axzo.oss.dal.vo.FileBusinessSceneVo; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.google.common.collect.Lists; import org.apache.commons.lang3.StringUtils; @@ -50,4 +51,12 @@ public class FileBusinessSceneDaoImpl extends .eq(StringUtils.isNotBlank(bizScene), FileBusinessScene::getBusinessScene, StringUtils.isNotBlank(bizScene) ? bizScene : StringUtils.EMPTY) .eq(FileBusinessScene::getIsDelete, IsDeleteEnum.NO.getCode()).list(); } + + @Override + public List findByCondition(FileBusinessSceneVo vo) { + return lambdaQuery().eq(FileBusinessScene::getAppCode, vo.getAppCode()) + .eq(FileBusinessScene::getBusinessScene,vo.getBusinessScene()) + .eq(FileBusinessScene::getIsDelete, IsDeleteEnum.NO.getCode()).list(); + } + } diff --git a/oss-dal/src/main/java/cn/axzo/oss/dal/vo/FileBusinessSceneVo.java b/oss-dal/src/main/java/cn/axzo/oss/dal/vo/FileBusinessSceneVo.java new file mode 100644 index 0000000..b86f9c8 --- /dev/null +++ b/oss-dal/src/main/java/cn/axzo/oss/dal/vo/FileBusinessSceneVo.java @@ -0,0 +1,20 @@ +package cn.axzo.oss.dal.vo; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author xudawei@axzo.cn + * @date 2025/3/20 + * @description FileBusinessSceneVo + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class FileBusinessSceneVo { + private String appCode; + private String businessScene; +} diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java index 3b85a78..9157f4c 100644 --- a/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java @@ -24,6 +24,9 @@ public class ServerFileBatchCopyObjectRequest { @NotBlank(message = "appCode must not be null") private String appCode; + @NotBlank(message = "bizScene must not be null") + private String bizScene; + @NotEmpty(message = "集合对象不能为空") private Set copyObjects; diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/FileBusinessSceneManager.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/FileBusinessSceneManager.java index 4eb53ff..f0ce799 100644 --- a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/FileBusinessSceneManager.java +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/FileBusinessSceneManager.java @@ -1,6 +1,7 @@ package cn.axzo.oss.manager.api; import cn.axzo.oss.dal.entity.FileBusinessScene; +import cn.axzo.oss.dal.vo.FileBusinessSceneVo; import java.util.List; import java.util.Set; @@ -25,4 +26,6 @@ public interface FileBusinessSceneManager { * 指定appcode文件业务场景 */ List queryByBucketNoAndScene(Set bucketNoList, String bizScene); + + List findByCondition(FileBusinessSceneVo vo); } diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/AppInfoDto.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/AppInfoDto.java new file mode 100644 index 0000000..e25496e --- /dev/null +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/AppInfoDto.java @@ -0,0 +1,28 @@ +package cn.axzo.oss.manager.api.dto.request; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author xudawei@axzo.cn + * @date 2025/3/20 + * @description app + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class AppInfoDto { + + /** + * appCode + */ + private String appCode; + /** + * bizScene + */ + private String bizScene; + +} diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java index 90375ca..ccbc884 100644 --- a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java @@ -2,6 +2,7 @@ package cn.axzo.oss.manager.api.dto.request; import cn.axzo.oss.common.utils.Utility; import cn.axzo.oss.dal.entity.File; +import cn.axzo.oss.dal.entity.FileBusinessScene; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -64,11 +65,11 @@ public class CopyObjectCloudDto { private File file; private String fileUuid; - public static CopyObjectCloudDto create(FileCopyObjectDto fileCopyObjectRequest, File file) { + public static CopyObjectCloudDto create(FileCopyObjectDto fileCopyObjectRequest, File file, FileBusinessScene fileBusinessScene) { // 入参中有通道,则优先取入参;否则取源通道 - String targetChannelCode = StringUtils.isBlank(fileCopyObjectRequest.getTargetChannelCode()) ? file.getChannelCode() : fileCopyObjectRequest.getTargetChannelCode(); - String targetBucketName = StringUtils.isBlank(fileCopyObjectRequest.getTargetBucketName()) ? file.getBucketName() : fileCopyObjectRequest.getTargetBucketName(); - String targetBucketDict = StringUtils.isBlank(fileCopyObjectRequest.getTargetDict()) ? file.getDirectory() : fileCopyObjectRequest.getTargetDict(); + String targetChannelCode = StringUtils.isBlank(fileCopyObjectRequest.getTargetChannelCode()) ? fileBusinessScene.getChannelCode() : fileCopyObjectRequest.getTargetChannelCode(); + String targetBucketName = StringUtils.isBlank(fileCopyObjectRequest.getTargetBucketName()) ? fileBusinessScene.getBucketName() : fileCopyObjectRequest.getTargetBucketName(); + String targetBucketDict = StringUtils.isBlank(fileCopyObjectRequest.getTargetDict()) ? fileBusinessScene.getDirectory() : fileCopyObjectRequest.getTargetDict(); String fileName = StringUtils.isBlank(fileCopyObjectRequest.getTargetFileName()) ? file.getFileName() : fileCopyObjectRequest.getTargetFileName(); String uuid = Utility.getUUID(); diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/FileBusinessSceneDto.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/FileBusinessSceneDto.java new file mode 100644 index 0000000..0b22a70 --- /dev/null +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/FileBusinessSceneDto.java @@ -0,0 +1,30 @@ +package cn.axzo.oss.manager.api.dto.request; + +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author xudawei@axzo.cn + * @date 2025/3/20 + * @description FileBusinessSceneDto + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FileBusinessSceneDto { + + /** + * 应用编码 + */ + private String appCode; + + /** + * 业务场景 + */ + private String businessScene; + +} diff --git a/oss-manager/src/main/java/cn/axzo/oss/manager/impl/FileBusinessSceneManagerImpl.java b/oss-manager/src/main/java/cn/axzo/oss/manager/impl/FileBusinessSceneManagerImpl.java index 9746d2c..685ffc9 100644 --- a/oss-manager/src/main/java/cn/axzo/oss/manager/impl/FileBusinessSceneManagerImpl.java +++ b/oss-manager/src/main/java/cn/axzo/oss/manager/impl/FileBusinessSceneManagerImpl.java @@ -4,10 +4,10 @@ import cn.axzo.oss.common.enums.CodeEnum; import cn.axzo.oss.common.exception.BizException; import cn.axzo.oss.dal.entity.FileBusinessScene; import cn.axzo.oss.dal.repository.FileBusinessSceneDao; +import cn.axzo.oss.dal.vo.FileBusinessSceneVo; import cn.axzo.oss.manager.api.FileBusinessSceneManager; import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; @@ -53,4 +53,9 @@ public class FileBusinessSceneManagerImpl implements FileBusinessSceneManager { return fileBusinessSceneDao .queryByBucketNoAndScene(bucketNoList, bizScene); } + + @Override + public List findByCondition(FileBusinessSceneVo vo) { + return fileBusinessSceneDao.findByCondition(vo); + } } diff --git a/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileService.java b/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileService.java index 0523cdb..8a67ab9 100644 --- a/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileService.java +++ b/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileService.java @@ -3,6 +3,7 @@ package cn.axzo.oss.service.api; import cn.axzo.framework.auth.domain.ContextInfo; import cn.axzo.oss.dal.entity.AppChannelBucket; import cn.axzo.oss.dal.entity.FileUploadConfig; +import cn.axzo.oss.manager.api.dto.request.AppInfoDto; import cn.axzo.oss.manager.api.dto.request.DeleteFileDto; import cn.axzo.oss.manager.api.dto.request.FileCopyObjectDto; import cn.axzo.oss.manager.api.dto.request.FindFileKeyDto; @@ -127,7 +128,7 @@ public interface FileService { * 1 不同通道,则通过url进行复制 * 2 相同通道,则直接调用复制方法 */ - List batchCopyObject(List dtoList, String appCode); + List batchCopyObject(List dtoList, AppInfoDto appInfoDto); /** * 更新文件信息 diff --git a/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java index 607ba84..6153818 100644 --- a/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java +++ b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java @@ -26,12 +26,14 @@ import cn.axzo.oss.dal.entity.FileBusinessScene; import cn.axzo.oss.dal.entity.FileUploadConfig; import cn.axzo.oss.dal.repository.FileAppDao; import cn.axzo.oss.dal.repository.FileDao; +import cn.axzo.oss.dal.vo.FileBusinessSceneVo; import cn.axzo.oss.integration.s3.config.HuaWeiCloudObsConfig; import cn.axzo.oss.manager.api.AppChannelBucketManager; import cn.axzo.oss.manager.api.FileBusinessSceneManager; import cn.axzo.oss.manager.api.FileManager; import cn.axzo.oss.manager.api.FileUploadConfigManager; import cn.axzo.oss.manager.api.dto.PartETag; +import cn.axzo.oss.manager.api.dto.request.AppInfoDto; import cn.axzo.oss.manager.api.dto.request.CopyObjectCloudDto; import cn.axzo.oss.manager.api.dto.request.DeleteFileDto; import cn.axzo.oss.manager.api.dto.request.FileCopyObjectDto; @@ -1268,12 +1270,12 @@ public class FileServiceImpl implements FileService { * 1 不同通道,则通过url进行复制 * 2 相同通道,则直接调用复制方法 */ - public List batchCopyObject(List dtoList, String appCode) { + public List batchCopyObject(List dtoList, AppInfoDto appInfoDto) { AssertUtil.isFalse(CollectionUtils.isEmpty(dtoList), "请求入参为空"); //校验appCode - this.checkAppCode(appCode); + this.checkAppCode(appInfoDto.getAppCode()); //通过fileKeys复制文件 - List cloudDtos = this.batchCopyObjectByFileKeys(dtoList); + List cloudDtos = this.batchCopyObjectByFileKeys(dtoList, appInfoDto); //保存文件表 return this.saveFiles(cloudDtos); } @@ -1324,7 +1326,7 @@ public class FileServiceImpl implements FileService { /** * 通过fileKeys复制文件 */ - private List batchCopyObjectByFileKeys(List dtoList) { + private List batchCopyObjectByFileKeys(List dtoList, AppInfoDto appInfoDto) { List fileKeys = dtoList.stream() .filter(item -> StringUtils.isNotBlank(item.getSrcFileKey())) .map(FileCopyObjectDto::getSrcFileKey).collect(Collectors.toList()); @@ -1339,7 +1341,7 @@ public class FileServiceImpl implements FileService { return Lists.newArrayList(); } //通过文件表,完成文件对象复制 - return this.doBatchCopyObjectByFiles(reqFileKeyMap, fileList); + return this.doBatchCopyObjectByFiles(reqFileKeyMap, fileList, appInfoDto); } /** @@ -1347,8 +1349,9 @@ public class FileServiceImpl implements FileService { * 注意,此方法是根据业务文件复制 * 底层通用方法fileManager.copyObjects(dto); */ - private List doBatchCopyObjectByFiles(Map reqFileKeyMap, List fileList) { + private List doBatchCopyObjectByFiles(Map reqFileKeyMap, List fileList, AppInfoDto appInfoDto) { List returnList = Lists.newArrayList(); + FileBusinessScene fileBusinessScene = this.fetchBizSceneByAppCodeAndBizScene(appInfoDto); for (File file : fileList) { if (Objects.isNull(reqFileKeyMap.get(file.getFileUuid()))) { continue; @@ -1357,7 +1360,7 @@ public class FileServiceImpl implements FileService { if (Objects.isNull(fileCopyObjectRequest)) { continue; } - CopyObjectCloudDto dto = CopyObjectCloudDto.create(fileCopyObjectRequest, file); + CopyObjectCloudDto dto = CopyObjectCloudDto.create(fileCopyObjectRequest, file, fileBusinessScene); this.fileManager.copyObjects(dto); returnList.add(dto); @@ -1365,6 +1368,16 @@ public class FileServiceImpl implements FileService { return returnList; } + private FileBusinessScene fetchBizSceneByAppCodeAndBizScene(AppInfoDto appInfoDto) { + List list = this.fileBusinessSceneManager.findByCondition(FileBusinessSceneVo.builder() + .appCode(appInfoDto.getAppCode()) + .businessScene(appInfoDto.getBizScene()) + .build()); + AssertUtil.notEmpty(list, "文件业务场景未配置"); + AssertUtil.isFalse(list.size() > 1, "文件业务场景匹配多个"); + return list.get(0); + } + /** * 更新文件信息 */ From 911b70631c22cfaf55aec64a4d1cbabb936a2cf6 Mon Sep 17 00:00:00 2001 From: xudawei Date: Thu, 20 Mar 2025 18:48:47 +0800 Subject: [PATCH 13/15] =?UTF-8?q?feat:(REQ-3540)=20=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=85=8B=E9=9A=86-=E5=8A=A0=E4=B8=8AbizScene,=E4=B8=8D?= =?UTF-8?q?=E4=BC=A0=E7=9B=AE=E6=A0=87=E6=A1=B6=E4=B8=8Ekey=EF=BC=8C?= =?UTF-8?q?=E5=88=99=E6=8C=89=E7=85=A7appCode=E4=B8=8EbizScene=E7=9A=84?= =?UTF-8?q?=E4=B8=BA=E5=87=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oss/manager/api/dto/request/CopyObjectCloudDto.java | 6 ++++++ .../java/cn/axzo/oss/service/impl/FileServiceImpl.java | 7 +++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java index ccbc884..ee04c0d 100644 --- a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java @@ -65,6 +65,10 @@ public class CopyObjectCloudDto { private File file; private String fileUuid; + private String appChannelBucketNo; + + private String appCode; + public static CopyObjectCloudDto create(FileCopyObjectDto fileCopyObjectRequest, File file, FileBusinessScene fileBusinessScene) { // 入参中有通道,则优先取入参;否则取源通道 String targetChannelCode = StringUtils.isBlank(fileCopyObjectRequest.getTargetChannelCode()) ? fileBusinessScene.getChannelCode() : fileCopyObjectRequest.getTargetChannelCode(); @@ -86,6 +90,8 @@ public class CopyObjectCloudDto { .targetFileName(fileName) .file(file) .fileUuid(fileCopyObjectRequest.getFileUuid()) + .appChannelBucketNo(fileBusinessScene.getAppChannelBucketNo()) + .appCode(fileBusinessScene.getAppCode()) .build(); } diff --git a/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java index 6153818..e70c1b9 100644 --- a/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java +++ b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java @@ -27,6 +27,7 @@ import cn.axzo.oss.dal.entity.FileUploadConfig; import cn.axzo.oss.dal.repository.FileAppDao; import cn.axzo.oss.dal.repository.FileDao; import cn.axzo.oss.dal.vo.FileBusinessSceneVo; +import cn.axzo.oss.integration.s3.config.CadThirdProperty; import cn.axzo.oss.integration.s3.config.HuaWeiCloudObsConfig; import cn.axzo.oss.manager.api.AppChannelBucketManager; import cn.axzo.oss.manager.api.FileBusinessSceneManager; @@ -47,6 +48,7 @@ import cn.axzo.oss.manager.api.dto.request.MultipartUploadInitDto; import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto; import cn.axzo.oss.manager.api.dto.request.ServerFileDownloadDto; import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto; +import cn.axzo.oss.manager.api.dto.request.SignUploadTokenDto; import cn.axzo.oss.manager.api.dto.request.SignUrlDownloadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto; import cn.axzo.oss.manager.api.dto.request.file.DeleteObjectsFileDto; @@ -62,6 +64,7 @@ import cn.axzo.oss.manager.api.dto.response.ServerFileDownloadResponse; import cn.axzo.oss.manager.api.dto.response.ServerFileUploadResponse; import cn.axzo.oss.manager.api.dto.response.SignUrlDownloadResponse; import cn.axzo.oss.manager.api.dto.response.SignUrlUploadResponse; +import cn.axzo.oss.manager.api.dto.response.UploadTokenResponse; import cn.axzo.oss.service.api.FileService; import cn.axzo.oss.service.metafile.WithFileFactory; import cn.axzo.oss.service.metafile.WithFileService; @@ -1306,8 +1309,8 @@ public class FileServiceImpl implements FileService { */ private File buildFileWhenCopyObject(CopyObjectCloudDto item) { File ossFile = new File(); - ossFile.setAppChannelBucketNo(item.getFile().getAppChannelBucketNo()); - ossFile.setAppCode(item.getFile().getAppCode()); + ossFile.setAppChannelBucketNo(item.getAppChannelBucketNo()); + ossFile.setAppCode(item.getAppCode()); ossFile.setChannelCode(item.getTargetChannelCode()); ossFile.setBucketName(item.getTargetBucketName()); ossFile.setDirectory(item.getTargetBucketDict()); From ba1e0715fd780472ae00a8622b4744b3a2f65181 Mon Sep 17 00:00:00 2001 From: xudawei Date: Fri, 21 Mar 2025 14:09:23 +0800 Subject: [PATCH 14/15] =?UTF-8?q?feat:(REQ-3540)=20=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=85=8B=E9=9A=86-=E5=8A=A0=E4=B8=8AtargetAppCode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ServerFileController.java | 3 ++- .../oss/client/convert/ServerFileConvert.java | 25 ++++++++++++++++++ .../cn/axzo/oss/common/enums/CodeEnum.java | 1 + .../ServerFileBatchCopyObjectRequest.java | 10 +++++++ .../manager/api/dto/request/AppInfoDto.java | 10 +++++++ .../api/dto/request/CopyObjectCloudDto.java | 11 +++++--- .../oss/service/impl/FileServiceImpl.java | 26 +++++++++++++------ 7 files changed, 74 insertions(+), 12 deletions(-) create mode 100644 oss-client/src/main/java/cn/axzo/oss/client/convert/ServerFileConvert.java diff --git a/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java b/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java index 5160c98..02da5a3 100644 --- a/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java +++ b/oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java @@ -3,6 +3,7 @@ package cn.axzo.oss.client.controller; import cn.axzo.basics.common.util.AssertUtil; import cn.axzo.core.utils.converter.BeanConverter; import cn.axzo.framework.auth.domain.ContextInfo; +import cn.axzo.oss.client.convert.ServerFileConvert; import cn.axzo.oss.common.utils.BeanConvertUtil; import cn.axzo.oss.http.api.ServerFileServiceApi; import cn.axzo.oss.http.model.ApiSignUrlDownloadRequest; @@ -245,7 +246,7 @@ public class ServerFileController implements ServerFileServiceApi { public CommonResponse batchCopyObject(@Valid @RequestBody ServerFileBatchCopyObjectRequest request) { AssertUtil.isFalse(Objects.isNull(request) || CollectionUtils.isEmpty(request.getCopyObjects()), "入参为空"); List fileCopyObjectDtos = BeanUtil.copyToList(request.getCopyObjects(), FileCopyObjectDto.class); - List fileCopyObjectResponses = fileService.batchCopyObject(fileCopyObjectDtos, AppInfoDto.builder().appCode(request.getAppCode()).bizScene(request.getBizScene()).build()); + List fileCopyObjectResponses = fileService.batchCopyObject(fileCopyObjectDtos, ServerFileConvert.copyObjectConvertAppInfo(request)); return CommonResponse.success(ServerFileBatchCopyObjectResponse.builder().responses(BeanUtil.copyToList(fileCopyObjectResponses, ServerFileBatchCopyObjectResponse.ServerFileCopyObjectResponse.class)).build()); } diff --git a/oss-client/src/main/java/cn/axzo/oss/client/convert/ServerFileConvert.java b/oss-client/src/main/java/cn/axzo/oss/client/convert/ServerFileConvert.java new file mode 100644 index 0000000..abc372a --- /dev/null +++ b/oss-client/src/main/java/cn/axzo/oss/client/convert/ServerFileConvert.java @@ -0,0 +1,25 @@ +package cn.axzo.oss.client.convert; + +import cn.axzo.oss.http.model.copyobject.ServerFileBatchCopyObjectRequest; +import cn.axzo.oss.manager.api.dto.request.AppInfoDto; + +/** + * @author xudawei@axzo.cn + * @date 2025/3/21 + * @description 对象转换 + */ +public class ServerFileConvert { + + /** + * 克隆对象转换成AppInfo + */ + public static AppInfoDto copyObjectConvertAppInfo(ServerFileBatchCopyObjectRequest request) { + return AppInfoDto.builder() + .appCode(request.getAppCode()) + .bizScene(request.getBizScene()) + .targetAppCode(request.getTargetAppCode()) + .targetBizScene(request.getTargetBizScene()) + .build(); + } + +} diff --git a/oss-common/src/main/java/cn/axzo/oss/common/enums/CodeEnum.java b/oss-common/src/main/java/cn/axzo/oss/common/enums/CodeEnum.java index badc957..4d19a04 100644 --- a/oss-common/src/main/java/cn/axzo/oss/common/enums/CodeEnum.java +++ b/oss-common/src/main/java/cn/axzo/oss/common/enums/CodeEnum.java @@ -64,6 +64,7 @@ public enum CodeEnum implements EnumBase { GET_OBJECT_META_FAIL(507, "获取元文件失败"), URL_BUCKET_NAME_KEY_ALL_EMPTY(508, "url-bucketName-key同时为空"), SIGN_URL_DOWNLOAD_FILEKEYS_EXCEEDS_MAXSIZE(509, "fileKeys exceeds the maximum size"), + FILE_TARGET_APP_IS_EMPTY(510, "target app is empty"), ; private final Integer code; diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java index 9157f4c..b4e4ac1 100644 --- a/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/model/copyobject/ServerFileBatchCopyObjectRequest.java @@ -27,6 +27,16 @@ public class ServerFileBatchCopyObjectRequest { @NotBlank(message = "bizScene must not be null") private String bizScene; + /** + * 目标appCode + */ + private String targetAppCode; + + /** + * 目标bizScene + */ + private String targetBizScene; + @NotEmpty(message = "集合对象不能为空") private Set copyObjects; diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/AppInfoDto.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/AppInfoDto.java index e25496e..1d45f9e 100644 --- a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/AppInfoDto.java +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/AppInfoDto.java @@ -25,4 +25,14 @@ public class AppInfoDto { */ private String bizScene; + /** + * 目标appCode + */ + private String targetAppCode; + + /** + * 目标bizScene + */ + private String targetBizScene; + } diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java index ee04c0d..fd01b6a 100644 --- a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/CopyObjectCloudDto.java @@ -9,6 +9,8 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.apache.commons.lang3.StringUtils; +import java.util.Objects; + /** * @author xudawei@axzo.cn * @date 2025/3/10 @@ -69,13 +71,16 @@ public class CopyObjectCloudDto { private String appCode; - public static CopyObjectCloudDto create(FileCopyObjectDto fileCopyObjectRequest, File file, FileBusinessScene fileBusinessScene) { + public static CopyObjectCloudDto create(FileCopyObjectDto fileCopyObjectRequest, File file, FileBusinessScene fileBusinessScene,FileBusinessScene targetFileBiz) { // 入参中有通道,则优先取入参;否则取源通道 String targetChannelCode = StringUtils.isBlank(fileCopyObjectRequest.getTargetChannelCode()) ? fileBusinessScene.getChannelCode() : fileCopyObjectRequest.getTargetChannelCode(); String targetBucketName = StringUtils.isBlank(fileCopyObjectRequest.getTargetBucketName()) ? fileBusinessScene.getBucketName() : fileCopyObjectRequest.getTargetBucketName(); String targetBucketDict = StringUtils.isBlank(fileCopyObjectRequest.getTargetDict()) ? fileBusinessScene.getDirectory() : fileCopyObjectRequest.getTargetDict(); String fileName = StringUtils.isBlank(fileCopyObjectRequest.getTargetFileName()) ? file.getFileName() : fileCopyObjectRequest.getTargetFileName(); + String appCode = (Objects.isNull(targetFileBiz) || StringUtils.isBlank(targetFileBiz.getAppCode())) ? fileBusinessScene.getAppCode() : targetFileBiz.getAppCode(); + String appChannelBucketNo = (Objects.isNull(targetFileBiz) || StringUtils.isBlank(targetFileBiz.getAppChannelBucketNo())) ? fileBusinessScene.getAppChannelBucketNo() : targetFileBiz.getAppChannelBucketNo(); + String uuid = Utility.getUUID(); return CopyObjectCloudDto.builder() @@ -90,8 +95,8 @@ public class CopyObjectCloudDto { .targetFileName(fileName) .file(file) .fileUuid(fileCopyObjectRequest.getFileUuid()) - .appChannelBucketNo(fileBusinessScene.getAppChannelBucketNo()) - .appCode(fileBusinessScene.getAppCode()) + .appChannelBucketNo(appChannelBucketNo) + .appCode(appCode) .build(); } diff --git a/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java index e70c1b9..9a2c410 100644 --- a/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java +++ b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileServiceImpl.java @@ -27,7 +27,6 @@ import cn.axzo.oss.dal.entity.FileUploadConfig; import cn.axzo.oss.dal.repository.FileAppDao; import cn.axzo.oss.dal.repository.FileDao; import cn.axzo.oss.dal.vo.FileBusinessSceneVo; -import cn.axzo.oss.integration.s3.config.CadThirdProperty; import cn.axzo.oss.integration.s3.config.HuaWeiCloudObsConfig; import cn.axzo.oss.manager.api.AppChannelBucketManager; import cn.axzo.oss.manager.api.FileBusinessSceneManager; @@ -48,7 +47,6 @@ import cn.axzo.oss.manager.api.dto.request.MultipartUploadInitDto; import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto; import cn.axzo.oss.manager.api.dto.request.ServerFileDownloadDto; import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto; -import cn.axzo.oss.manager.api.dto.request.SignUploadTokenDto; import cn.axzo.oss.manager.api.dto.request.SignUrlDownloadDto; import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto; import cn.axzo.oss.manager.api.dto.request.file.DeleteObjectsFileDto; @@ -64,7 +62,6 @@ import cn.axzo.oss.manager.api.dto.response.ServerFileDownloadResponse; import cn.axzo.oss.manager.api.dto.response.ServerFileUploadResponse; import cn.axzo.oss.manager.api.dto.response.SignUrlDownloadResponse; import cn.axzo.oss.manager.api.dto.response.SignUrlUploadResponse; -import cn.axzo.oss.manager.api.dto.response.UploadTokenResponse; import cn.axzo.oss.service.api.FileService; import cn.axzo.oss.service.metafile.WithFileFactory; import cn.axzo.oss.service.metafile.WithFileService; @@ -1354,7 +1351,10 @@ public class FileServiceImpl implements FileService { */ private List doBatchCopyObjectByFiles(Map reqFileKeyMap, List fileList, AppInfoDto appInfoDto) { List returnList = Lists.newArrayList(); - FileBusinessScene fileBusinessScene = this.fetchBizSceneByAppCodeAndBizScene(appInfoDto); + // key:appCode的对象 + // value:targetAppCode的对象 + Pair pair = this.checkBatchCopyObject(appInfoDto); + for (File file : fileList) { if (Objects.isNull(reqFileKeyMap.get(file.getFileUuid()))) { continue; @@ -1363,7 +1363,7 @@ public class FileServiceImpl implements FileService { if (Objects.isNull(fileCopyObjectRequest)) { continue; } - CopyObjectCloudDto dto = CopyObjectCloudDto.create(fileCopyObjectRequest, file, fileBusinessScene); + CopyObjectCloudDto dto = CopyObjectCloudDto.create(fileCopyObjectRequest, file, pair.getKey(), pair.getValue()); this.fileManager.copyObjects(dto); returnList.add(dto); @@ -1371,10 +1371,20 @@ public class FileServiceImpl implements FileService { return returnList; } - private FileBusinessScene fetchBizSceneByAppCodeAndBizScene(AppInfoDto appInfoDto) { + private Pair checkBatchCopyObject(AppInfoDto appInfoDto) { + FileBusinessScene fileBusinessScene = this.fetchBizSceneByAppCodeAndBizScene(appInfoDto.getAppCode(), appInfoDto.getBizScene()); + FileBusinessScene targetFileBiz = null; + if (StringUtils.isNotBlank(appInfoDto.getTargetAppCode()) && StringUtils.isNotBlank(appInfoDto.getTargetBizScene())) { + targetFileBiz = this.fetchBizSceneByAppCodeAndBizScene(appInfoDto.getTargetAppCode(), appInfoDto.getTargetBizScene()); + BizException.error(Utility.objIsNotNull(targetFileBiz), CodeEnum.FILE_TARGET_APP_IS_EMPTY); + } + return Pair.of(fileBusinessScene, targetFileBiz); + } + + private FileBusinessScene fetchBizSceneByAppCodeAndBizScene(String appCode, String bizScene) { List list = this.fileBusinessSceneManager.findByCondition(FileBusinessSceneVo.builder() - .appCode(appInfoDto.getAppCode()) - .businessScene(appInfoDto.getBizScene()) + .appCode(appCode) + .businessScene(bizScene) .build()); AssertUtil.notEmpty(list, "文件业务场景未配置"); AssertUtil.isFalse(list.size() > 1, "文件业务场景匹配多个"); From 8b18471de8df61af3392d275fe859e8bb22bd220 Mon Sep 17 00:00:00 2001 From: xudawei Date: Tue, 25 Mar 2025 16:32:04 +0800 Subject: [PATCH 15/15] =?UTF-8?q?feat:(REQ-3540)=20=E9=87=8D=E5=91=BD?= =?UTF-8?q?=E5=90=8Dbug=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/cn/axzo/oss/dal/repository/impl/FileDaoImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oss-dal/src/main/java/cn/axzo/oss/dal/repository/impl/FileDaoImpl.java b/oss-dal/src/main/java/cn/axzo/oss/dal/repository/impl/FileDaoImpl.java index f139101..672a734 100644 --- a/oss-dal/src/main/java/cn/axzo/oss/dal/repository/impl/FileDaoImpl.java +++ b/oss-dal/src/main/java/cn/axzo/oss/dal/repository/impl/FileDaoImpl.java @@ -84,7 +84,7 @@ public class FileDaoImpl extends ServiceImpl implements FileDa */ @Override public boolean updateFileById(File file) { - if (Objects.isNull(file) || Objects.isNull(file.getId()) || StringUtils.isBlank(file.getFileUuid())) { + if (Objects.isNull(file) || Objects.isNull(file.getId())) { return false; } return lambdaUpdate().eq(File::getId, file.getId())