From 0af4e47039e89ac3053bb1c0b88ad391d34df774 Mon Sep 17 00:00:00 2001 From: xudawei Date: Mon, 1 Jul 2024 16:26:38 +0800 Subject: [PATCH 1/3] =?UTF-8?q?[REQ-2259]=E4=B8=8A=E4=BC=A0=E8=87=B3?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/ServerFileController.java | 18 +++++ .../oss/http/api/ServerFileServiceApi.java | 10 +++ .../model/ServerFileCopyToDictRequest.java | 39 ++++++++++ .../model/ServerFileCopyToDictResponse.java | 22 ++++++ .../integration/s3/HuaWeiCloudService.java | 5 ++ .../s3/impl/HuaWeiCloudServiceImpl.java | 24 +++++- .../cn/axzo/oss/manager/api/FileManager.java | 8 ++ .../dto/request/ServerFileCopyToDictDto.java | 42 +++++++++++ .../oss/manager/impl/FileManagerImpl.java | 48 +++++++++++- .../service/api/FileCopyToDictService.java | 14 ++++ .../cn/axzo/oss/service/api/FileService.java | 13 ++++ .../impl/FileCopyToDictServiceImpl.java | 73 +++++++++++++++++++ .../oss/service/impl/FileServiceImpl.java | 43 ++++++----- 13 files changed, 339 insertions(+), 20 deletions(-) create mode 100644 oss-http-api/src/main/java/cn/axzo/oss/http/model/ServerFileCopyToDictRequest.java create mode 100644 oss-http-api/src/main/java/cn/axzo/oss/http/model/ServerFileCopyToDictResponse.java create mode 100644 oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/ServerFileCopyToDictDto.java create mode 100644 oss-service-api/src/main/java/cn/axzo/oss/service/api/FileCopyToDictService.java create mode 100644 oss-service/src/main/java/cn/axzo/oss/service/impl/FileCopyToDictServiceImpl.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 2f2a617..6b917fa 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 @@ -21,6 +21,8 @@ import cn.axzo.oss.http.model.FindFileUrlRequest; import cn.axzo.oss.http.model.FindFileUrlResponse; import cn.axzo.oss.http.model.GetObjectMetaRequest; import cn.axzo.oss.http.model.GetObjectMetaResponse; +import cn.axzo.oss.http.model.ServerFileCopyToDictRequest; +import cn.axzo.oss.http.model.ServerFileCopyToDictResponse; import cn.axzo.oss.http.model.ServerFileDeleteRequest; import cn.axzo.oss.http.model.ServerFileUploadByUrlRequest; import cn.axzo.oss.http.model.ServerFileUploadRequest; @@ -28,6 +30,7 @@ import cn.axzo.oss.http.model.ServerFileUploadResponse; import cn.axzo.oss.http.model.ServerFileUploadV2Request; 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.ServerFileDeleteDto; import cn.axzo.oss.manager.api.dto.request.ServerFileUploadByUrlDto; import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto; @@ -35,6 +38,7 @@ 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.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.json.JSONUtil; @@ -68,6 +72,9 @@ public class ServerFileController implements ServerFileServiceApi { @Autowired private FileByUrlService fileByUrlService; + @Autowired + private FileCopyToDictService fileCopyToDictService; + @Autowired private HttpServletRequest httpServletRequest; @@ -214,4 +221,15 @@ public class ServerFileController implements ServerFileServiceApi { ContextInfo.LiteSaasContext liteSaasContext = JSONUtil.toBean(contextInfoLiteJsonStr, ContextInfo.LiteSaasContext.class); return CommonResponse.success(BeanConverter.convert(fileByUrlService.uploadByUrl(dto.getAppCode(), dto.getBizScene(), dto.getFileName(), dto.getFileUrl(), dto.getChannelCode(), dto.getStyle(), liteSaasContext), ServerFileUploadResponse.class)); } + + /** + * 通过URL上传文件 + * @param request + * @return + */ + public CommonResponse copyToDict(@Valid @RequestBody ServerFileCopyToDictRequest request) { + ServerFileCopyToDictDto dto = BeanConvertUtil.copyBean(request, ServerFileCopyToDictDto.class); + String targetFileKey = fileCopyToDictService.copyToDict(dto); + return CommonResponse.success(ServerFileCopyToDictResponse.builder().targetFileKey(targetFileKey).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 b3ce9d0..1f9a521 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 @@ -13,6 +13,8 @@ import cn.axzo.oss.http.model.FindFileUrlRequest; import cn.axzo.oss.http.model.FindFileUrlResponse; import cn.axzo.oss.http.model.GetObjectMetaRequest; import cn.axzo.oss.http.model.GetObjectMetaResponse; +import cn.axzo.oss.http.model.ServerFileCopyToDictRequest; +import cn.axzo.oss.http.model.ServerFileCopyToDictResponse; import cn.axzo.oss.http.model.ServerFileDeleteRequest; import cn.axzo.oss.http.model.ServerFileUploadByUrlRequest; import cn.axzo.oss.http.model.ServerFileUploadRequest; @@ -107,4 +109,12 @@ public interface ServerFileServiceApi { @RequestMapping(value = "/api/v1/server/uploadByUrl", method = RequestMethod.POST) CommonResponse uploadByUrl(ServerFileUploadByUrlRequest request); + /** + * 通过URL上传文件 + * @param request + * @return + */ + @RequestMapping(value = "/api/server/copyToDict", method = RequestMethod.POST) + CommonResponse copyToDict(ServerFileCopyToDictRequest request); + } diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/model/ServerFileCopyToDictRequest.java b/oss-http-api/src/main/java/cn/axzo/oss/http/model/ServerFileCopyToDictRequest.java new file mode 100644 index 0000000..6d0b802 --- /dev/null +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/model/ServerFileCopyToDictRequest.java @@ -0,0 +1,39 @@ +package cn.axzo.oss.http.model; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 复制至指定目录下 + * + * @author xudawei + * @date 2024-07-01 + */ +@Data +public class ServerFileCopyToDictRequest { + + @NotBlank(message = "appCode must not be null") + private String appCode; + @NotBlank(message = "bizScene must not be null") + private String bizScene; + @NotBlank(message = "fileName must not be null") + + @NotNull(message = "fileKey must not be null") + private String fileKey; + + @NotNull(message = "fileKey must not be null") + private String targetDict; + + private Integer channelCode; + /** + * 图片样式,比如x-oss-process=image/auto-orient,1/resize,p_50/quality,q_30 + */ + private String style; + + /** + * 最大文件大小 + */ + private Long maxFileSize; +} diff --git a/oss-http-api/src/main/java/cn/axzo/oss/http/model/ServerFileCopyToDictResponse.java b/oss-http-api/src/main/java/cn/axzo/oss/http/model/ServerFileCopyToDictResponse.java new file mode 100644 index 0000000..684e2b0 --- /dev/null +++ b/oss-http-api/src/main/java/cn/axzo/oss/http/model/ServerFileCopyToDictResponse.java @@ -0,0 +1,22 @@ +package cn.axzo.oss.http.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 复制至指定目录下 + * + * @author xudawei + * @date 2024-07-01 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class ServerFileCopyToDictResponse { + + private String targetFileKey; + +} 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 ec41f89..efe3385 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 @@ -51,4 +51,9 @@ public interface HuaWeiCloudService { * 元数据 */ ObjectMetadata getObjectMeta(String bucketName, String key, String url); + + /** + * 元数据 + */ + boolean copyToDict(String bucketName, String key, String targetBucketName, String targetKey); } 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 ca562c1..acc8d97 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,6 +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.DeleteObjectResult; import com.obs.services.model.DownloadFileRequest; import com.obs.services.model.DownloadFileResult; @@ -468,7 +469,28 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService { return new ObjectMetadata(); } catch (Exception e) { log.warn("huaweicloud-getObjectMeta-exception, bucketName:{}, key:{}", bucketName, key, e); - return new ObjectMetadata(); + ObjectMetadata objectMetadata = new ObjectMetadata(); + objectMetadata.setContentLength(0L); + return objectMetadata; + } + } + + /** + * 元数据 + */ + @Override + public boolean copyToDict(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; + } catch (Exception e) { + log.warn("huaweicloud-copyToDict-exception, bucketName:{}, key:{}", bucketName, key, e); + return false; } } 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 38520e0..1f4cb88 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.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 org.springframework.web.multipart.MultipartFile; @@ -87,4 +88,11 @@ public interface FileManager { */ String uploadByUrl(String bulkName, String keyPath, String fileName, String url, String channelCode); + + SignUrlDownloadResponse fetchDownloadUrl(String bucketType, String bucketName, String bucketKey, String channelCode, Long expire, String fileName, String style, boolean hasFileName); + + /** + * 构建公开Style + */ + String buildPublicXImageProcess(String url, String style); } diff --git a/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/ServerFileCopyToDictDto.java b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/ServerFileCopyToDictDto.java new file mode 100644 index 0000000..693c197 --- /dev/null +++ b/oss-manager-api/src/main/java/cn/axzo/oss/manager/api/dto/request/ServerFileCopyToDictDto.java @@ -0,0 +1,42 @@ +package cn.axzo.oss.manager.api.dto.request; + +import lombok.Data; +import org.hibernate.validator.constraints.Length; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 复制至指定目录下 + * + * @author xudawei + * @date 2024-07-01 + */ +@Data +public class ServerFileCopyToDictDto { + + @NotBlank(message = "appCode must not be null") + private String appCode; + @NotBlank(message = "bizScene must not be null") + private String bizScene; + @NotBlank(message = "fileName must not be null") + @Length(max = 128, message = "文件名不能超过128个字符") + private String fileName; + @NotNull(message = "fileKey must not be null") + private String fileKey; + + @NotNull(message = "targetDict must not be null") + private String targetDict; + + private Integer channelCode; + /** + * 图片样式,比如x-oss-process=image/auto-orient,1/resize,p_50/quality,q_30 + */ + private String style; + + /** + * 最大文件大小 + */ + private Long maxFileSize; + +} 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 ae55f60..7cab2bb 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,6 +14,7 @@ import cn.axzo.oss.manager.api.FileManager; import cn.axzo.oss.manager.api.dto.PartETag; 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.aliyun.oss.model.SimplifiedObjectMeta; import com.obs.services.model.ObjectMetadata; @@ -22,6 +23,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; @@ -29,6 +31,7 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * @Author admin @@ -49,6 +52,9 @@ public class FileManagerImpl implements FileManager { private final String HUAWEI_CLOUD_SIGNURL_UPLOAD_HOST_KEY = "Host"; private final String HUAWEI_CLOUD_SIGNURL_UPLOAD_CONTENT_TYPE_KEY = "Content-Type"; + @Value("${sign.url.download.expire.second:2000}") + private Long SIGN_URL_DOWNLOAD_EXPIRE_SECOND; + /** * 删除文件 * @@ -290,10 +296,50 @@ public class FileManagerImpl implements FileManager { BizException.error(CodeEnum.CHANNEL_TYPE_NOT_EXIST); } } catch (Exception e) { - log.error("通过url上传至云 exception,bulkName:{}, key:{}, fileName:{}, url:{},channelCode:{}" + log.warn("通过url上传至云 exception,bulkName:{}, key:{}, fileName:{}, url:{},channelCode:{}" , bulkName, keyPath, fileName, url, channelCode, e); + return StringUtils.EMPTY; } return StringUtils.EMPTY; } + + @Override + public SignUrlDownloadResponse fetchDownloadUrl(String bucketType, String bucketName, String bucketKey , String channelCode, Long expire, String fileName, String style, boolean hasFileName) { + switch (BucketTypeEnum.getByCode(bucketType)) { + case PUBLIC_BUCKET://公有桶 - 永久链接,例如 http://xxx.png + String url = this.fetchDownloadUrl(bucketName, bucketKey, channelCode); + return SignUrlDownloadResponse.builder() + .signUrl(this.buildPublicXImageProcess(url, style)) + .fileName(fileName) + .build(); + case PRIVATE_BUCKET://私有桶 - 临时授权链接 例如 http://xxx.png?Expire=a&AccessKeyId=b&Signature=c&repsonse-content-disposition=d + String signUrl = this.signUrlDownload(bucketName, bucketKey, Objects.nonNull(expire) ? expire : SIGN_URL_DOWNLOAD_EXPIRE_SECOND , channelCode, fileName, style, hasFileName); + return SignUrlDownloadResponse.builder() + .signUrl(UrlUtil.httpToHttps(signUrl)) + .fileName(fileName) + .build(); + default: + BizException.error(CodeEnum.CHANNEL_TYPE_NOT_EXIST); + } + return SignUrlDownloadResponse.builder().build(); + } + + /** + * 构建公开Style + */ + @Override + public String buildPublicXImageProcess(String url, String style) { + if (StringUtils.isBlank(style)) { + return url; + } + if (url.toLowerCase().contains(UrlUtil.ALIYUN) && !url.toLowerCase().contains(UrlUtil.X_OSS_PROCESS)) { + return url + UrlUtil.X_OSS_PROCESS_APPEND + style; + } + if (url.toLowerCase().contains(UrlUtil.HUAWEICLOUD) && !url.toLowerCase().contains(UrlUtil.X_IMAGE_PROCESS)) { + return url + UrlUtil.X_IMAGE_PROCESS_APPEND + style; + } + return url; + } + } diff --git a/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileCopyToDictService.java b/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileCopyToDictService.java new file mode 100644 index 0000000..a0f61ba --- /dev/null +++ b/oss-service-api/src/main/java/cn/axzo/oss/service/api/FileCopyToDictService.java @@ -0,0 +1,14 @@ +package cn.axzo.oss.service.api; + +import cn.axzo.oss.manager.api.dto.request.ServerFileCopyToDictDto; + +/** + * @author xudawei@axzo.cn + * @date 2024/7/1 + * @description TODO + */ +public interface FileCopyToDictService { + + String copyToDict(ServerFileCopyToDictDto dto); + +} 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 932fc3c..85d6451 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 @@ -1,6 +1,8 @@ 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.DeleteFileDto; import cn.axzo.oss.manager.api.dto.request.FindFileKeyDto; import cn.axzo.oss.manager.api.dto.request.FindFileUrlDto; @@ -23,6 +25,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.hutool.core.lang.Pair; import org.springframework.web.multipart.MultipartFile; import java.util.List; @@ -92,4 +95,14 @@ public interface FileService { * 元数据 */ ManaGetObjectMetaResponse getObjectMeta(String bucketName, String key, String url,String channelCode); + + /** + * 获取桶配置 + */ + FileUploadConfig getFileUploadConfig(String appCode, String bizScene, Integer channelType); + + /** + * 获取桶基础与配置 + */ + Pair channelBucketAndConfig(String appCode, String bizScene, Integer channelType); } diff --git a/oss-service/src/main/java/cn/axzo/oss/service/impl/FileCopyToDictServiceImpl.java b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileCopyToDictServiceImpl.java new file mode 100644 index 0000000..099c9a0 --- /dev/null +++ b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileCopyToDictServiceImpl.java @@ -0,0 +1,73 @@ +package cn.axzo.oss.service.impl; + +import cn.axzo.oss.common.utils.Utility; +import cn.axzo.oss.dal.entity.AppChannelBucket; +import cn.axzo.oss.dal.entity.File; +import cn.axzo.oss.dal.entity.FileUploadConfig; +import cn.axzo.oss.dal.repository.FileDao; +import cn.axzo.oss.manager.api.FileManager; +import cn.axzo.oss.manager.api.dto.request.ServerFileCopyToDictDto; +import cn.axzo.oss.manager.api.dto.response.ManaGetObjectMetaResponse; +import cn.axzo.oss.manager.api.dto.response.SignUrlDownloadResponse; +import cn.axzo.oss.service.api.FileCopyToDictService; +import cn.axzo.oss.service.api.FileService; +import cn.hutool.core.lang.Pair; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.stereotype.Service; + +import java.util.Objects; + +/** + * @Author admin + * @Description + * @Date 2021/7/28 22:48 + * @Version 0.0.1 + **/ +@Service +@RefreshScope +@Slf4j +public class FileCopyToDictServiceImpl implements FileCopyToDictService { + + @Autowired + private FileService fileService; + + @Autowired + private FileManager fileManager; + + @Autowired + private FileDao fileDao; + @Value("${sign.url.download.expire.second:2000}") + private Long SIGN_URL_DOWNLOAD_EXPIRE_SECOND; + + @Override + public String copyToDict(ServerFileCopyToDictDto dto) { + //1 获取桶基础与配置 + Pair pair = this.fileService.channelBucketAndConfig(dto.getAppCode(), dto.getBizScene(), dto.getChannelCode()); + + AppChannelBucket appChannelBucket = pair.getKey(); + FileUploadConfig fileUploadConfig = pair.getValue(); + //2 获取文件信息 + File byFileUuid = this.fileDao.getByFileUuid(dto.getFileKey()); + String sourceFileKey = Utility.generateFileKey(byFileUuid.getDirectory(), dto.getFileKey(), byFileUuid.getFileFormat()); + String targetFileKey = Utility.generateFileKey(fileUploadConfig.getDirectory() + "_" + dto.getTargetDict(), dto.getFileKey(), byFileUuid.getFileFormat()); + + //3 获取下载文件url(支持:公有桶/私有桶) + SignUrlDownloadResponse downloadResponse = this.fileManager.fetchDownloadUrl(appChannelBucket.getBucketType(), fileUploadConfig.getBucketName(), sourceFileKey + , fileUploadConfig.getChannelCode(), SIGN_URL_DOWNLOAD_EXPIRE_SECOND, byFileUuid.getFileName(), null, false); + //4 获取文件元信息(此时主要文件大小) + ManaGetObjectMetaResponse objectMeta = fileService.getObjectMeta(appChannelBucket.getBucketName(), sourceFileKey, downloadResponse.getSignUrl(), appChannelBucket.getChannelCode()); + //文件大小没有达到maxFileSize,则不用裁剪 + if (Objects.nonNull(dto.getMaxFileSize()) && !Objects.equals(dto.getMaxFileSize(), 0) && !Objects.equals(objectMeta.getSize(), 0)&& objectMeta.getSize() > dto.getMaxFileSize()) { + //5 重新获取下载文件url(支持:公有桶/私有桶) + downloadResponse = this.fileManager.fetchDownloadUrl(appChannelBucket.getBucketType(), fileUploadConfig.getBucketName(), sourceFileKey + , fileUploadConfig.getChannelCode(), SIGN_URL_DOWNLOAD_EXPIRE_SECOND, byFileUuid.getFileName(), dto.getStyle(), false); + } + + //6 上传至指定目录 + this.fileManager.uploadByUrl(fileUploadConfig.getBucketName(), targetFileKey, byFileUuid.getFileName(), downloadResponse.getSignUrl(), fileUploadConfig.getChannelCode()); + return targetFileKey; + } +} 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 c4b11f9..d10c3da 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 @@ -55,6 +55,7 @@ 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.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.Pair; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import lombok.extern.slf4j.Slf4j; @@ -302,7 +303,8 @@ public class FileServiceImpl implements FileService { return setFileDownloadResponse(file, fileStream); } - private FileUploadConfig getFileUploadConfig(String appCode, String bizScene, Integer channelType) { + @Override + public FileUploadConfig getFileUploadConfig(String appCode, String bizScene, Integer channelType) { // 检查appCode checkAppCode(appCode); @@ -319,6 +321,25 @@ public class FileServiceImpl implements FileService { return fileUploadConfig; } + @Override + public Pair channelBucketAndConfig(String appCode, String bizScene, Integer channelType) { + // 检查appCode + checkAppCode(appCode); + + // 通过appcode获取文件渠道桶信息 + AppChannelBucket appChannelBucket = appChannelBucketManager.getByAppCode(appCode, channelType); + + // 通过渠道桶编码获取到具体文件业务场景 + FileBusinessScene scene = fileBusinessSceneManager + .getByBucketNoAndScene(appChannelBucket.getAppChannelBucketNo(), bizScene); + + // 通过渠道码和桶名称获取获取指定上传配置 + FileUploadConfig fileUploadConfig = fileUploadConfigManager + .getByUploadConfig(scene.getAppChannelBucketNo(), scene.getDirectory()); + return Pair.of(appChannelBucket, fileUploadConfig); + } + + private File completeFile(FileUploadConfig fileUploadConfig, String fileName, String tgtFileKey, String uploadId, List partETags) { // 文件合并 String fileUrl = fileManager.multipartUploadComplete(fileUploadConfig.getBucketName(), tgtFileKey, uploadId, partETags); @@ -896,7 +917,7 @@ public class FileServiceImpl implements FileService { case PUBLIC_BUCKET://公有桶 - 永久链接,例如 http://xxx.png String url = this.fileManager.fetchDownloadUrl(item.getBucketName(), tgtFileKey, item.getChannelCode()); return SignUrlDownloadResponse.builder() - .signUrl(this.buildPublicXImageProcess(url, style)) + .signUrl(this.fileManager.buildPublicXImageProcess(url, style)) .fileKey(item.getFileUuid()) .fileName(item.getFileName()) .build(); @@ -927,26 +948,12 @@ public class FileServiceImpl implements FileService { return Lists.newArrayList(); } return httpUrlList.stream().map(item -> SignUrlDownloadResponse.builder() - .signUrl(this.buildPublicXImageProcess(item, dto.getStyle())) + .signUrl(this.fileManager.buildPublicXImageProcess(item, dto.getStyle())) .fileKey(item) .build()).collect(Collectors.toList()); } - /** - * 构建公开Style - */ - private String buildPublicXImageProcess(String url, String style) { - if (StringUtils.isBlank(style)) { - return url; - } - if (url.toLowerCase().contains(UrlUtil.ALIYUN) && !url.toLowerCase().contains(UrlUtil.X_OSS_PROCESS)) { - return url + UrlUtil.X_OSS_PROCESS_APPEND + style; - } - if (url.toLowerCase().contains(UrlUtil.HUAWEICLOUD) && !url.toLowerCase().contains(UrlUtil.X_IMAGE_PROCESS)) { - return url + UrlUtil.X_IMAGE_PROCESS_APPEND + style; - } - return url; - } + /** * 构建http链接(非fileKey入参)返回对象 From 3797afcd06ff05dda85b2e1267110fdeb53dd246 Mon Sep 17 00:00:00 2001 From: xudawei Date: Mon, 1 Jul 2024 21:18:31 +0800 Subject: [PATCH 2/3] =?UTF-8?q?[REQ-2259]=E4=B8=8A=E4=BC=A0=E8=87=B3?= =?UTF-8?q?=E6=8C=87=E5=AE=9A=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/cn/axzo/oss/manager/impl/FileManagerImpl.java | 2 ++ .../cn/axzo/oss/service/impl/FileCopyToDictServiceImpl.java | 2 ++ 2 files changed, 4 insertions(+) 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 7cab2bb..30859b5 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 @@ -16,6 +16,7 @@ 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.ObjectMetadata; import com.obs.services.model.TemporarySignatureResponse; @@ -286,6 +287,7 @@ public class FileManagerImpl implements FileManager { */ public String uploadByUrl(String bulkName, String keyPath, String fileName, String url, String channelCode) { + log.info("uploadByUrl,bulkName:{},keyPath:{},fileName:{},url:{},channelCode:{}", bulkName, keyPath, fileName, url, channelCode); try { switch (ChannelTypeEnum.getChannelTypeByChannelCode(channelCode)) { case OSS: diff --git a/oss-service/src/main/java/cn/axzo/oss/service/impl/FileCopyToDictServiceImpl.java b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileCopyToDictServiceImpl.java index 099c9a0..574f5ab 100644 --- a/oss-service/src/main/java/cn/axzo/oss/service/impl/FileCopyToDictServiceImpl.java +++ b/oss-service/src/main/java/cn/axzo/oss/service/impl/FileCopyToDictServiceImpl.java @@ -12,6 +12,7 @@ import cn.axzo.oss.manager.api.dto.response.SignUrlDownloadResponse; import cn.axzo.oss.service.api.FileCopyToDictService; import cn.axzo.oss.service.api.FileService; import cn.hutool.core.lang.Pair; +import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -44,6 +45,7 @@ public class FileCopyToDictServiceImpl implements FileCopyToDictService { @Override public String copyToDict(ServerFileCopyToDictDto dto) { + log.info("copyToDict-start,dto:{}", JSON.toJSONString(dto)); //1 获取桶基础与配置 Pair pair = this.fileService.channelBucketAndConfig(dto.getAppCode(), dto.getBizScene(), dto.getChannelCode()); From c0ca54970d7e62ef1b5cd7f99d8f861e6338c6cb Mon Sep 17 00:00:00 2001 From: xudawei Date: Wed, 10 Jul 2024 10:23:05 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=8E=88=E6=9D=83?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD-uploadByUrl=E5=BC=82=E5=B8=B8=E5=A0=86?= =?UTF-8?q?=E6=A0=88=E6=89=93=E5=8D=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../oss/integration/s3/impl/AliOssServiceImpl.java | 10 +++++----- .../integration/s3/impl/HuaWeiCloudServiceImpl.java | 6 +++--- 2 files changed, 8 insertions(+), 8 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 9c9e85d..98ac328 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 @@ -82,10 +82,10 @@ public class AliOssServiceImpl implements AliOssService { client.putObject(bucketName, tgtFileKey, srcStream, metadata); } } catch (OSSException e) { - LogUtil.error("uploadByStream OSSException", e); + LogUtil.error("uploadByStream OSSException,bucketName:{},tgtFileKey:{},fileName:{},appCode:{}",bucketName,tgtFileKey, fileName,appCode, e); return ""; } catch (Exception e) { - LogUtil.error("uploadByStream ClientException", e); + LogUtil.error("uploadByStream ClientException,bucketName:{},tgtFileKey:{},fileName:{},appCode:{}",bucketName,tgtFileKey, fileName,appCode, e); return ""; } @@ -305,7 +305,7 @@ public class AliOssServiceImpl implements AliOssService { log.info("aliyun downloadSignUrl result, bucketName:{}, key:{}, url:{}", bucketName, key, JsonUtil.obj2Str(url)); return url.toString(); } catch (Exception e) { - log.warn("aliyun downloadSignUrl result, bucketName:{}, key:{}", bucketName, key); + log.warn("aliyun downloadSignUrl result, bucketName:{}, key:{}", bucketName, key,e); throw new BizException(CodeEnum.DOWNLOAD_SIGN_URL_FAIL); } } @@ -408,10 +408,10 @@ public class AliOssServiceImpl implements AliOssService { metadata.setContentEncoding("utf-8"); client.putObject(bucketName, tgtFileKey, srcStream, metadata); } catch (OSSException e) { - LogUtil.error("uploadByStream OSSException", e); + LogUtil.error("uploadByStream OSSException, bucketName:{}, tgtFileKey:{}, fileName:{}, url:{}",bucketName, tgtFileKey, fileName, url,e); return ""; } catch (Exception e) { - LogUtil.error("uploadByStream ClientException", e); + LogUtil.error("uploadByStream ClientException, bucketName:{}, tgtFileKey:{}, fileName:{}, url:{}",bucketName, tgtFileKey, fileName, url, e); return ""; } 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 acc8d97..747a0df 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 @@ -342,7 +342,7 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService { log.info("response = {}", JSONUtil.toJsonStr(response)); return response; } catch (Exception exception) { - log.warn("获取临时url发生异常, exception = {}", exception.getMessage()); + log.warn("获取临时url发生异常, exception = {}", exception.getMessage(), exception); log.warn("异常信息:"); exception.printStackTrace(); return null; @@ -373,7 +373,7 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService { log.info("huawei cloud downloadSignUrl result, bucketName:{}, key:{}, request:{}", bucketName, key, JsonUtil.obj2Str(response)); return response.getSignedUrl(); } catch (Exception e) { - log.info("huawei cloud downloadSignUrl exception, bucketName:{}, key:{}", bucketName, key); + log.info("huawei cloud downloadSignUrl exception, bucketName:{}, key:{}", bucketName, key,e); throw new BizException(CodeEnum.DOWNLOAD_SIGN_URL_FAIL); } @@ -449,7 +449,7 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService { PutObjectResult putObjectResult = obsClient.putObject(bucketName, key, srcStream, metadata); return putObjectResult.getObjectUrl(); } catch (Exception e) { - log.error("通过url上传 exception,bucketName:{}, key:{}, fileName:{},url:{}", bucketName, key, fileName, url); + log.error("通过url上传 exception,bucketName:{}, key:{}, fileName:{},url:{}", bucketName, key, fileName, url, e); return ""; }