Merge branch 'master' into feature/REQ-2322

This commit is contained in:
xudawei 2024-06-18 18:44:15 +08:00
commit f8a8a6ae58
23 changed files with 774 additions and 45 deletions

View File

@ -13,7 +13,7 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
@Slf4j
@MapperScan(basePackages = {"cn.axzo.oss.dal.mapper", "cn.axzo.oss.client.icon.mapper"})
@EnableFeignClients(basePackages = {"cn.axzo.log.platform.client"})
@SpringBootApplication(scanBasePackages = {"cn.axzo.oss"})
@SpringBootApplication(scanBasePackages = {"cn.axzo.oss","com.axzo.framework"})
public class Bootstrap {
public static void main(String[] args) {
log.info("axzo oss begin starting...");

View File

@ -22,16 +22,19 @@ 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.ServerFileDeleteRequest;
import cn.axzo.oss.http.model.ServerFileUploadByUrlRequest;
import cn.axzo.oss.http.model.ServerFileUploadRequest;
import cn.axzo.oss.http.model.ServerFileUploadResponse;
import cn.axzo.oss.http.model.ServerFileUploadV2Request;
import cn.axzo.oss.manager.api.dto.request.FindFileKeyDto;
import cn.axzo.oss.manager.api.dto.request.FindFileUrlDto;
import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto;
import cn.axzo.oss.manager.api.dto.request.ServerFileUploadByUrlDto;
import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto;
import cn.axzo.oss.manager.api.dto.request.SignUrlDownloadDto;
import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto;
import cn.axzo.oss.manager.api.dto.response.ManaGetObjectMetaResponse;
import cn.axzo.oss.service.api.FileByUrlService;
import cn.axzo.oss.service.api.FileService;
import cn.azxo.framework.common.model.CommonResponse;
import cn.hutool.json.JSONUtil;
@ -62,6 +65,9 @@ public class ServerFileController implements ServerFileServiceApi {
@Autowired
private FileService fileService;
@Autowired
private FileByUrlService fileByUrlService;
@Autowired
private HttpServletRequest httpServletRequest;
@ -152,15 +158,30 @@ public class ServerFileController implements ServerFileServiceApi {
throw new BizException(CodeEnum.URL_BUCKET_NAME_KEY_ALL_EMPTY);
}
String bucketName = UrlUtil.fetchBucketName(request.getBucketName(), request.getUrl());
String bucketKey = UrlUtil.fetchBucketKey(request.getKey(), request.getUrl());
ManaGetObjectMetaResponse response = this.fileService.getObjectMeta(bucketName
, bucketKey, request.getUrl()
, ChannelTypeEnum.OSS.getChannelCode());
, this.swtchChannelCode(request.getUrl()));
return CommonResponse.success(BeanConverter.convert(response, GetObjectMetaResponse.class));
}
/**
* 决定渠道
*/
private String swtchChannelCode(String url) {
if (!StringUtils.hasText(url)) {
return "";
}
if (url.toLowerCase().contains("aliyun")) {
return ChannelTypeEnum.OSS.getChannelCode();
}
if (url.toLowerCase().contains("huaweicloud")) {
return ChannelTypeEnum.OBS.getChannelCode();
}
return url;
}
/**
* 文件元数据信息-批量
*/
@ -179,4 +200,18 @@ public class ServerFileController implements ServerFileServiceApi {
}
/**
* 通过URL上传文件
* @param request
* @return
*/
@Override
public CommonResponse<ServerFileUploadResponse> uploadByUrl(@Valid @RequestBody ServerFileUploadByUrlRequest request) {
ServerFileUploadByUrlDto dto = BeanConvertUtil.copyBean(request, ServerFileUploadByUrlDto.class);
// 获取feign调用请求头携带的用户信息
String contextInfoLiteJsonStr = httpServletRequest.getHeader("X-CONTEXT-INFO-LITE");
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));
}
}

View File

