Merge branch 'feature/REQ-2599' into 'master'

Feature/req 2599

See merge request universal/infrastructure/backend/oss!153
This commit is contained in:
徐大伟 2024-07-10 09:45:16 +00:00
commit fc4f913f73
14 changed files with 351 additions and 28 deletions

View File

@ -21,6 +21,8 @@ import cn.axzo.oss.http.model.FindFileUrlRequest;
import cn.axzo.oss.http.model.FindFileUrlResponse; import cn.axzo.oss.http.model.FindFileUrlResponse;
import cn.axzo.oss.http.model.GetObjectMetaRequest; import cn.axzo.oss.http.model.GetObjectMetaRequest;
import cn.axzo.oss.http.model.GetObjectMetaResponse; 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.ServerFileDeleteRequest;
import cn.axzo.oss.http.model.ServerFileUploadByUrlRequest; import cn.axzo.oss.http.model.ServerFileUploadByUrlRequest;
import cn.axzo.oss.http.model.ServerFileUploadRequest; 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.http.model.ServerFileUploadV2Request;
import cn.axzo.oss.manager.api.dto.request.FindFileKeyDto; 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.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.ServerFileDeleteDto;
import cn.axzo.oss.manager.api.dto.request.ServerFileUploadByUrlDto; 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.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.request.SignUrlUploadDto;
import cn.axzo.oss.manager.api.dto.response.ManaGetObjectMetaResponse; import cn.axzo.oss.manager.api.dto.response.ManaGetObjectMetaResponse;
import cn.axzo.oss.service.api.FileByUrlService; import cn.axzo.oss.service.api.FileByUrlService;
import cn.axzo.oss.service.api.FileCopyToDictService;
import cn.axzo.oss.service.api.FileService; import cn.axzo.oss.service.api.FileService;
import cn.azxo.framework.common.model.CommonResponse; import cn.azxo.framework.common.model.CommonResponse;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
@ -68,6 +72,9 @@ public class ServerFileController implements ServerFileServiceApi {
@Autowired @Autowired
private FileByUrlService fileByUrlService; private FileByUrlService fileByUrlService;
@Autowired
private FileCopyToDictService fileCopyToDictService;
@Autowired @Autowired
private HttpServletRequest httpServletRequest; private HttpServletRequest httpServletRequest;
@ -214,4 +221,15 @@ public class ServerFileController implements ServerFileServiceApi {
ContextInfo.LiteSaasContext liteSaasContext = JSONUtil.toBean(contextInfoLiteJsonStr, ContextInfo.LiteSaasContext.class); 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)); 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<ServerFileCopyToDictResponse> 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());
}
} }

View File

@ -13,6 +13,8 @@ import cn.axzo.oss.http.model.FindFileUrlRequest;
import cn.axzo.oss.http.model.FindFileUrlResponse; import cn.axzo.oss.http.model.FindFileUrlResponse;
import cn.axzo.oss.http.model.GetObjectMetaRequest; import cn.axzo.oss.http.model.GetObjectMetaRequest;
import cn.axzo.oss.http.model.GetObjectMetaResponse; 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.ServerFileDeleteRequest;
import cn.axzo.oss.http.model.ServerFileUploadByUrlRequest; import cn.axzo.oss.http.model.ServerFileUploadByUrlRequest;
import cn.axzo.oss.http.model.ServerFileUploadRequest; import cn.axzo.oss.http.model.ServerFileUploadRequest;
@ -107,4 +109,12 @@ public interface ServerFileServiceApi {
@RequestMapping(value = "/api/v1/server/uploadByUrl", method = RequestMethod.POST) @RequestMapping(value = "/api/v1/server/uploadByUrl", method = RequestMethod.POST)
CommonResponse<ServerFileUploadResponse> uploadByUrl(ServerFileUploadByUrlRequest request); CommonResponse<ServerFileUploadResponse> uploadByUrl(ServerFileUploadByUrlRequest request);
/**
* 通过URL上传文件
* @param request
* @return
*/
@RequestMapping(value = "/api/server/copyToDict", method = RequestMethod.POST)
CommonResponse<ServerFileCopyToDictResponse> copyToDict(ServerFileCopyToDictRequest request);
} }

View File

@ -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;
}

View File

