Merge branch 'master' into feature/REQ-2673

# Conflicts:
#	oss-client/src/main/java/cn/axzo/oss/client/controller/ServerFileController.java
#	oss-http-api/src/main/java/cn/axzo/oss/http/api/ServerFileServiceApi.java
#	oss-service-api/src/main/java/cn/axzo/oss/service/api/FileService.java
This commit is contained in:
xudawei 2024-10-09 16:13:18 +08:00
commit b49bc7eec3
17 changed files with 381 additions and 42 deletions

View File

@ -23,6 +23,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;
@ -30,6 +32,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.GetObjectMetaDto;
import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto;
import cn.axzo.oss.manager.api.dto.request.ServerFileUploadByUrlDto;
@ -38,6 +41,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;
@ -45,6 +49,8 @@ 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;
@ -69,6 +75,9 @@ public class ServerFileController implements ServerFileServiceApi {
@Autowired
private FileByUrlService fileByUrlService;
@Autowired
private FileCopyToDictService fileCopyToDictService;
@Autowired
private HttpServletRequest httpServletRequest;
@ -201,6 +210,17 @@ public class ServerFileController implements ServerFileServiceApi {
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());
}
/**
* 临时授权上传-生成临时url-公有桶
*/

View File

@ -75,7 +75,7 @@ public class ControllerExceptionHandler {
@ExceptionHandler(value = MethodArgumentNotValidException.class)
public CommonResponse handleArgumentValidException(MethodArgumentNotValidException e){
log.warn("[oss] ControllerExceptionHandler.handleArgumentValidException Exception", e.getMessage());
log.warn("[oss] ControllerExceptionHandler.handleArgumentValidException Exception", e);
BindingResult bindingResult = e.getBindingResult();
StringBuilder errorMsg = new StringBuilder();
for (FieldError fieldError : bindingResult.getFieldErrors()) {

View File

@ -16,3 +16,5 @@ spring:
logging:
level:
com.alibaba.nacos.client.config.impl: WARN
server:
shutdown: graceful

View File

@ -15,6 +15,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;
@ -125,4 +127,12 @@ public interface ServerFileServiceApi {
@RequestMapping(value = "/api/v1/server/fetchUploadToPublishSignUrl", method = RequestMethod.POST)
CommonResponse<FetchUploadSignUrlToPublishResponse> fetchUploadSignUrlToPublish(@Valid @RequestBody FetchUploadSignUrlToPublishRequest request);
/**
* 通过URL上传文件
* @param request
* @return
*/
@RequestMapping(value = "/api/server/copyToDict", method = RequestMethod.POST)
CommonResponse<ServerFileCopyToDictResponse> copyToDict(ServerFileCopyToDictRequest request);
}

View File

@ -0,0 +1,38 @@
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;
@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

@ -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);
/**
* 元数据
*/
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);
}
} 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);
}
}
@ -325,7 +325,7 @@ public class AliOssServiceImpl implements AliOssService {
// 设置内容被下载时的名称
metadata.put("Content-Encoding", "utf-8");
} catch (UnsupportedEncodingException uee) {
log.error("uploadSignUrl metadata build exception", uee);
log.warn("uploadSignUrl metadata build exception", uee);
}
// 生成签名URL
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, key, HttpMethod.PUT);
@ -358,7 +358,7 @@ public class AliOssServiceImpl implements AliOssService {
log.info("aliyun deleteFile params, bucketName:{}, key:{}", bucketName, key);
aliOssClient.getClient().deleteObject(bucketName, key);
} catch (Exception e) {
log.error("aliyun deleteFile exception, bucketName:{}, key:{}", bucketName, key, e);
log.warn("aliyun deleteFile exception, bucketName:{}, key:{}", bucketName, key, e);
throw new BizException(CodeEnum.DELETE_FILE_FAIL);
}
}
@ -399,8 +399,7 @@ public class AliOssServiceImpl implements AliOssService {
@Override
public String uploadByUrl(String bucketName, String tgtFileKey, String fileName, String url) {
OSS client = aliOssClient.getClient();
try {
InputStream srcStream = new URL(url).openStream();
try(InputStream srcStream = new URL(url).openStream()) {
// 创建上传文件的元信息通过文件云信息设置HTTP Header
ObjectMetadata metadata = new ObjectMetadata();
// 设置内容被下载时的名称
@ -408,10 +407,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 "";
}

View File

@ -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;
@ -341,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;
@ -372,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);
}
@ -399,7 +400,7 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService {
log.info("huawei cloud uploadSignUrl result, bucketName:{}, key:{}, request:{}", bucketName, key, JsonUtil.obj2Str(response));
return response;
} catch (Exception e) {
log.error("huawei cloud uploadSignUrl result, bucketName:{}, key:{}", e);
log.warn("huawei cloud uploadSignUrl result, bucketName:{}, key:{}", e);
throw new BizException(CodeEnum.UPLOAD_SIGN_URL_FAIL);
}
@ -415,7 +416,7 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService {
DeleteObjectResult deleteObjectResult = huaWeiCloudObsClient.getClient().deleteObject(bucketName, key);
log.info("huawei cloud deleteFile result, bucketName:{}, key:{},deleteObjectResult:{}", bucketName, key, JsonUtil.obj2Str(deleteObjectResult));
} catch (Exception e) {
log.error("huawei cloud deleteFile exception, bucketName:{}, key:{},deleteObjectResult:{}", bucketName, key, e);
log.warn("huawei cloud deleteFile exception, bucketName:{}, key:{},deleteObjectResult:{}", bucketName, key, e);
throw new BizException(CodeEnum.DELETE_FILE_FAIL);
}
}
@ -438,8 +439,7 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService {
@Override
public String uploadFileByUrl(String bucketName, String key, String fileName, String url) {
ObsClient obsClient = huaWeiCloudObsClient.getClient();
try {
InputStream srcStream = new URL(url).openStream();
try (InputStream srcStream = new URL(url).openStream()) {
// 创建上传文件的元信息通过文件云信息设置HTTP Header
ObjectMetadata metadata = new ObjectMetadata();
// 设置内容被下载时的名称
@ -448,7 +448,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.warn("通过url上传 exception,bucketName:{}, key:{}, fileName:{},url:{}", bucketName, key, fileName, url, e);
return "";
}
@ -468,7 +468,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;
}
}

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

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.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;
@ -22,6 +24,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 +32,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 +53,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;
/**
* 删除文件
*
@ -232,8 +239,10 @@ public class FileManagerImpl implements FileManager {
switch (typeEnum) {
case OBS:// 华为云
huaWeiCloudService.deleteFile(bucketName, key);
break;
case OSS:// 阿里云
aliOssService.deleteFile(bucketName, key);
break;
default:
BizException.error(CodeEnum.CHANNEL_TYPE_NOT_EXIST);
}
@ -280,6 +289,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:
@ -290,10 +300,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;
}
}

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;
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;
@ -24,6 +26,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.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;
@ -95,6 +98,16 @@ public interface FileService {
*/
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,91 @@
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.request.SignUrlDownloadDto;
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 com.google.common.collect.Lists;
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.List;
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);
String downloadSignUrl = this.fetchSignUrlByFileKey(dto.getFileKey(), null);
//4 获取文件元信息(此时主要文件大小)
ManaGetObjectMetaResponse objectMeta = fileService.getObjectMeta(byFileUuid.getBucketName(), sourceFileKey, downloadSignUrl, byFileUuid.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);
downloadSignUrl = this.fetchSignUrlByFileKey(dto.getFileKey(), dto.getStyle());
}
//6 上传至指定目录
this.fileManager.uploadByUrl(fileUploadConfig.getBucketName(), targetFileKey, byFileUuid.getFileName(), downloadSignUrl, fileUploadConfig.getChannelCode());
log.info("copyToDict-end,targetFileKey:{}", targetFileKey);
return targetFileKey;
}
private String fetchSignUrlByFileKey(String fileKey, String style) {
SignUrlDownloadDto signUrlDownloadDto = new SignUrlDownloadDto();
signUrlDownloadDto.setFileKeys(Lists.newArrayList(fileKey));
signUrlDownloadDto.setStyle(style);
List<SignUrlDownloadResponse> responseList = this.fileService.signUrlDownload(signUrlDownloadDto);
return responseList.get(0).getSignUrl();
}
}

View File

@ -61,6 +61,7 @@ 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;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
@ -309,7 +310,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);
@ -326,6 +328,25 @@ public class FileServiceImpl implements FileService {
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) {
// 文件合并
String fileUrl = fileManager.multipartUploadComplete(fileUploadConfig.getBucketName(), tgtFileKey, uploadId, partETags);
@ -931,7 +952,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();
@ -992,26 +1013,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入参)返回对象

View File

@ -40,11 +40,8 @@ public class FileServiceTest extends SpringTestBase {
File file = new File("/Users/admin/Downloads/表扬人员名称.xlsx");
FileInputStream fileInputStream = null;
byte[] bytes = new byte[(int) file.length()];
try {
fileInputStream = new FileInputStream(file);
try (FileInputStream fileInputStream = new FileInputStream(file)) {
fileInputStream.read(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();