@ -26,6 +26,7 @@ public enum ChannelTypeEnum {
private final String channelCode;
private final static Map<String, ChannelTypeEnum> channelCodeMap = Arrays.stream(ChannelTypeEnum.values()).collect(Collectors.toMap(ChannelTypeEnum::getChannelCode, Function.identity()));
private final static Map<Integer, ChannelTypeEnum> codeMap = Arrays.stream(ChannelTypeEnum.values()).collect(Collectors.toMap(ChannelTypeEnum::getCode, Function.identity()));
ChannelTypeEnum(Integer code, String message, String channelCode) {
this.code = code;
@ -45,9 +46,16 @@ public enum ChannelTypeEnum {
}
/**
* 通过code获取枚举
* 通过channelCode获取枚举
*/
public static ChannelTypeEnum getChannelTypeByChannelCode(String channelCode) {
return channelCodeMap.get(channelCode);
}
/**
* 通过code获取枚举
*/
public static ChannelTypeEnum getChannelTypeByCode(Integer code) {
return codeMap.get(code);
}
}

View File

@ -10,8 +10,14 @@ import org.apache.commons.lang3.StringUtils;
public class UrlUtil {
public static String HTTP = "http:";
public static String HTTPS = "https:";
public static String HTTP_START = "http:";
public static String HTTPS_START = "https:";
public static String X_OSS_PROCESS = "x-oss-process";
public static String X_OSS_PROCESS_APPEND = "?x-oss-process=";
public static String X_IMAGE_PROCESS = "x-image-process";
public static String X_IMAGE_PROCESS_APPEND = "?x-image-process=";
public static String ALIYUN = "aliyun";
public static String HUAWEICLOUD = "huaweicloud";
/**
* http的url替换成https
@ -20,8 +26,8 @@ public class UrlUtil {
if (StringUtils.isBlank(str)) {
return str;
}
if (str.startsWith(HTTP)) {
return HTTPS + str.substring(str.indexOf(HTTP) + HTTP.length());
if (str.startsWith(HTTP_START)) {
return HTTPS_START + str.substring(str.indexOf(HTTP_START) + HTTP_START.length());
}
return str;
}
@ -47,11 +53,16 @@ public class UrlUtil {
if (org.springframework.util.StringUtils.hasText(bucketKey)) {
return bucketKey;
}
if (org.springframework.util.StringUtils.hasText(url)) {
if (url.contains(".") && url.contains("//")) {
String urlPathNoHttp = url.split("//")[1];
return urlPathNoHttp.substring(urlPathNoHttp.indexOf("/") + 1);
}
if (StringUtils.isBlank(url)) {
return url;
}
if (url.contains("?")) {
url = url.split("\\?")[0];
}
if (url.contains(".") && url.contains("//")) {
String urlPathNoHttp = url.split("//")[1];
return urlPathNoHttp.substring(urlPathNoHttp.indexOf("/") + 1);
}
return url;
}

View File

@ -14,6 +14,7 @@ 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.ServerFileDeleteRequest;
import cn.axzo.oss.http.model.ServerFileUploadByUrlRequest;
import cn.axzo.oss.http.model.ServerFileUploadRequest;
import cn.axzo.oss.http.model.ServerFileUploadResponse;
import cn.axzo.oss.http.model.ServerFileUploadV2Request;
@ -98,4 +99,12 @@ public interface ServerFileServiceApi {
@RequestMapping(value = "api/server/batchGetObjectMeta", method = RequestMethod.POST)
CommonResponse<BatchGetObjectMetaResponse> batchGetObjectMeta(BatchGetObjectMetaRequest request);
/**
* 通过URL上传文件
* @param request
* @return
*/
@RequestMapping(value = "/api/v1/server/uploadByUrl", method = RequestMethod.POST)
CommonResponse<ServerFileUploadResponse> uploadByUrl(ServerFileUploadByUrlRequest request);
}

View File

@ -32,4 +32,14 @@ public class ApiSignUrlDownloadRequest {
*/
private String bizScene;
/**
* 图片样式比如x-oss-process=image/auto-orient,1/resize,p_50/quality,q_30
*/
private String style;
/**
* 是否带上文件名称
*/
private Boolean hasFileName = true;
}

View File

@ -56,4 +56,9 @@ public class ApiSignUrlUploadRequest {
* 过期时间
*/
private Long expiration;
/**
* 是否带上文件名称
*/
private Boolean hasFileName = true;
}

View File

@ -46,4 +46,9 @@ public class ApiSignUrlUploadResponse {
* 下载url
*/
private String downloadSignUrl;
/**
* 文件名称
*/
private String fileName;
}

View File

@ -0,0 +1,35 @@
package cn.axzo.oss.http.model;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 服务端文件上传请求类
*
* @author zhaoyong
* @see ServerFileUploadByUrlRequest
* @since 2021-07-23 10:35
*/
@Data
public class ServerFileUploadByUrlRequest {
@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 = "fileUrl must not be null")
private String fileUrl;
private Integer channelCode;
/**
* 图片样式比如x-oss-process=image/auto-orient,1/resize,p_50/quality,q_30
*/
private String style;
}

View File

@ -14,7 +14,7 @@ public interface AliOssService extends BaseS3Service {
/**
* 授权给第三方下载
*/
String downloadSignUrl(String bucketName, String key, Long expireSecond, String fileName);
String downloadSignUrl(String bucketName, String key, Long expireSecond, String fileName, boolean hasFileName);
/**
* 授权给第三方-上传
@ -35,4 +35,9 @@ public interface AliOssService extends BaseS3Service {
*/
SimplifiedObjectMeta getObjectMeta(String bucketName, String key, String url);
/**
* 通过url上传至OBS
*/
String uploadByUrl(String bucketName, String tgtFileKey, String fileName, String url);
}

View File

@ -1,5 +1,6 @@
package cn.axzo.oss.integration.s3;
import com.obs.services.model.ObjectMetadata;
import com.obs.services.model.TemporarySignatureResponse;
import java.io.InputStream;
@ -24,7 +25,7 @@ public interface HuaWeiCloudService {
/**
* 授权给第三方-下载
*/
String downloadSignUrl(String bucketName, String key, Long expireSecond, String fileName);
String downloadSignUrl(String bucketName, String key, Long expireSecond, String fileName, String style, boolean hasFilename);
/**
* 授权给第三方-上传
@ -40,4 +41,14 @@ public interface HuaWeiCloudService {
* 获取url
*/
String getUrl(String bucketName, String tgtFileKey);
/**
* 通过url上传OBS
*/
String uploadFileByUrl(String bucketName, String key, String fileName, String url);
/**
* 元数据
*/
ObjectMetadata getObjectMeta(String bucketName, String key, String url);
}

View File