@ -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;
}

View File

@ -51,4 +51,9 @@ public interface HuaWeiCloudService {
* 元数据 * 元数据
*/ */
ObjectMetadata getObjectMeta(String bucketName, String key, String url); ObjectMetadata getObjectMeta(String bucketName, String key, String url);
/**
* 元数据
*/
boolean copyToDict(String bucketName, String key, String targetBucketName, String targetKey);
} }

View File

@ -82,10 +82,10 @@ public class AliOssServiceImpl implements AliOssService {
client.putObject(bucketName, tgtFileKey, srcStream, metadata); client.putObject(bucketName, tgtFileKey, srcStream, metadata);
} }
} catch (OSSException e) { } catch (OSSException e) {
LogUtil.error("uploadByStream OSSException", e); LogUtil.error("uploadByStream OSSException,bucketName:{},tgtFileKey:{},fileName:{},appCode:{}",bucketName,tgtFileKey, fileName,appCode, e);
return ""; return "";
} catch (Exception e) { } catch (Exception e) {
LogUtil.error("uploadByStream ClientException", e); LogUtil.error("uploadByStream ClientException,bucketName:{},tgtFileKey:{},fileName:{},appCode:{}",bucketName,tgtFileKey, fileName,appCode, e);
return ""; return "";
} }
@ -305,7 +305,7 @@ public class AliOssServiceImpl implements AliOssService {
log.info("aliyun downloadSignUrl result, bucketName:{}, key:{}, url:{}", bucketName, key, JsonUtil.obj2Str(url)); log.info("aliyun downloadSignUrl result, bucketName:{}, key:{}, url:{}", bucketName, key, JsonUtil.obj2Str(url));
return url.toString(); return url.toString();
} catch (Exception e) { } 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); throw new BizException(CodeEnum.DOWNLOAD_SIGN_URL_FAIL);
} }
} }
@ -407,10 +407,10 @@ public class AliOssServiceImpl implements AliOssService {
metadata.setContentEncoding("utf-8"); metadata.setContentEncoding("utf-8");
client.putObject(bucketName, tgtFileKey, srcStream, metadata); client.putObject(bucketName, tgtFileKey, srcStream, metadata);
} catch (OSSException e) { } catch (OSSException e) {
LogUtil.error("uploadByStream OSSException", e); LogUtil.error("uploadByStream OSSException, bucketName:{}, tgtFileKey:{}, fileName:{}, url:{}",bucketName, tgtFileKey, fileName, url,e);
return ""; return "";
} catch (Exception e) { } catch (Exception e) {
LogUtil.error("uploadByStream ClientException", e); LogUtil.error("uploadByStream ClientException, bucketName:{}, tgtFileKey:{}, fileName:{}, url:{}",bucketName, tgtFileKey, fileName, url, e);
return ""; return "";
} }

View File

@ -15,6 +15,7 @@ import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException; import com.obs.services.exception.ObsException;
import com.obs.services.model.CompleteMultipartUploadRequest; import com.obs.services.model.CompleteMultipartUploadRequest;
import com.obs.services.model.CompleteMultipartUploadResult; import com.obs.services.model.CompleteMultipartUploadResult;
import com.obs.services.model.CopyObjectRequest;
import com.obs.services.model.DeleteObjectResult; import com.obs.services.model.DeleteObjectResult;
import com.obs.services.model.DownloadFileRequest; import com.obs.services.model.DownloadFileRequest;
import com.obs.services.model.DownloadFileResult; import com.obs.services.model.DownloadFileResult;
@ -341,7 +342,7 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService {
log.info("response = {}", JSONUtil.toJsonStr(response)); log.info("response = {}", JSONUtil.toJsonStr(response));
return response; return response;
} catch (Exception exception) { } catch (Exception exception) {
log.warn("获取临时url发生异常, exception = {}", exception.getMessage()); log.warn("获取临时url发生异常, exception = {}", exception.getMessage(), exception);
log.warn("异常信息:"); log.warn("异常信息:");
exception.printStackTrace(); exception.printStackTrace();
return null; return null;
@ -372,7 +373,7 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService {
log.info("huawei cloud downloadSignUrl result, bucketName:{}, key:{}, request:{}", bucketName, key, JsonUtil.obj2Str(response)); log.info("huawei cloud downloadSignUrl result, bucketName:{}, key:{}, request:{}", bucketName, key, JsonUtil.obj2Str(response));
return response.getSignedUrl(); return response.getSignedUrl();
} catch (Exception e) { } 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); throw new BizException(CodeEnum.DOWNLOAD_SIGN_URL_FAIL);
} }
@ -447,7 +448,7 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService {
PutObjectResult putObjectResult = obsClient.putObject(bucketName, key, srcStream, metadata); PutObjectResult putObjectResult = obsClient.putObject(bucketName, key, srcStream, metadata);
return putObjectResult.getObjectUrl(); return putObjectResult.getObjectUrl();
} catch (Exception e) { } 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 ""; return "";
} }
@ -467,7 +468,28 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService {
return new ObjectMetadata(); return new ObjectMetadata();
} catch (Exception e) { } catch (Exception e) {
log.warn("huaweicloud-getObjectMeta-exception, bucketName:{}, key:{}", bucketName, key, 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;
} }
} }

View File

@ -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.PartETag;
import cn.axzo.oss.manager.api.dto.request.MultipartUploadDto; 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.ManaGetObjectMetaResponse;
import cn.axzo.oss.manager.api.dto.response.SignUrlDownloadResponse;
import cn.axzo.oss.manager.api.vo.SignUrlUploadVo; import cn.axzo.oss.manager.api.vo.SignUrlUploadVo;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -87,4 +88,11 @@ public interface FileManager {
*/ */
String uploadByUrl(String bulkName, String keyPath, String fileName, String url, String uploadByUrl(String bulkName, String keyPath, String fileName, String url,
String channelCode); 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);
} }

View File

@ -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;
}

View File

@ -14,7 +14,9 @@ import cn.axzo.oss.manager.api.FileManager;
import cn.axzo.oss.manager.api.dto.PartETag; import cn.axzo.oss.manager.api.dto.PartETag;
import cn.axzo.oss.manager.api.dto.request.MultipartUploadDto; 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.ManaGetObjectMetaResponse;
import cn.axzo.oss.manager.api.dto.response.SignUrlDownloadResponse;
import cn.axzo.oss.manager.api.vo.SignUrlUploadVo; import cn.axzo.oss.manager.api.vo.SignUrlUploadVo;
import com.alibaba.fastjson.JSON;
import com.aliyun.oss.model.SimplifiedObjectMeta; import com.aliyun.oss.model.SimplifiedObjectMeta;
import com.obs.services.model.ObjectMetadata; import com.obs.services.model.ObjectMetadata;
import com.obs.services.model.TemporarySignatureResponse; import com.obs.services.model.TemporarySignatureResponse;
@ -22,6 +24,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -29,6 +32,7 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Objects;
/** /**
* @Author admin * @Author admin
@ -49,6 +53,9 @@ public class FileManagerImpl implements FileManager {
private final String HUAWEI_CLOUD_SIGNURL_UPLOAD_HOST_KEY = "Host"; private final String HUAWEI_CLOUD_SIGNURL_UPLOAD_HOST_KEY = "Host";
private final String HUAWEI_CLOUD_SIGNURL_UPLOAD_CONTENT_TYPE_KEY = "Content-Type"; 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;
/** /**
* 删除文件 * 删除文件
* *
@ -282,6 +289,7 @@ public class FileManagerImpl implements FileManager {
*/ */
public String uploadByUrl(String bulkName, String keyPath, String fileName, String url, public String uploadByUrl(String bulkName, String keyPath, String fileName, String url,
String channelCode) { String channelCode) {
log.info("uploadByUrl,bulkName:{},keyPath:{},fileName:{},url:{},channelCode:{}", bulkName, keyPath, fileName, url, channelCode);
try { try {
switch (ChannelTypeEnum.getChannelTypeByChannelCode(channelCode)) { switch (ChannelTypeEnum.getChannelTypeByChannelCode(channelCode)) {
case OSS: case OSS:
@ -292,10 +300,50 @@ public class FileManagerImpl implements FileManager {
BizException.error(CodeEnum.CHANNEL_TYPE_NOT_EXIST); BizException.error(CodeEnum.CHANNEL_TYPE_NOT_EXIST);
} }
} catch (Exception e) { } 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); , bulkName, keyPath, fileName, url, channelCode, e);
return StringUtils.EMPTY;
} }
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;
}
} }