@ -289,7 +289,7 @@ public class AliOssServiceImpl implements AliOssService {
* 授权给第三方-下载
*/
@Override
public String downloadSignUrl(String bucketName, String key, Long expireSecond, String fileName) {
public String downloadSignUrl(String bucketName, String key, Long expireSecond, String fileName, boolean hasFileName) {
Date date = new Date();
date.setTime(date.getTime() + expireSecond * 1000);
try {
@ -297,7 +297,9 @@ public class AliOssServiceImpl implements AliOssService {
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, key, HttpMethod.GET);
request.setExpiration(date);
ResponseHeaderOverrides responseHeaderOverrides = new ResponseHeaderOverrides();
responseHeaderOverrides.setContentDisposition("attachment;filename=\"" + URLEncoder.encode(fileName, "utf-8") + "\"");
if (hasFileName) {
responseHeaderOverrides.setContentDisposition("attachment;filename=\"" + URLEncoder.encode(fileName, "utf-8") + "\"");
}
request.setResponseHeaders(responseHeaderOverrides);
URL url = aliOssClient.getClient().generatePresignedUrl(request);
log.info("aliyun downloadSignUrl result, bucketName:{}, key:{}, url:{}", bucketName, key, JsonUtil.obj2Str(url));
@ -390,4 +392,29 @@ public class AliOssServiceImpl implements AliOssService {
return new SimplifiedObjectMeta();
}
}
/**
* 通过url上传至OSS
*/
@Override
public String uploadByUrl(String bucketName, String tgtFileKey, String fileName, String url) {
OSS client = aliOssClient.getClient();
try {
InputStream srcStream = new URL(url).openStream();
// 创建上传文件的元信息通过文件云信息设置HTTP Header
ObjectMetadata metadata = new ObjectMetadata();
// 设置内容被下载时的名称
metadata.setContentDisposition("attachment;filename=\"" + URLEncoder.encode(fileName, "utf-8") + "\"");
metadata.setContentEncoding("utf-8");
client.putObject(bucketName, tgtFileKey, srcStream, metadata);
} catch (OSSException e) {
LogUtil.error("uploadByStream OSSException", e);
return "";
} catch (Exception e) {
LogUtil.error("uploadByStream ClientException", e);
return "";
}
return getUrl(bucketName, tgtFileKey);
}
}

View File

@ -1,7 +1,7 @@
package cn.axzo.oss.integration.s3.impl;
import cn.axzo.oss.common.enums.FileDownloadTypeEnum;
import cn.axzo.oss.common.enums.CodeEnum;
import cn.axzo.oss.common.enums.FileDownloadTypeEnum;
import cn.axzo.oss.common.exception.BizException;
import cn.axzo.oss.common.utils.JsonUtil;
import cn.axzo.oss.integration.s3.HuaWeiCloudService;
@ -13,12 +13,33 @@ import cn.hutool.json.JSONUtil;
import com.google.common.collect.Maps;
import com.obs.services.ObsClient;
import com.obs.services.exception.ObsException;
import com.obs.services.model.*;
import com.obs.services.model.CompleteMultipartUploadRequest;
import com.obs.services.model.CompleteMultipartUploadResult;
import com.obs.services.model.DeleteObjectResult;
import com.obs.services.model.DownloadFileRequest;
import com.obs.services.model.DownloadFileResult;
import com.obs.services.model.GetObjectRequest;
import com.obs.services.model.HttpMethodEnum;
import com.obs.services.model.InitiateMultipartUploadRequest;
import com.obs.services.model.InitiateMultipartUploadResult;
import com.obs.services.model.ObjectMetadata;
import com.obs.services.model.ObsObject;
import com.obs.services.model.PartEtag;
import com.obs.services.model.PutObjectRequest;
import com.obs.services.model.PutObjectResult;
import com.obs.services.model.TemporarySignatureRequest;
import com.obs.services.model.TemporarySignatureResponse;
import com.obs.services.model.UploadFileRequest;
import com.obs.services.model.UploadPartRequest;
import com.obs.services.model.UploadPartResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
@ -331,14 +352,21 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService {
* 授权给第三方-下载
*/
@Override
public String downloadSignUrl(String bucketName, String key, Long expireSeconds, String fileName) {
public String downloadSignUrl(String bucketName, String key, Long expireSeconds, String fileName, String style, boolean hasFilename) {
TemporarySignatureRequest request = new TemporarySignatureRequest(HttpMethodEnum.GET, expireSeconds);
request.setBucketName(bucketName);
request.setObjectKey(key);
Map<String, Object> queryParams = Maps.newHashMap();
try {
queryParams.put("response-content-disposition", "attachment;filename=\"" + URLEncoder.encode(fileName, "utf-8") + "\"");
request.setQueryParams(queryParams);
if (hasFilename) {
queryParams.put("response-content-disposition", "attachment;filename=\"" + URLEncoder.encode(fileName, "utf-8") + "\"");
}
if (StringUtils.hasText(style)) {
queryParams.put("x-image-process", style);
}
if (!CollectionUtils.isEmpty(queryParams)) {
request.setQueryParams(queryParams);
}
log.info("huawei cloud downloadSignUrl params, bucketName:{}, key:{}, request:{}", bucketName, key, JsonUtil.obj2Str(request));
TemporarySignatureResponse response = huaWeiCloudObsClient.getClient().createTemporarySignature(request);
log.info("huawei cloud downloadSignUrl result, bucketName:{}, key:{}, request:{}", bucketName, key, JsonUtil.obj2Str(response));
@ -403,4 +431,45 @@ public class HuaWeiCloudServiceImpl implements HuaWeiCloudService {
return allBuilder.toString();
}
/**
* 通过URL上传文件到OBS
*/
@Override
public String uploadFileByUrl(String bucketName, String key, String fileName, String url) {
ObsClient obsClient = huaWeiCloudObsClient.getClient();
try {
InputStream srcStream = new URL(url).openStream();
// 创建上传文件的元信息通过文件云信息设置HTTP Header
ObjectMetadata metadata = new ObjectMetadata();
// 设置内容被下载时的名称
metadata.setContentDisposition("attachment;filename=\"" + URLEncoder.encode(fileName, "utf-8") + "\"");
metadata.setContentEncoding("utf-8");
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);
return "";
}
}
/**
* 元数据
*/
@Override
public ObjectMetadata getObjectMeta(String bucketName, String key, String url) {
try {
if (org.apache.commons.lang3.StringUtils.isNotBlank(url) && url.toLowerCase().startsWith("http") && url.toLowerCase().contains("huaweicloud")) {
return huaWeiCloudObsClient.getClient().getObjectMetadata(bucketName, key);
}
log.info("huaweicloud-none-endpoint getObjectMeta params, bucketName:{}, key:{},url:{}", bucketName, key, url);
return new ObjectMetadata();
} catch (Exception e) {
log.warn("huaweicloud-getObjectMeta-exception, bucketName:{}, key:{}", bucketName, key, e);
return new ObjectMetadata();
}
}
}

View File

@ -60,12 +60,12 @@ public interface FileManager {
/**
* 根据华为云/阿里云授权给第三方下载
*/
String signUrlDownload(String bucketName, String key, Long expireSecond, String channelCode, String fileName);
String signUrlDownload(String bucketName, String key, Long expireSecond, String channelCode, String fileName, String style, boolean hasFileName);
/**
* 根据华为云/阿里云授权给第三方上传
*/
SignUrlUploadVo signUrlUpload(String bucketName, String key, String fileName, Long expireSecond, String channelCode, String contentType, String bucketType);
SignUrlUploadVo signUrlUpload(String bucketName, String key, String fileName, Long expireSecond, String channelCode, String contentType, String bucketType, boolean hasFileName);
/**
* 删除File
@ -81,4 +81,10 @@ public interface FileManager {
* 元数据
*/
ManaGetObjectMetaResponse getObjectMeta(String bucketName, String key, String url,String channelCode);
/**
* 通过url上传至云
*/
String uploadByUrl(String bulkName, String keyPath, String fileName, String url,
String channelCode);
}

View File

@ -0,0 +1,33 @@
package cn.axzo.oss.manager.api.dto.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
/**
* @program: oss
* @description: 文件上传
* @author: mr.jie
* @date: 2021-07-29 18:31
**/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class ServerFileUploadByUrlDto {
private String appCode;
private String bizScene;
private String fileName;
private String fileUrl;
private String filePath;
private Integer channelCode;
/**
* 图片样式比如x-oss-process=image/auto-orient,1/resize,p_50/quality,q_30
*/
private String style;
}

View File

@ -34,4 +34,13 @@ public class SignUrlDownloadDto {
*/
private String bizScene;
/**
* 图片样式比如x-oss-process=image/auto-orient,1/resize,p_50/quality,q_30
*/
private String style;
/**
* 是否带上文件名称
*/
private Boolean hasFileName = true;
}

View File

@ -57,4 +57,9 @@ public class SignUrlUploadDto {
* 过期时间
*/
private Long expiration;
/**
* 是否带上文件名称
*/
private Boolean hasFileName = true;
}

View File

@ -46,4 +46,9 @@ public class SignUrlUploadResponse {
* 下载url
*/
private String downloadSignUrl;
/**
* 文件名称
*/
private String fileName;
}

View File

@ -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.vo.SignUrlUploadVo;
import com.aliyun.oss.model.SimplifiedObjectMeta;
import com.obs.services.model.ObjectMetadata;
import com.obs.services.model.TemporarySignatureResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
@ -150,13 +151,13 @@ public class FileManagerImpl implements FileManager {
* 根据华为云/阿里云授权给第三方下载
*/
@Override
public String signUrlDownload(String bucketName, String key, Long expireSecond, String channelCode, String fileName) {
public String signUrlDownload(String bucketName, String key, Long expireSecond, String channelCode, String fileName, String style, boolean hasFileName) {
ChannelTypeEnum typeEnum = ChannelTypeEnum.getChannelTypeByChannelCode(channelCode);
switch (typeEnum) {
case OBS:// 华为云
return huaWeiCloudService.downloadSignUrl(bucketName, key, expireSecond, fileName);
return huaWeiCloudService.downloadSignUrl(bucketName, key, expireSecond, fileName, style, hasFileName);
case OSS:// 阿里云
return aliOssService.downloadSignUrl(bucketName, key, expireSecond, fileName);
return aliOssService.downloadSignUrl(bucketName, key, expireSecond, fileName, hasFileName);
default:
BizException.error(CodeEnum.CHANNEL_TYPE_NOT_EXIST);
}
@ -167,7 +168,7 @@ public class FileManagerImpl implements FileManager {
* 根据华为云/阿里云授权给第三方上传
*/
@Override
public SignUrlUploadVo signUrlUpload(String bucketName, String key, String fileName, Long expireSecond, String channelCode, String contentType, String bucketType) {
public SignUrlUploadVo signUrlUpload(String bucketName, String key, String fileName, Long expireSecond, String channelCode, String contentType, String bucketType, boolean hasFileName) {
ChannelTypeEnum typeEnum = ChannelTypeEnum.getChannelTypeByChannelCode(channelCode);
switch (typeEnum) {
case OBS:// 华为云
@ -178,13 +179,13 @@ public class FileManagerImpl implements FileManager {
.host(response.getActualSignedRequestHeaders().get(HUAWEI_CLOUD_SIGNURL_UPLOAD_HOST_KEY))
.contentType(response.getActualSignedRequestHeaders().get(HUAWEI_CLOUD_SIGNURL_UPLOAD_CONTENT_TYPE_KEY))
.channelCode(channelCode)
.downloadSignUrl(UrlUtil.httpToHttps(this.downloadHuaweiSignUrl(bucketName, key, expireSecond, bucketType, fileName)))
.downloadSignUrl(UrlUtil.httpToHttps(this.downloadHuaweiSignUrl(bucketName, key, expireSecond, bucketType, fileName, hasFileName)))
.build();
case OSS:// 阿里云
return SignUrlUploadVo.builder()
.signUrl(UrlUtil.httpToHttps(aliOssService.uploadSignUrl(bucketName, key, fileName,expireSecond)))
.channelCode(channelCode)
.downloadSignUrl(UrlUtil.httpToHttps(this.downloadAliyunSignUrl(bucketName, key, expireSecond, bucketType, fileName)))
.downloadSignUrl(UrlUtil.httpToHttps(this.downloadAliyunSignUrl(bucketName, key, expireSecond, bucketType, fileName, hasFileName)))
.build();
default:
BizException.error(CodeEnum.CHANNEL_TYPE_NOT_EXIST);
@ -195,10 +196,10 @@ public class FileManagerImpl implements FileManager {
/**
* 构建华为云下载地址
*/
private String downloadHuaweiSignUrl(String bucketName, String key, Long expireSecond, String bucketType, String fileName) {
private String downloadHuaweiSignUrl(String bucketName, String key, Long expireSecond, String bucketType, String fileName, boolean hasFileName) {
switch (BucketTypeEnum.getByCode(bucketType)) {
case PRIVATE_BUCKET:
return huaWeiCloudService.downloadSignUrl(bucketName, key, expireSecond, fileName);
return huaWeiCloudService.downloadSignUrl(bucketName, key, expireSecond, fileName, null, hasFileName);
case PUBLIC_BUCKET:
return huaWeiCloudService.getUrl(bucketName, key);
default:
@ -210,10 +211,10 @@ public class FileManagerImpl implements FileManager {
/**
* 构建阿里云下载地址
*/
private String downloadAliyunSignUrl(String bucketName, String key, Long expireSecond, String bucketType, String fileName) {
private String downloadAliyunSignUrl(String bucketName, String key, Long expireSecond, String bucketType, String fileName, boolean hasFileName) {
switch (BucketTypeEnum.getByCode(bucketType)) {
case PRIVATE_BUCKET:
return aliOssService.downloadSignUrl(bucketName, key, expireSecond, fileName);
return aliOssService.downloadSignUrl(bucketName, key, expireSecond, fileName, hasFileName);
case PUBLIC_BUCKET:
return aliOssService.getUrl(bucketName, key);
default:
@ -263,7 +264,8 @@ public class FileManagerImpl implements FileManager {
ChannelTypeEnum typeEnum = ChannelTypeEnum.getChannelTypeByChannelCode(channelCode);
switch (typeEnum) {
case OBS:// 华为云
return ManaGetObjectMetaResponse.builder().build();
ObjectMetadata objectMetadata = huaWeiCloudService.getObjectMeta(bucketName, key, url);
return ManaGetObjectMetaResponse.builder().bucketName(bucketName).key(key).size(objectMetadata.getContentLength()).build();
case OSS:// 阿里云
SimplifiedObjectMeta simplifiedObjectMeta = aliOssService.getObjectMeta(bucketName, key, url);
return ManaGetObjectMetaResponse.builder().bucketName(bucketName).key(key).size(simplifiedObjectMeta.getSize()).build();
@ -272,4 +274,26 @@ public class FileManagerImpl implements FileManager {
}
return ManaGetObjectMetaResponse.builder().build();
}
/**
* 通过url上传至云
*/
public String uploadByUrl(String bulkName, String keyPath, String fileName, String url,
String channelCode) {
try {
switch (ChannelTypeEnum.getChannelTypeByChannelCode(channelCode)) {
case OSS:
return aliOssService.uploadByUrl(bulkName,keyPath, fileName, url);
case OBS:
return huaWeiCloudService.uploadFileByUrl(bulkName, keyPath, fileName, url);
default:
BizException.error(CodeEnum.CHANNEL_TYPE_NOT_EXIST);
}
} catch (Exception e) {
log.error("通过url上传至云 exception,bulkName:{}, key:{}, fileName:{}, url:{},channelCode:{}"
, bulkName, keyPath, fileName, url, channelCode, e);
}
return StringUtils.EMPTY;
}
}

View File

@ -0,0 +1,41 @@
package cn.axzo.oss.service.api;
import cn.axzo.framework.auth.domain.ContextInfo;
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;
import cn.axzo.oss.manager.api.dto.request.MultipartUploadCompleteDto;
import cn.axzo.oss.manager.api.dto.request.MultipartUploadDto;
import cn.axzo.oss.manager.api.dto.request.MultipartUploadFileDto;
import cn.axzo.oss.manager.api.dto.request.MultipartUploadInitDto;
import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto;
import cn.axzo.oss.manager.api.dto.request.ServerFileDownloadDto;
import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto;
import cn.axzo.oss.manager.api.dto.request.SignUrlDownloadDto;
import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto;
import cn.axzo.oss.manager.api.dto.response.FileInformationResponse;
import cn.axzo.oss.manager.api.dto.response.FindFileKeyResponse;
import cn.axzo.oss.manager.api.dto.response.FindFileUrlResponse;
import cn.axzo.oss.manager.api.dto.response.MultipartUploadInitResponse;
import cn.axzo.oss.manager.api.dto.response.MultipartUploadResponse;
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 org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
* @Author admin
* @Description
* @Date 2021/7/28 22:48
* @Version 0.0.1
**/
public interface FileByUrlService {
/**
* 上传-通过url
*/
ServerFileUploadResponse uploadByUrl(String appCode, String bizScene, String fileName, String url,Integer channelType, String style, ContextInfo.LiteSaasContext liteSaasContext);
}

View File

@ -26,6 +26,12 @@
<groupId>com.huaweicloud</groupId>
<artifactId>esdk-obs-java-bundle</artifactId>
</dependency>
<dependency>
<groupId>cn.axzo.framework.logging</groupId>
<artifactId>axzo-common-trace</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,349 @@
package cn.axzo.oss.service.impl;
import cn.axzo.framework.auth.domain.ContextInfo;
import cn.axzo.log.platform.client.LogPlatClient;
import cn.axzo.log.platform.client.model.OperateLogReq;
import cn.axzo.oss.common.constans.CommonConstants;
import cn.axzo.oss.common.constans.CommonConstants.FileStatus;
import cn.axzo.oss.common.constans.CommonConstants.TableDelete;
import cn.axzo.oss.common.enums.BucketTypeEnum;
import cn.axzo.oss.common.enums.ChannelTypeEnum;
import cn.axzo.oss.common.enums.CodeEnum;
import cn.axzo.oss.common.enums.FileClassEnum;
import cn.axzo.oss.common.enums.FileDownloadTypeEnum;
import cn.axzo.oss.common.enums.FileStatusEnum;
import cn.axzo.oss.common.enums.FileUploadTypeEnum;
import cn.axzo.oss.common.exception.BizException;
import cn.axzo.oss.common.utils.JsonUtil;
import cn.axzo.oss.common.utils.UrlUtil;
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.FileApp;
import cn.axzo.oss.dal.entity.FileBusinessScene;
import cn.axzo.oss.dal.entity.FileUploadConfig;
import cn.axzo.oss.dal.repository.FileAppDao;
import cn.axzo.oss.dal.repository.FileDao;
import cn.axzo.oss.integration.s3.config.HuaWeiCloudObsConfig;
import cn.axzo.oss.manager.api.AppChannelBucketManager;
import cn.axzo.oss.manager.api.FileBusinessSceneManager;
import cn.axzo.oss.manager.api.FileManager;
import cn.axzo.oss.manager.api.FileUploadConfigManager;
import cn.axzo.oss.manager.api.dto.PartETag;
import cn.axzo.oss.manager.api.dto.request.DeleteFileDto;
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.MultipartUploadCompleteDto;
import cn.axzo.oss.manager.api.dto.request.MultipartUploadDto;
import cn.axzo.oss.manager.api.dto.request.MultipartUploadFileDto;
import cn.axzo.oss.manager.api.dto.request.MultipartUploadInitDto;
import cn.axzo.oss.manager.api.dto.request.ServerFileDeleteDto;
import cn.axzo.oss.manager.api.dto.request.ServerFileDownloadDto;
import cn.axzo.oss.manager.api.dto.request.ServerFileUploadDto;
import cn.axzo.oss.manager.api.dto.request.SignUrlDownloadDto;
import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto;
import cn.axzo.oss.manager.api.dto.response.FileInformationResponse;
import cn.axzo.oss.manager.api.dto.response.FindFileKeyResponse;
import cn.axzo.oss.manager.api.dto.response.FindFileUrlResponse;
import cn.axzo.oss.manager.api.dto.response.MultipartUploadInitResponse;
import cn.axzo.oss.manager.api.dto.response.MultipartUploadResponse;
import cn.axzo.oss.manager.api.dto.response.ServerFileDownloadResponse;
import cn.axzo.oss.manager.api.dto.response.ServerFileUploadResponse;
import cn.axzo.oss.manager.api.dto.response.SignUrlDownloadResponse;
import cn.axzo.oss.manager.api.dto.response.SignUrlUploadResponse;
import cn.axzo.oss.manager.api.vo.SignUrlUploadVo;
import cn.axzo.oss.service.api.FileByUrlService;
import cn.axzo.oss.service.api.FileService;
import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import static cn.axzo.oss.common.constans.CommonConstants.APP_PRO_BUCKET_NAME;
/**
* @Author admin
* @Description
* @Date 2021/7/28 22:48
* @Version 0.0.1
**/
@Service
@RefreshScope
@Slf4j
public class FileByUrlServiceImpl implements FileByUrlService {
private static final String FILE_UPLOAD_CODE = "OSS_FILE_UPLOAD";
private static final String FILE_UPLOAD_NAME = "文件上传";
@Autowired
private FileDao fileDao;
@Autowired
private FileManager fileManager;
@Autowired
private FileAppDao fileAppDao;
@Autowired
private AppChannelBucketManager appChannelBucketManager;
@Autowired
private FileBusinessSceneManager fileBusinessSceneManager;
@Autowired
private FileUploadConfigManager fileUploadConfigManager;
@Autowired
private Environment environment;
@Autowired
private LogPlatClient logPlatClient;
@Autowired
private FileService fileService;
@Value("${sign.url.download.expire.second:2000}")
private Long SIGN_URL_DOWNLOAD_EXPIRE_SECOND;
/**
* 通过url上传
*/
@Override
public ServerFileUploadResponse uploadByUrl(String appCode, String bizScene, String fileName, String url, Integer channelType,String style, ContextInfo.LiteSaasContext liteSaasContext) {
log.info("uploadByUrl params,appCode:{},bizScene:{}, fileName:{},url:{},channelType:{}", appCode, bizScene, fileName, url, channelType);
Long start = System.currentTimeMillis();
//重新构建链接
url = this.rebuildUrl(url, style);
log.info("uploadByUrl-style-url:{}",url);
File ossFile = uploadFileAndGetFile(appCode, bizScene, fileName, url, channelType);
//操作日志记录
operateLog(this.buildUploadParams(appCode, bizScene, fileName, url, channelType), "", FILE_UPLOAD_CODE, FILE_UPLOAD_NAME, liteSaasContext);
ServerFileUploadResponse response = this.buildResponse(ossFile);
log.info("uploadByUrl result,appCode:{},bizScene:{}, fileName:{},url:{},channelType:{}, response:{},times:{}"
, appCode, bizScene, fileName, url, channelType, JsonUtil.obj2Str(response), System.currentTimeMillis() - start);
return response;
}
/**
* url:https://xxx,则直接返回
* url:fileKey,则返回https://链接
*/
private String rebuildUrl(String url, String style) {
if (StringUtils.isNotBlank(url)) {
SignUrlDownloadDto signUrlDownloadDto = SignUrlDownloadDto.builder().fileKeys(Lists.newArrayList(url)).style(style).build();
List<SignUrlDownloadResponse> responseList = fileService.signUrlDownload(signUrlDownloadDto);
if (CollectionUtil.isNotEmpty(responseList)) {
return responseList.get(0).getSignUrl();
}
}
return StringUtils.EMPTY;
}
/**
* 操作日志记录
*/
private void operateLog(String param, String serviceName, String featureCode, String featureName, ContextInfo.LiteSaasContext liteSaasContext) {
if (liteSaasContext == null || liteSaasContext.getIdentityId() == null || liteSaasContext.getIdentityType() == null) {
log.warn("获取用户上下文信息失败");
return;
}
//记录日志
try {
OperateLogReq log = OperateLogReq.builder()
.serviceName(StringUtils.isNotEmpty(serviceName) ? serviceName : environment.getProperty("spring.application.name"))
.featureCode(featureCode)
.featureName(featureName)
.operateTime(new Date())
.identityId(liteSaasContext.getIdentityId())
.identityType(liteSaasContext.getIdentityType())
.operateParam(param)
.workspaceId(liteSaasContext.getWorkspaceId())
.operateType(1)
.build();
logPlatClient.createOperateLog(log);
} catch (Exception e) {
log.warn("服务间调用异常-发送日志失败: errMsg={}.", e.getMessage());
}
}
/**
* 上传并获取文件
*/
private File uploadFileAndGetFile(String appCode, String bizScene, String fileName, String url, Integer channelType) {
log.info("update channelType:{}, fileName:{}, appCode:{}, bizScene:{}",
channelType, fileName, appCode, bizScene);
// 检查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());
// 上传文件并生成file对象
return generateFile(fileUploadConfig, fileName,url, fileUploadConfig.getChannelCode(), appChannelBucket.getBucketType(), scene.getDownloadExpiration());
}
/**
* 检查appCode是否有效
*
* @param appCode
*/
private void checkAppCode(final String appCode) {
log.info("checkAppCode appCode = {}", appCode);
FileApp fileApp = fileAppDao.getByAppCode(appCode);
BizException.error(Utility.objIsNotNull(fileApp), CodeEnum.FILE_APP_IS_EMPTY);
}
/**
* 生产File对象
*/
private File generateFile(FileUploadConfig fileUploadConfig, String fileName, String url, String channelCode, String bucketType, Long expire) {
// 判断容量
String fileConform = isFileConform(fileUploadConfig, fileName);
String uuid = Utility.getUUID();
// 生成上传文件的唯一key
String tgtFileKey = Utility.generateFileKey(fileUploadConfig.getDirectory(), uuid, fileConform);
// 上传文件
String fileUrl = fileManager.uploadByUrl(fileUploadConfig.getBucketName(), tgtFileKey, fileName, url, channelCode);
//重新构建fileUrl
fileUrl = rebuildFileUrl(fileUploadConfig, fileName, channelCode, bucketType, expire, tgtFileKey, fileUrl);
File file = rebuildOssFile(fileUploadConfig, fileName, fileConform, uuid, fileUrl, Utility.getMd5(url));
fileDao.save(file);
return file;
}
/**
* 重新构建fileUrl
*/
private String rebuildFileUrl(FileUploadConfig fileUploadConfig, String fileName, String channelCode, String bucketType, Long expire, String tgtFileKey, String fileUrl) {
switch (BucketTypeEnum.getByCode(bucketType)) {
case PUBLIC_BUCKET:
fileUrl = this.fileManager.fetchDownloadUrl(fileUploadConfig.getBucketName(), tgtFileKey, channelCode);
break;
case PRIVATE_BUCKET:
fileUrl = this.fileManager.signUrlDownload(fileUploadConfig.getBucketName(), tgtFileKey, Objects.nonNull(expire) ? expire : SIGN_URL_DOWNLOAD_EXPIRE_SECOND , channelCode, fileName, null,false);
break;
default:
BizException.error(CodeEnum.CHANNEL_TYPE_NOT_EXIST);
}
// 保存失败
if (Utility.isBlank(fileUrl)) {
log.error("fileUrl is empty");
throw new BizException(CodeEnum.FILE_UPLOAD_FAILED);
}
return fileUrl;
}
/**
*
* @param fileUploadConfig
* @param fileName
* @param fileConform
* @param uuid
* @param fileUrl
* @param fileMd5
* @return
*/
private File rebuildOssFile(FileUploadConfig fileUploadConfig, String fileName, String fileConform, String uuid,
String fileUrl, String fileMd5) {
File ossFile = new File();
ossFile.setAppChannelBucketNo(fileUploadConfig.getAppChannelBucketNo());
ossFile.setAppCode(fileUploadConfig.getAppCode());
ossFile.setChannelCode(fileUploadConfig.getChannelCode());
ossFile.setBucketName(fileUploadConfig.getBucketName());
ossFile.setDirectory(fileUploadConfig.getDirectory());
ossFile.setStatus(FileStatusEnum.STATUS_UPLOAD_FAIL.getCode());
ossFile.setStorageUnit(fileUploadConfig.getStorageUnit());
ossFile.setStorageSize(fileUploadConfig.getStorageSize());
ossFile.setFileFormat(fileConform);
ossFile.setFileUuid(uuid);
ossFile.setFileUrl(fileUrl);
ossFile.setUrlMd5(Utility.getMd5(fileUrl));
ossFile.setStatus(FileStatusEnum.STATUS_UPLOAD_SUCCESS.getCode());
ossFile.setFileName(fileName);
ossFile.setFileMd5(fileMd5);
return ossFile;
}
/**
* 判断文件是否符合要求
*/
private String isFileConform(FileUploadConfig fileUploadConfig, String fileName) {
// 文件格式判断
String[] formats = fileUploadConfig.getFileFormat().split(FileClassEnum.COMMA.type);
int lastIndexOf = fileName.lastIndexOf(FileClassEnum.DOT.type);
BizException
.error(lastIndexOf != CommonConstants.NOT_FOUND_INDEX_OF, CodeEnum.NOT_FILE_FORMAT);
// 是否包含指定格式
String fileFormat = fileName.substring(lastIndexOf + CommonConstants.ONE).toLowerCase();
boolean contains = Arrays.asList(formats).contains(fileFormat);
BizException.error(contains, CodeEnum.FILE_FORMAT_NOT_SUPPORTED);
return fileFormat;
}
/**
* 构建操作日志入参
*/
private String buildUploadParams(String appCode, String bizScene, String fileName, String url,Integer channelType) {
StringBuilder builder = new StringBuilder("appCode:");
builder.append(appCode).append(";");
builder.append("bizScene").append(":");
builder.append(bizScene).append(";");
builder.append("fileName").append(":");
builder.append(fileName).append(";");
builder.append("url").append(":");
builder.append(url).append(";");
builder.append("channelType").append("");
builder.append(channelType).append(";");
return builder.toString();
}
/**
* 构建返回对象
*/
private ServerFileUploadResponse buildResponse(File ossFile) {
ServerFileUploadResponse response = new ServerFileUploadResponse();
response.setUrl(ossFile.getFileUrl());
response.setUrlMd5(ossFile.getUrlMd5());
response.setFileKey(ossFile.getFileUuid());
return response;
}
}

View File

@ -502,7 +502,7 @@ public class FileServiceImpl implements FileService {
response.setFileKey(fileKey);
if (Objects.nonNull(bucketTypeMap.get(file.getAppChannelBucketNo())) && BucketTypeEnum.PRIVATE_BUCKET.getCode().equals(bucketTypeMap.get(file.getAppChannelBucketNo()))) {
String tgtFileKey = Utility.generateFileKey(file.getDirectory(), file.getFileUuid(), file.getFileFormat());
response.setUrl(fileManager.signUrlDownload(file.getBucketName(), tgtFileKey, SIGN_URL_DOWNLOAD_EXPIRE_SECOND, file.getChannelCode(), file.getFileName()));
response.setUrl(fileManager.signUrlDownload(file.getBucketName(), tgtFileKey, SIGN_URL_DOWNLOAD_EXPIRE_SECOND, file.getChannelCode(), file.getFileName(), null, false));
} else {
response.setUrl(fileUrl);
}
@ -833,6 +833,8 @@ public class FileServiceImpl implements FileService {
public List<SignUrlDownloadResponse> signUrlDownload(SignUrlDownloadDto dto) {
log.info("signUrl download dto = {}", JsonUtil.obj2Str(dto));
Long start = System.currentTimeMillis();
//是否代文件名称
dto.setHasFileName(Objects.isNull(dto.getHasFileName()) ? true : dto.getHasFileName());
if (CollectionUtil.isEmpty(dto.getFileKeys())) {
return Lists.newArrayList();
@ -846,7 +848,7 @@ public class FileServiceImpl implements FileService {
List<SignUrlDownloadResponse> httpUrlSignResList = this.buildHttpUrlSignResponse(dto);
//3 构建fileKey入参对象集合
List<SignUrlDownloadResponse> fileKeyResList = this.buildFileKeyResponse(dto.getFileKeys(), dto.getBizScene());
List<SignUrlDownloadResponse> fileKeyResList = this.buildFileKeyResponse(dto.getFileKeys(), dto.getBizScene(), dto.getStyle(), dto.getHasFileName());
//4 1/2/3集合累加
httpUrlResList.addAll(fileKeyResList);
httpUrlResList.addAll(httpUrlSignResList);
@ -857,7 +859,7 @@ public class FileServiceImpl implements FileService {
/**
* 构建fileKey(非http的入参)的返回对象
*/
private List<SignUrlDownloadResponse> buildFileKeyResponse(List<String> fileKeys, String bizScene) {
private List<SignUrlDownloadResponse> buildFileKeyResponse(List<String> fileKeys, String bizScene, String style, boolean hasFileName) {
if (CollectionUtil.isEmpty(fileKeys)) {
return Lists.newArrayList();
}
@ -878,13 +880,13 @@ public class FileServiceImpl implements FileService {
List<FileBusinessScene> fileBusinessSceneList = fileBusinessSceneManager.queryByBucketNoAndScene(fileList.stream().map(File::getAppChannelBucketNo).collect(Collectors.toSet()), bizScene);
Map<String, Long> bizSceneExpireMap = fileBusinessSceneList.stream().collect(Collectors.toMap(FileBusinessScene::getAppChannelBucketNo, FileBusinessScene::getDownloadExpiration, (x, y) -> y));
//构建返回集合
return this.buildFileKeyRespByFile(fileList, bucketTypeMap, bizSceneExpireMap);
return this.buildFileKeyRespByFile(fileList, bucketTypeMap, bizSceneExpireMap, style, hasFileName);
}
/**
* 通过File对象构建返回集合
*/
private List<SignUrlDownloadResponse> buildFileKeyRespByFile(List<File> fileList,Map<String, String> bucketTypeMap, Map<String, Long> bizSceneExpireMap) {
private List<SignUrlDownloadResponse> buildFileKeyRespByFile(List<File> fileList,Map<String, String> bucketTypeMap, Map<String, Long> bizSceneExpireMap, String style, boolean hasFileName) {
List<SignUrlDownloadResponse> responseList = fileList.stream().map(item -> {
Long expire = bizSceneExpireMap.get(item.getAppChannelBucketNo());
// bucket下的key
@ -894,12 +896,12 @@ 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(url)
.signUrl(this.buildPublicXImageProcess(url, style))
.fileKey(item.getFileUuid())
.fileName(item.getFileName())
.build();
case PRIVATE_BUCKET://私有桶 - 临时授权链接 例如 http://xxx.png?Expire=a&AccessKeyId=b&Signature=c&repsonse-content-disposition=d
String signUrl = this.fileManager.signUrlDownload(item.getBucketName(), tgtFileKey, Objects.nonNull(expire) ? expire : SIGN_URL_DOWNLOAD_EXPIRE_SECOND , item.getChannelCode(), item.getFileName());
String signUrl = this.fileManager.signUrlDownload(item.getBucketName(), tgtFileKey, Objects.nonNull(expire) ? expire : SIGN_URL_DOWNLOAD_EXPIRE_SECOND , item.getChannelCode(), item.getFileName(), style, hasFileName);
return SignUrlDownloadResponse.builder()
.signUrl(UrlUtil.httpToHttps(signUrl))
.fileKey(item.getFileUuid())
@ -925,11 +927,27 @@ public class FileServiceImpl implements FileService {
return Lists.newArrayList();
}
return httpUrlList.stream().map(item -> SignUrlDownloadResponse.builder()
.signUrl(item)
.signUrl(this.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入参)返回对象
*/
@ -945,7 +963,7 @@ public class FileServiceImpl implements FileService {
if (CollectionUtil.isEmpty(map)) {
return httpUrlList.stream().map(item -> SignUrlDownloadResponse.builder().fileKey(item).signUrl(item).build()).collect(Collectors.toList());
}
List<SignUrlDownloadResponse> responseList = this.buildFileKeyResponse(Lists.newArrayList(map.values()), null);
List<SignUrlDownloadResponse> responseList = this.buildFileKeyResponse(Lists.newArrayList(map.values()), null, dto.getStyle(), dto.getHasFileName());
if (CollectionUtil.isEmpty(responseList)) {
return httpUrlList.stream().map(item -> SignUrlDownloadResponse.builder().fileKey(item).signUrl(item).build()).collect(Collectors.toList());
}
@ -1072,7 +1090,9 @@ public class FileServiceImpl implements FileService {
Long expiration = this.buildExpiration(dto, scene);
//1 调用阿里云/华为云 获取临时授权signUrl
SignUrlUploadVo signUrlUpload = this.fileManager.signUrlUpload(fileUploadConfig.getBucketName(), tgtFileKey, dto.getFileName(),expiration
, fileUploadConfig.getChannelCode(), StringUtils.isNotBlank(dto.getContentType()) ? dto.getContentType() : "multipart/form-data", appChannelBucket.getBucketType());
, fileUploadConfig.getChannelCode()
, StringUtils.isNotBlank(dto.getContentType()) ? dto.getContentType() : "multipart/form-data", appChannelBucket.getBucketType()
, Objects.isNull(dto.getHasFileName()) ? true: dto.getHasFileName() );
//2 保存File对象
this.saveOssFile(fileUploadConfig, dto.getFileName(), fileFormat, uuid,
signUrlUpload.getDownloadSignUrl(), Utility.getMd5(signUrlUpload.getDownloadSignUrl()), expiration);
@ -1083,6 +1103,7 @@ public class FileServiceImpl implements FileService {
.host(signUrlUpload.getHost())
.channelCode(signUrlUpload.getChannelCode())
.downloadSignUrl(UrlUtil.httpToHttps(signUrlUpload.getDownloadSignUrl()))
.fileName(dto.getFileName())
.build();
}