View File

@ -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);
}

View File

@ -1,6 +1,8 @@
package cn.axzo.oss.service.api; package cn.axzo.oss.service.api;
import cn.axzo.framework.auth.domain.ContextInfo; 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.DeleteFileDto;
import cn.axzo.oss.manager.api.dto.request.FindFileKeyDto; 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.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.ServerFileUploadResponse;
import cn.axzo.oss.manager.api.dto.response.SignUrlDownloadResponse; 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.SignUrlUploadResponse;
import cn.hutool.core.lang.Pair;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.util.List; import java.util.List;
@ -92,4 +95,14 @@ public interface FileService {
* 元数据 * 元数据
*/ */
ManaGetObjectMetaResponse getObjectMeta(String bucketName, String key, String url,String channelCode); ManaGetObjectMetaResponse getObjectMeta(String bucketName, String key, String url,String channelCode);
/**
* 获取桶配置
*/
FileUploadConfig getFileUploadConfig(String appCode, String bizScene, Integer channelType);
/**
* 获取桶基础与配置
*/
Pair<AppChannelBucket, FileUploadConfig> channelBucketAndConfig(String appCode, String bizScene, Integer channelType);
} }

View File

@ -0,0 +1,75 @@
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 com.alibaba.fastjson.JSON;
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) {
log.info("copyToDict-start,dto:{}", JSON.toJSONString(dto));
//1 获取桶基础与配置
Pair<AppChannelBucket, FileUploadConfig> 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;
}
}

View File

@ -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.manager.api.vo.SignUrlUploadVo;
import cn.axzo.oss.service.api.FileService; import cn.axzo.oss.service.api.FileService;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Pair;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -302,7 +303,8 @@ public class FileServiceImpl implements FileService {
return setFileDownloadResponse(file, fileStream); return setFileDownloadResponse(file, fileStream);
} }
private FileUploadConfig getFileUploadConfig(String appCode, String bizScene, Integer channelType) { @Override
public FileUploadConfig getFileUploadConfig(String appCode, String bizScene, Integer channelType) {
// 检查appCode // 检查appCode
checkAppCode(appCode); checkAppCode(appCode);
@ -319,6 +321,25 @@ public class FileServiceImpl implements FileService {
return fileUploadConfig; return fileUploadConfig;
} }
@Override
public Pair<AppChannelBucket, FileUploadConfig> 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<PartETag> partETags) { private File completeFile(FileUploadConfig fileUploadConfig, String fileName, String tgtFileKey, String uploadId, List<PartETag> partETags) {
// 文件合并 // 文件合并
String fileUrl = fileManager.multipartUploadComplete(fileUploadConfig.getBucketName(), tgtFileKey, uploadId, 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 case PUBLIC_BUCKET://公有桶 - 永久链接例如 http://xxx.png
String url = this.fileManager.fetchDownloadUrl(item.getBucketName(), tgtFileKey, item.getChannelCode()); String url = this.fileManager.fetchDownloadUrl(item.getBucketName(), tgtFileKey, item.getChannelCode());
return SignUrlDownloadResponse.builder() return SignUrlDownloadResponse.builder()
.signUrl(this.buildPublicXImageProcess(url, style)) .signUrl(this.fileManager.buildPublicXImageProcess(url, style))
.fileKey(item.getFileUuid()) .fileKey(item.getFileUuid())
.fileName(item.getFileName()) .fileName(item.getFileName())
.build(); .build();
@ -927,26 +948,12 @@ public class FileServiceImpl implements FileService {
return Lists.newArrayList(); return Lists.newArrayList();
} }
return httpUrlList.stream().map(item -> SignUrlDownloadResponse.builder() return httpUrlList.stream().map(item -> SignUrlDownloadResponse.builder()
.signUrl(this.buildPublicXImageProcess(item, dto.getStyle())) .signUrl(this.fileManager.buildPublicXImageProcess(item, dto.getStyle()))
.fileKey(item) .fileKey(item)
.build()).collect(Collectors.toList()); .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入参)返回对象 * 构建http链接(非fileKey入参)返回对象