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

Feature/req 2673

See merge request universal/infrastructure/backend/oss!156
This commit is contained in:
徐大伟 2024-10-09 08:31:31 +00:00
commit 5281a816c9
18 changed files with 738 additions and 114 deletions

View File

@ -14,6 +14,8 @@ import cn.axzo.oss.http.model.ApiSignUrlUploadRequest;
import cn.axzo.oss.http.model.ApiSignUrlUploadResponse; import cn.axzo.oss.http.model.ApiSignUrlUploadResponse;
import cn.axzo.oss.http.model.BatchGetObjectMetaRequest; import cn.axzo.oss.http.model.BatchGetObjectMetaRequest;
import cn.axzo.oss.http.model.BatchGetObjectMetaResponse; import cn.axzo.oss.http.model.BatchGetObjectMetaResponse;
import cn.axzo.oss.http.model.FetchUploadSignUrlToPublishRequest;
import cn.axzo.oss.http.model.FetchUploadSignUrlToPublishResponse;
import cn.axzo.oss.http.model.FileInformationResponse; import cn.axzo.oss.http.model.FileInformationResponse;
import cn.axzo.oss.http.model.FindFileKeyRequest; import cn.axzo.oss.http.model.FindFileKeyRequest;
import cn.axzo.oss.http.model.FindFileKeyResponse; import cn.axzo.oss.http.model.FindFileKeyResponse;
@ -31,6 +33,7 @@ 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.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.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;
@ -144,6 +147,15 @@ public class ServerFileController implements ServerFileServiceApi {
return CommonResponse.success(BeanConverter.convert(fileService.signUrlDownload(dto), ApiSignUrlDownloadResponse.class)); return CommonResponse.success(BeanConverter.convert(fileService.signUrlDownload(dto), ApiSignUrlDownloadResponse.class));
} }
/**
* 授权给第三方下载-生成临时url
*/
@Override
public CommonResponse<List<ApiSignUrlDownloadResponse>> signUrlFetchDownloadNoFile(@Valid @RequestBody ApiSignUrlDownloadRequest request) {
SignUrlDownloadDto dto = BeanConvertUtil.copyBean(request, SignUrlDownloadDto.class);
return CommonResponse.success(BeanConverter.convert(fileService.signUrlDownloadNoFile(dto), ApiSignUrlDownloadResponse.class));
}
/** /**
* 授权给第三方上传-生成临时url * 授权给第三方上传-生成临时url
*/ */
@ -161,32 +173,8 @@ public class ServerFileController implements ServerFileServiceApi {
*/ */
@Override @Override
public CommonResponse<GetObjectMetaResponse> getObjectMeta(@RequestBody GetObjectMetaRequest request) { public CommonResponse<GetObjectMetaResponse> getObjectMeta(@RequestBody GetObjectMetaRequest request) {
if (!StringUtils.hasText(request.getUrl()) && !StringUtils.hasText(request.getBucketName()) && !StringUtils.hasText(request.getKey())) { GetObjectMetaDto dto = BeanConvertUtil.copyBean(request, GetObjectMetaDto.class);
throw new BizException(CodeEnum.URL_BUCKET_NAME_KEY_ALL_EMPTY); return CommonResponse.success(BeanConverter.convert(this.fileService.getObjectMeta(dto), GetObjectMetaResponse.class));
}
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()
, 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;
} }
/** /**
@ -232,4 +220,15 @@ public class ServerFileController implements ServerFileServiceApi {
String targetFileKey = fileCopyToDictService.copyToDict(dto); String targetFileKey = fileCopyToDictService.copyToDict(dto);
return CommonResponse.success(ServerFileCopyToDictResponse.builder().targetFileKey(targetFileKey).build()); return CommonResponse.success(ServerFileCopyToDictResponse.builder().targetFileKey(targetFileKey).build());
} }
/**
* 临时授权上传-生成临时url-公有桶
*/
@Override
public CommonResponse<FetchUploadSignUrlToPublishResponse> fetchUploadSignUrlToPublish(@Valid @RequestBody FetchUploadSignUrlToPublishRequest request) {
SignUrlUploadDto dto = BeanConvertUtil.copyBean(request, SignUrlUploadDto.class);
dto.setAppCode(dto.getAppCode() + "-public");
dto.setBizScene(dto.getAppCode() + "-public");
return CommonResponse.success(BeanConverter.convert(fileService.signUrlUpload(dto, ContextInfo.LiteSaasContext.builder().build()), FetchUploadSignUrlToPublishResponse.class));
}
} }

View File

@ -39,6 +39,9 @@ public class UrlUtil {
if (org.springframework.util.StringUtils.hasText(bucketName)) { if (org.springframework.util.StringUtils.hasText(bucketName)) {
return bucketName; return bucketName;
} }
if (url.contains("?")) {
url = url.split("\\?")[0];
}
if (org.springframework.util.StringUtils.hasText(url)) { if (org.springframework.util.StringUtils.hasText(url)) {
if (url.contains(".") && url.contains("//")) { if (url.contains(".") && url.contains("//")) {
return url.substring(url.indexOf("//") + 2,url.indexOf(".")); return url.substring(url.indexOf("//") + 2,url.indexOf("."));

View File

@ -6,6 +6,8 @@ import cn.axzo.oss.http.model.ApiSignUrlUploadRequest;
import cn.axzo.oss.http.model.ApiSignUrlUploadResponse; import cn.axzo.oss.http.model.ApiSignUrlUploadResponse;
import cn.axzo.oss.http.model.BatchGetObjectMetaRequest; import cn.axzo.oss.http.model.BatchGetObjectMetaRequest;
import cn.axzo.oss.http.model.BatchGetObjectMetaResponse; import cn.axzo.oss.http.model.BatchGetObjectMetaResponse;
import cn.axzo.oss.http.model.FetchUploadSignUrlToPublishRequest;
import cn.axzo.oss.http.model.FetchUploadSignUrlToPublishResponse;
import cn.axzo.oss.http.model.FileInformationResponse; import cn.axzo.oss.http.model.FileInformationResponse;
import cn.axzo.oss.http.model.FindFileKeyRequest; import cn.axzo.oss.http.model.FindFileKeyRequest;
import cn.axzo.oss.http.model.FindFileKeyResponse; import cn.axzo.oss.http.model.FindFileKeyResponse;
@ -22,9 +24,11 @@ import cn.axzo.oss.http.model.ServerFileUploadResponse;
import cn.axzo.oss.http.model.ServerFileUploadV2Request; import cn.axzo.oss.http.model.ServerFileUploadV2Request;
import cn.azxo.framework.common.model.CommonResponse; import cn.azxo.framework.common.model.CommonResponse;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import javax.validation.Valid;
import java.util.List; import java.util.List;
/** /**
@ -83,6 +87,14 @@ public interface ServerFileServiceApi {
@RequestMapping(value = "api/signUrl/fetchDownload", method = RequestMethod.POST) @RequestMapping(value = "api/signUrl/fetchDownload", method = RequestMethod.POST)
CommonResponse<List<ApiSignUrlDownloadResponse>> signUrlFetchDownload(ApiSignUrlDownloadRequest request); CommonResponse<List<ApiSignUrlDownloadResponse>> signUrlFetchDownload(ApiSignUrlDownloadRequest request);
/**
* 临时授权下载-生成临时url
*/
@RequestMapping(value = "api/signUrl/fetchDownloadNoFile", method = RequestMethod.POST)
CommonResponse<List<ApiSignUrlDownloadResponse>> signUrlFetchDownloadNoFile(@Valid @RequestBody ApiSignUrlDownloadRequest request);
/** /**
* 临时授权上传-生成临时url * 临时授权上传-生成临时url
*/ */
@ -109,6 +121,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-公有桶
*/
@RequestMapping(value = "/api/v1/server/fetchUploadToPublishSignUrl", method = RequestMethod.POST)
CommonResponse<FetchUploadSignUrlToPublishResponse> fetchUploadSignUrlToPublish(@Valid @RequestBody FetchUploadSignUrlToPublishRequest request);
/** /**
* 通过URL上传文件 * 通过URL上传文件
* @param request * @param request

View File

@ -32,6 +32,11 @@ public class ApiSignUrlDownloadRequest {
*/ */
private String bizScene; private String bizScene;
/**
* bizScene,对应目录
*/
private String appCode;
/** /**
* 图片样式比如x-oss-process=image/auto-orient,1/resize,p_50/quality,q_30 * 图片样式比如x-oss-process=image/auto-orient,1/resize,p_50/quality,q_30
*/ */
@ -42,4 +47,9 @@ public class ApiSignUrlDownloadRequest {
*/ */
private Boolean hasFileName = true; private Boolean hasFileName = true;
/**
* 过期时间
*/
private Long expiration;
} }

View File

@ -61,4 +61,8 @@ public class ApiSignUrlUploadRequest {
* 是否带上文件名称 * 是否带上文件名称
*/ */
private Boolean hasFileName = true; private Boolean hasFileName = true;
/**
* 桶key
*/
private String bucketKey;
} }

View File

@ -0,0 +1,68 @@
package cn.axzo.oss.http.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank;
/**
* @author: xudawei
* @date: 2024-03-12
* @description: 授权给第三方下载
**/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FetchUploadSignUrlToPublishRequest {
/**
* appCode
*/
@NotBlank(message = "appCode not blank")
private String appCode;
/**
* bizScene,对应目录
*/
@NotBlank(message = "bizScene not blank")
private String bizScene;
/**
* serviceName
*/
private String serviceName;
/**
* 1-阿里云-aliyun
* 2-华为云-huaweicloud
*/
private Integer channelType;
/**
* 桶名称
*/
private String bucketName;
/**
* 文件名称
*/
private String fileName;
/**
* 类型
*/
private String contentType = "multipart/form-data";
/**
* 过期时间
*/
private Long expiration;
/**
* 是否带上文件名称
*/
private Boolean hasFileName = true;
/**
* 桶key
*/
private String bucketKey;
}

View File

@ -0,0 +1,54 @@
package cn.axzo.oss.http.model;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author: xudawei
* @Date: 2024/03/12
* @Description: 授权给第三方下载
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FetchUploadSignUrlToPublishResponse {
/**
* 文件临时-URL
*/
private String signUrl;
/**
* 文件 Key
*/
private String fileKey;
/**
* host
*/
private String host;
/**
* 类型
*/
private String contentType;
/**
* 通道
* 1-阿里云-aliyun
* 2-华为云-huaweicloud
*/
private String channelCode;
/**
* 下载url
*/
private String downloadSignUrl;
/**
* 文件名称
*/
private String fileName;
}

View File

@ -31,4 +31,8 @@ public class GetObjectMetaRequest {
* 唯一标识 * 唯一标识
*/ */
private String id; private String id;
/**
* 文件对象key
*/
private String fileKey;
} }

View File

@ -0,0 +1,64 @@
package cn.axzo.oss.manager.api.dto.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author: xudawei
* @date: 2024-03-12
* @description: 授权给第三方下载
**/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FetchUploadSignUrlToPublishDto {
/**
* appCode
*/
private String appCode;
/**
* bizScene,对应目录
*/
private String bizScene;
/**
* serviceName
*/
private String serviceName;
/**
* 1-阿里云-aliyun
* 2-华为云-huaweicloud
*/
private Integer channelType;
/**
* 桶名称
*/
private String bucketName;
/**
* 文件名称
*/
private String fileName;
/**
* 类型
*/
private String contentType = "multipart/form-data";
/**
* 过期时间
*/
private Long expiration;
/**
* 是否带上文件名称
*/
private Boolean hasFileName = true;
/**
* 桶key
*/
private String bucketKey;
}

View File

@ -0,0 +1,38 @@
package cn.axzo.oss.manager.api.dto.request;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author: xudawei
* @date: 2024-07-16
* @description: 元数据
**/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class GetObjectMetaDto {
/**
* 桶名称
*/
private String bucketName;
/**
* 文件key
*/
private String key;
/**
* 文件url
*/
private String url;
/**
* 唯一标识
*/
private String id;
/**
* 文件对象key
*/
private String fileKey;
}

View File

@ -34,6 +34,8 @@ public class SignUrlDownloadDto {
*/ */
private String bizScene; private String bizScene;
private String appCode;
/** /**
* 图片样式比如x-oss-process=image/auto-orient,1/resize,p_50/quality,q_30 * 图片样式比如x-oss-process=image/auto-orient,1/resize,p_50/quality,q_30
*/ */
@ -43,4 +45,9 @@ public class SignUrlDownloadDto {
*/ */
private Boolean hasFileName = true; private Boolean hasFileName = true;
/**
* 过期时间
*/
private Long expiration;
} }

View File

@ -62,4 +62,9 @@ public class SignUrlUploadDto {
* 是否带上文件名称 * 是否带上文件名称
*/ */
private Boolean hasFileName = true; private Boolean hasFileName = true;
/**
* 桶key
*/
private String bucketKey;
} }

View File

@ -6,6 +6,7 @@ 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;
import cn.axzo.oss.manager.api.dto.request.GetObjectMetaDto;
import cn.axzo.oss.manager.api.dto.request.MultipartUploadCompleteDto; 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.MultipartUploadDto;
import cn.axzo.oss.manager.api.dto.request.MultipartUploadFileDto; import cn.axzo.oss.manager.api.dto.request.MultipartUploadFileDto;
@ -26,6 +27,7 @@ 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 cn.hutool.core.lang.Pair;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.util.List; import java.util.List;
@ -105,4 +107,14 @@ public interface FileService {
* 获取桶基础与配置 * 获取桶基础与配置
*/ */
Pair<AppChannelBucket, FileUploadConfig> channelBucketAndConfig(String appCode, String bizScene, Integer channelType); Pair<AppChannelBucket, FileUploadConfig> channelBucketAndConfig(String appCode, String bizScene, Integer channelType);
/**
* 文件元数据信息
*/
ManaGetObjectMetaResponse getObjectMeta(@RequestBody GetObjectMetaDto dto);
/**
* 授权给第三方下载
*/
List<SignUrlDownloadResponse> signUrlDownloadNoFile(SignUrlDownloadDto dto);
} }

View File

@ -1,5 +1,6 @@
package cn.axzo.oss.service.impl; package cn.axzo.oss.service.impl;
import cn.axzo.core.utils.converter.BeanConverter;
import cn.axzo.framework.auth.domain.ContextInfo; import cn.axzo.framework.auth.domain.ContextInfo;
import cn.axzo.log.platform.client.LogPlatClient; import cn.axzo.log.platform.client.LogPlatClient;
import cn.axzo.log.platform.client.model.OperateLogReq; import cn.axzo.log.platform.client.model.OperateLogReq;
@ -33,6 +34,7 @@ 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.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;
import cn.axzo.oss.manager.api.dto.request.GetObjectMetaDto;
import cn.axzo.oss.manager.api.dto.request.MultipartUploadCompleteDto; 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.MultipartUploadDto;
import cn.axzo.oss.manager.api.dto.request.MultipartUploadFileDto; import cn.axzo.oss.manager.api.dto.request.MultipartUploadFileDto;
@ -54,6 +56,10 @@ 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.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.axzo.oss.service.metafile.WithFileFactory;
import cn.axzo.oss.service.metafile.WithFileService;
import cn.azxo.framework.common.model.CommonResponse;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Pair; import cn.hutool.core.lang.Pair;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@ -66,6 +72,7 @@ import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.IOException; import java.io.IOException;
@ -134,8 +141,8 @@ public class FileServiceImpl implements FileService {
@Value("${sign.url.download.expire.second:2000}") @Value("${sign.url.download.expire.second:2000}")
private Long SIGN_URL_DOWNLOAD_EXPIRE_SECOND; private Long SIGN_URL_DOWNLOAD_EXPIRE_SECOND;
@Value("${sign.url.upload.expire.second:2000}") @Autowired
private Long SIGN_URL_UPLOAD_EXPIRE_SECOND; private WithFileFactory withFileFactory;
/** /**
* 删除文件 * 删除文件
@ -869,7 +876,7 @@ public class FileServiceImpl implements FileService {
List<SignUrlDownloadResponse> httpUrlSignResList = this.buildHttpUrlSignResponse(dto); List<SignUrlDownloadResponse> httpUrlSignResList = this.buildHttpUrlSignResponse(dto);
//3 构建fileKey入参对象集合 //3 构建fileKey入参对象集合
List<SignUrlDownloadResponse> fileKeyResList = this.buildFileKeyResponse(dto.getFileKeys(), dto.getBizScene(), dto.getStyle(), dto.getHasFileName()); List<SignUrlDownloadResponse> fileKeyResList = this.buildFileKeyResponse(dto.getFileKeys(), dto.getBizScene(), dto.getStyle(), dto.getHasFileName(), dto.getExpiration());
//4 1/2/3集合累加 //4 1/2/3集合累加
httpUrlResList.addAll(fileKeyResList); httpUrlResList.addAll(fileKeyResList);
httpUrlResList.addAll(httpUrlSignResList); httpUrlResList.addAll(httpUrlSignResList);
@ -880,7 +887,7 @@ public class FileServiceImpl implements FileService {
/** /**
* 构建fileKey(非http的入参)的返回对象 * 构建fileKey(非http的入参)的返回对象
*/ */
private List<SignUrlDownloadResponse> buildFileKeyResponse(List<String> fileKeys, String bizScene, String style, boolean hasFileName) { private List<SignUrlDownloadResponse> buildFileKeyResponse(List<String> fileKeys, String bizScene, String style, boolean hasFileName, Long expiration) {
if (CollectionUtil.isEmpty(fileKeys)) { if (CollectionUtil.isEmpty(fileKeys)) {
return Lists.newArrayList(); return Lists.newArrayList();
} }
@ -889,9 +896,13 @@ public class FileServiceImpl implements FileService {
return Lists.newArrayList(); return Lists.newArrayList();
} }
List<SignUrlDownloadResponse> responseList = Lists.newArrayList();
List<File> fileList = fileDao.getByFileUuids(fileKeyList); List<File> fileList = fileDao.getByFileUuids(fileKeyList);
//获取不在dbFile中但是在默认axzo-obs-private中的key
responseList.addAll(fetchNoFileAndObsPrivate(fileKeyList, fileList));
if (CollectionUtils.isEmpty(fileList)) { if (CollectionUtils.isEmpty(fileList)) {
return Lists.newArrayList(); return responseList;
} }
//通过appChannelBucketNo集合获取文件渠道桶信息 //通过appChannelBucketNo集合获取文件渠道桶信息
@ -901,15 +912,39 @@ public class FileServiceImpl implements FileService {
List<FileBusinessScene> fileBusinessSceneList = fileBusinessSceneManager.queryByBucketNoAndScene(fileList.stream().map(File::getAppChannelBucketNo).collect(Collectors.toSet()), bizScene); 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)); Map<String, Long> bizSceneExpireMap = fileBusinessSceneList.stream().collect(Collectors.toMap(FileBusinessScene::getAppChannelBucketNo, FileBusinessScene::getDownloadExpiration, (x, y) -> y));
//构建返回集合 //构建返回集合
return this.buildFileKeyRespByFile(fileList, bucketTypeMap, bizSceneExpireMap, style, hasFileName); responseList.addAll(this.buildFileKeyRespByFile(fileList, bucketTypeMap, bizSceneExpireMap, style, hasFileName, expiration));
return responseList;
}
/**
* 获取不在dbFile中但是在默认axzo-obs-private中的key
*/
private List<SignUrlDownloadResponse> fetchNoFileAndObsPrivate(List<String> fileKeys, List<File> fileList) {
if (CollectionUtil.isEmpty(fileKeys)) {
return Lists.newArrayList();
}
List<String> fileDbList = Lists.newArrayList();
if (CollectionUtil.isNotEmpty(fileList)) {
fileDbList = fileList.stream().map(File::getFileUuid).collect(Collectors.toList());
}
List<String> subtractToList = CollUtil.subtractToList(fileKeys, fileDbList);
List<SignUrlDownloadResponse> collect = Lists.newArrayList();
if (CollectionUtil.isNotEmpty(subtractToList)) {
collect = subtractToList.stream().map(item -> this.buildSignUrlDownloadResponse(BucketTypeEnum.PRIVATE_BUCKET.getCode(),
"axzo-obs-private", item, ChannelTypeEnum.OBS.getChannelCode()
, item, null))
.collect(Collectors.toList());
}
return collect;
} }
/** /**
* 通过File对象构建返回集合 * 通过File对象构建返回集合
*/ */
private List<SignUrlDownloadResponse> buildFileKeyRespByFile(List<File> fileList,Map<String, String> bucketTypeMap, Map<String, Long> bizSceneExpireMap, String style, boolean hasFileName) { private List<SignUrlDownloadResponse> buildFileKeyRespByFile(List<File> fileList,Map<String, String> bucketTypeMap, Map<String, Long> bizSceneExpireMap, String style, boolean hasFileName, Long expiration) {
List<SignUrlDownloadResponse> responseList = fileList.stream().map(item -> { List<SignUrlDownloadResponse> responseList = fileList.stream().map(item -> {
Long expire = bizSceneExpireMap.get(item.getAppChannelBucketNo()); Long expire = Objects.nonNull(expiration) ? expiration : bizSceneExpireMap.get(item.getAppChannelBucketNo());
// bucket下的key // bucket下的key
String tgtFileKey = Utility.generateFileKey(item.getDirectory(), item.getFileUuid(), item.getFileFormat()); String tgtFileKey = Utility.generateFileKey(item.getDirectory(), item.getFileUuid(), item.getFileFormat());
String bucketType = StringUtils.isNotBlank(bucketTypeMap.get(item.getAppChannelBucketNo())) ? bucketTypeMap.get(item.getAppChannelBucketNo()) : BucketTypeEnum.PRIVATE_BUCKET.getCode(); String bucketType = StringUtils.isNotBlank(bucketTypeMap.get(item.getAppChannelBucketNo())) ? bucketTypeMap.get(item.getAppChannelBucketNo()) : BucketTypeEnum.PRIVATE_BUCKET.getCode();
@ -936,6 +971,36 @@ public class FileServiceImpl implements FileService {
return responseList; return responseList;
} }
/**
* 构建临时授权下载返回对象
* @param bucketType 公有桶/私有桶
* @param bucketName 桶名称
* @param tgtFileKey 桶key
* @param channelCode aliyun/huaweicloud
* @param fileUuid 文件标识
* @param expire 过期时间
* @return 临时授权下载返回对象
*/
private SignUrlDownloadResponse buildSignUrlDownloadResponse(String bucketType, String bucketName, String tgtFileKey, String channelCode, String fileUuid, Long expire) {
switch (BucketTypeEnum.getByCode(bucketType)) {
case PUBLIC_BUCKET://公有桶 - 永久链接例如 http://xxx.png
String url = this.fileManager.fetchDownloadUrl(bucketName, tgtFileKey, channelCode);//item.getBucketName() item.getChannelCode()
return SignUrlDownloadResponse.builder()
.signUrl(this.fileManager.buildPublicXImageProcess(url, null))
.fileKey(fileUuid)//item.getFileUuid()
.build();
case PRIVATE_BUCKET://私有桶 - 临时授权链接 例如 http://xxx.png?Expire=a&AccessKeyId=b&Signature=c&repsonse-content-disposition=d
String signUrl = this.fileManager.signUrlDownload(bucketName, tgtFileKey, Objects.nonNull(expire) ? expire : SIGN_URL_DOWNLOAD_EXPIRE_SECOND , channelCode, null, null, false);
return SignUrlDownloadResponse.builder()
.signUrl(UrlUtil.httpToHttps(signUrl))
.fileKey(fileUuid)
.build();
default:
BizException.error(CodeEnum.CHANNEL_TYPE_NOT_EXIST);
}
return SignUrlDownloadResponse.builder().build();
}
/** /**
* 构建http链接(非fileKey入参)返回对象 * 构建http链接(非fileKey入参)返回对象
*/ */
@ -970,7 +1035,7 @@ public class FileServiceImpl implements FileService {
if (CollectionUtil.isEmpty(map)) { if (CollectionUtil.isEmpty(map)) {
return httpUrlList.stream().map(item -> SignUrlDownloadResponse.builder().fileKey(item).signUrl(item).build()).collect(Collectors.toList()); 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, dto.getStyle(), dto.getHasFileName()); List<SignUrlDownloadResponse> responseList = this.buildFileKeyResponse(Lists.newArrayList(map.values()), null, dto.getStyle(), dto.getHasFileName(), dto.getExpiration());
if (CollectionUtil.isEmpty(responseList)) { if (CollectionUtil.isEmpty(responseList)) {
return httpUrlList.stream().map(item -> SignUrlDownloadResponse.builder().fileKey(item).signUrl(item).build()).collect(Collectors.toList()); return httpUrlList.stream().map(item -> SignUrlDownloadResponse.builder().fileKey(item).signUrl(item).build()).collect(Collectors.toList());
} }
@ -999,12 +1064,13 @@ public class FileServiceImpl implements FileService {
* 从链接中提取fileKey比如如下链接获取fileKey:b4148fbee6954c2fa3139471f18a2dcd * 从链接中提取fileKey比如如下链接获取fileKey:b4148fbee6954c2fa3139471f18a2dcd
* https://xx/identity/b4148fbee6954c2fa3139471f18a2dcd.jpg?AccessKeyId=xx&Expires=xx&response-content-disposition=xx&Signature=xx * https://xx/identity/b4148fbee6954c2fa3139471f18a2dcd.jpg?AccessKeyId=xx&Expires=xx&response-content-disposition=xx&Signature=xx
*/ */
private String signUrlToFileKey(String signUrl) { public static String signUrlToFileKey(String signUrl) {
if (StringUtils.isBlank(signUrl)) { if (StringUtils.isBlank(signUrl)) {
return StringUtils.EMPTY; return StringUtils.EMPTY;
} }
if (signUrl.contains("/") && signUrl.contains("?")) { if (signUrl.contains("/") && signUrl.contains("?")) {
String fileName = signUrl.substring(signUrl.lastIndexOf("/") + 1, signUrl.indexOf("?")); signUrl = signUrl.split("\\?")[0];
String fileName = signUrl.substring(signUrl.lastIndexOf("/") + 1);
if (fileName.contains(".")) { if (fileName.contains(".")) {
return fileName.substring(0, fileName.indexOf(".")); return fileName.substring(0, fileName.indexOf("."));
} }
@ -1065,87 +1131,12 @@ public class FileServiceImpl implements FileService {
//操作日志记录 //操作日志记录
operateLog(dto.toString(), dto.getServiceName(), FILE_UPLOAD_CODE, FILE_UPLOAD_NAME, liteSaasContext); operateLog(dto.toString(), dto.getServiceName(), FILE_UPLOAD_CODE, FILE_UPLOAD_NAME, liteSaasContext);
//3 保存File对象 //3 保存File对象
SignUrlUploadResponse response = this.signUrlSaveFile(dto, fileUploadConfig, scene, appChannelBucket); WithFileService withFileService = withFileFactory.getFileService(dto.getBizScene());
SignUrlUploadResponse response = withFileService.saveFile(dto, fileUploadConfig, scene, appChannelBucket);
log.info("signUrl upload dto = {}, times:{}", JsonUtil.obj2Str(dto), System.currentTimeMillis() - start); log.info("signUrl upload dto = {}, times:{}", JsonUtil.obj2Str(dto), System.currentTimeMillis() - start);
return response; return response;
} }
/**
*
* @param dto
* @param fileUploadConfig
* @return
*/
private SignUrlUploadResponse signUrlSaveFile(SignUrlUploadDto dto, FileUploadConfig fileUploadConfig, FileBusinessScene scene, AppChannelBucket appChannelBucket) {
String uuid = Utility.getUUID();
int lastIndexOf = dto.getFileName().lastIndexOf(FileClassEnum.DOT.type);
BizException
.error(lastIndexOf != CommonConstants.NOT_FOUND_INDEX_OF, CodeEnum.NOT_FILE_FORMAT);
// 是否包含指定格式
String fileFormat = dto.getFileName().substring(lastIndexOf + CommonConstants.ONE).toLowerCase();
// 文件格式判断
String[] formats = fileUploadConfig.getFileFormat().split(FileClassEnum.COMMA.type);
// 是否包含指定格式
BizException.error(Arrays.asList(formats).contains(fileFormat), CodeEnum.FILE_FORMAT_NOT_SUPPORTED);
// 生成上传文件的唯一key
String tgtFileKey = Utility.generateFileKey(fileUploadConfig.getDirectory(), uuid, fileFormat);
// 失效时间
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()
, Objects.isNull(dto.getHasFileName()) ? true: dto.getHasFileName() );
//2 保存File对象
this.saveOssFile(fileUploadConfig, dto.getFileName(), fileFormat, uuid,
signUrlUpload.getDownloadSignUrl(), Utility.getMd5(signUrlUpload.getDownloadSignUrl()), expiration);
return SignUrlUploadResponse.builder()
.signUrl(UrlUtil.httpToHttps(signUrlUpload.getSignUrl()))
.fileKey(uuid)
.contentType(signUrlUpload.getContentType())
.host(signUrlUpload.getHost())
.channelCode(signUrlUpload.getChannelCode())
.downloadSignUrl(UrlUtil.httpToHttps(signUrlUpload.getDownloadSignUrl()))
.fileName(dto.getFileName())
.build();
}
/**
* 临时授权失效时间
* 优先从业务入参取值业务入参失效时间为空则从oss配置中取失效时间
*/
private Long buildExpiration(SignUrlUploadDto dto, FileBusinessScene scene) {
if (Objects.nonNull(dto) && Objects.nonNull(dto.getExpiration())) {
return dto.getExpiration();
}
return scene.getUploadExpiration();
}
/**
* 授权给第三方下载获取文件上传配置
*/
private FileUploadConfig signUrlBuildUploadConfig(SignUrlUploadDto dto) {
FileUploadConfig fileUploadConfig = new FileUploadConfig();
if (Objects.nonNull(dto.getChannelType()) && StringUtils.isNoneBlank(dto.getBucketName()) && StringUtils.isNoneBlank(dto.getBizScene())) {
AppChannelBucket appChannelBucket = appChannelBucketManager.getByAppCodeChannelCodeBucket(dto.getAppCode(), dto.getChannelType(), dto.getBucketName());
// 通过渠道桶编码获取到具体文件业务场景
FileBusinessScene scene = fileBusinessSceneManager
.getByBucketNoAndScene(appChannelBucket.getAppChannelBucketNo(), dto.getBizScene());
// 通过渠道码和桶名称获取指定上传配置
fileUploadConfig = fileUploadConfigManager
.getByUploadConfig(scene.getAppChannelBucketNo(), scene.getDirectory());
} else {
fileUploadConfig = getFileUploadConfig(dto.getAppCode(), dto.getBizScene(), dto.getChannelType());
}
BizException.isEmpty(Objects.nonNull(fileUploadConfig) || StringUtils.isNotBlank(fileUploadConfig.getAppChannelBucketNo()), CodeEnum.NO_UPLOAD_CONFIG);
return fileUploadConfig;
}
/** /**
* 授权给第三方-下载 * 授权给第三方-下载
@ -1159,6 +1150,59 @@ public class FileServiceImpl implements FileService {
fileManager.deleteFile(file.getBucketName(), tgtFileKey,file.getChannelCode()); fileManager.deleteFile(file.getBucketName(), tgtFileKey,file.getChannelCode());
fileDao.deleteFile(dto.getFileKey()); fileDao.deleteFile(dto.getFileKey());
} }
/**
* 文件元数据信息
*/
@Override
public ManaGetObjectMetaResponse getObjectMeta(@RequestBody GetObjectMetaDto dto) {
if (!org.springframework.util.StringUtils.hasText(dto.getUrl()) && !org.springframework.util.StringUtils.hasText(dto.getBucketName())
&& !org.springframework.util.StringUtils.hasText(dto.getKey()) && !org.springframework.util.StringUtils.hasText(dto.getFileKey())) {
throw new BizException(CodeEnum.URL_BUCKET_NAME_KEY_ALL_EMPTY);
}
String bucketName = StringUtils.EMPTY;
String bucketKey = StringUtils.EMPTY;
String channelCode = StringUtils.EMPTY;
String url = StringUtils.EMPTY;
if (org.springframework.util.StringUtils.hasText(dto.getFileKey())) {
File byFileUuid = this.fileDao.getByFileUuid(dto.getFileKey());
if (Objects.nonNull(byFileUuid)) {
bucketName = byFileUuid.getBucketName();
bucketKey = Utility.generateFileKey(byFileUuid.getDirectory(), byFileUuid.getFileUuid(), byFileUuid.getFileFormat());
channelCode = byFileUuid.getChannelCode();
url = byFileUuid.getFileUrl();
}
}
if (StringUtils.isBlank(bucketName) && StringUtils.isBlank(bucketKey)) {
bucketName = UrlUtil.fetchBucketName(dto.getBucketName(), dto.getUrl());
bucketKey = UrlUtil.fetchBucketKey(dto.getKey(), dto.getUrl());
channelCode = this.swtchChannelCode(dto.getUrl());
url = dto.getUrl();
}
ManaGetObjectMetaResponse response = this.getObjectMeta(bucketName
, bucketKey, url
, channelCode);
return BeanConverter.convert(response, ManaGetObjectMetaResponse.class);
}
/**
* 决定渠道
*/
private String swtchChannelCode(String url) {
if (!org.springframework.util.StringUtils.hasText(url)) {
return "";
}
if (url.toLowerCase().contains("aliyun")) {
return ChannelTypeEnum.OSS.getChannelCode();
}
if (url.toLowerCase().contains("huaweicloud")) {
return ChannelTypeEnum.OBS.getChannelCode();
}
return url;
}
/** /**
* 元数据 * 元数据
*/ */
@ -1172,4 +1216,25 @@ public class FileServiceImpl implements FileService {
return response; return response;
} }
/**
* 授权给第三方下载
*/
@Override
public List<SignUrlDownloadResponse> signUrlDownloadNoFile(SignUrlDownloadDto dto) {
// 通过appcode获取文件渠道桶信息
AppChannelBucket appChannelBucket = appChannelBucketManager.getByAppCode(dto.getAppCode(), null);
// 通过渠道桶编码获取到具体文件业务场景
FileBusinessScene scene = fileBusinessSceneManager
.getByBucketNoAndScene(appChannelBucket.getAppChannelBucketNo(), dto.getBizScene());
Long expiration = Objects.nonNull(dto.getExpiration()) ? dto.getExpiration() : scene.getDownloadExpiration();
return dto.getFileKeys().stream().map(item ->{
//构建返回集合
return this.buildSignUrlDownloadResponse(appChannelBucket.getBucketType(), appChannelBucket.getBucketName()
, item, appChannelBucket.getChannelCode(), item, expiration);
}).collect(Collectors.toList());
}
} }

View File

@ -0,0 +1,54 @@
package cn.axzo.oss.service.metafile;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* @Author xudawei@axzo.cn
* @Description file工厂
* @Date 2024/06/25
**/
@Service
@RefreshScope
public class WithFileFactory {
private Map<String, WithFileService> serviceMap = Maps.newConcurrentMap();
private static final String DEFAULT_SERVICE = "handleFileService";
@Value("${ignore.file.biz.scene:attendance-snap,attendance1=ignoreFileService}")
private String ignoreFileBizScene;
public WithFileFactory(List<WithFileService> serviceList) {
serviceList.stream().forEach(item -> {
serviceMap.put(item.fetchServiceName(), item);
});
}
public WithFileService getFileService(String serviceKey) {
String serviceName = this.buildServiceName(serviceKey);
return Objects.nonNull(serviceMap.get(serviceName)) ? serviceMap.get(serviceName) : serviceMap.get(DEFAULT_SERVICE);
}
private String buildServiceName(String serviceKey) {
String[] strs = ignoreFileBizScene.split(";");
for (String str : strs) {
if (StringUtils.hasText(str) && str.contains(serviceKey)) {
return str.split("=")[1];
}
}
return "";
}
public void putService(String serviceName, WithFileService withFileService) {
serviceMap.put(serviceName, withFileService);
}
}

View File

@ -0,0 +1,61 @@
package cn.axzo.oss.service.metafile;
import cn.axzo.oss.common.constans.CommonConstants;
import cn.axzo.oss.common.enums.CodeEnum;
import cn.axzo.oss.common.enums.FileClassEnum;
import cn.axzo.oss.common.exception.BizException;
import cn.axzo.oss.dal.entity.AppChannelBucket;
import cn.axzo.oss.dal.entity.FileBusinessScene;
import cn.axzo.oss.dal.entity.FileUploadConfig;
import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto;
import cn.axzo.oss.manager.api.dto.response.SignUrlUploadResponse;
import java.util.Arrays;
import java.util.Objects;
/**
* @Author xudawei@axzo.cn
* @Description file相关
* @Date 2024/06/25
**/
public abstract class WithFileService {
public SignUrlUploadResponse saveFile(SignUrlUploadDto dto, FileUploadConfig fileUploadConfig, FileBusinessScene scene, AppChannelBucket appChannelBucket) {
String fileFormat = this.check(dto, fileUploadConfig);
return this.doSaveFile(dto, fileUploadConfig, scene, appChannelBucket, fileFormat);
}
public abstract SignUrlUploadResponse doSaveFile(SignUrlUploadDto dto, FileUploadConfig fileUploadConfig, FileBusinessScene scene, AppChannelBucket appChannelBucket, String fileFormat);
public abstract String fetchServiceName();
/**
* 校验
*/
public String check(SignUrlUploadDto dto, FileUploadConfig fileUploadConfig) {
int lastIndexOf = dto.getFileName().lastIndexOf(FileClassEnum.DOT.type);
BizException
.error(lastIndexOf != CommonConstants.NOT_FOUND_INDEX_OF, CodeEnum.NOT_FILE_FORMAT);
// 是否包含指定格式
String fileFormat = dto.getFileName().substring(lastIndexOf + CommonConstants.ONE).toLowerCase();
// 文件格式判断
String[] formats = fileUploadConfig.getFileFormat().split(FileClassEnum.COMMA.type);
// 是否包含指定格式
BizException.error(Arrays.asList(formats).contains(fileFormat), CodeEnum.FILE_FORMAT_NOT_SUPPORTED);
return fileFormat;
}
/**
* 临时授权失效时间
* 优先从业务入参取值业务入参失效时间为空则从oss配置中取失效时间
*/
public Long buildExpiration(SignUrlUploadDto dto, FileBusinessScene scene) {
if (Objects.nonNull(dto) && Objects.nonNull(dto.getExpiration())) {
return dto.getExpiration();
}
return scene.getUploadExpiration();
}
}

View File

@ -0,0 +1,96 @@
package cn.axzo.oss.service.metafile.impl;
import cn.axzo.oss.common.enums.FileStatusEnum;
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.FileBusinessScene;
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.SignUrlUploadDto;
import cn.axzo.oss.manager.api.dto.response.SignUrlUploadResponse;
import cn.axzo.oss.manager.api.vo.SignUrlUploadVo;
import cn.axzo.oss.service.metafile.WithFileService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import java.util.Objects;
/**
* @Author xudawei@axzo.cn
* @Description file操作
* @Date 2024/06/25
**/
@Service("handleFileService")
@RefreshScope
public class HandleFileService extends WithFileService{
@Autowired
private FileManager fileManager;
@Autowired
private FileDao fileDao;
public SignUrlUploadResponse doSaveFile(SignUrlUploadDto dto, FileUploadConfig fileUploadConfig, FileBusinessScene scene, AppChannelBucket appChannelBucket, String fileFormat) {
String uuid = Utility.getUUID();
// 生成上传文件的唯一key
String tgtFileKey = Utility.generateFileKey(fileUploadConfig.getDirectory(), uuid, fileFormat);
// 失效时间
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()
, Objects.isNull(dto.getHasFileName()) ? true: dto.getHasFileName() );
//2 保存File对象
this.saveOssFile(fileUploadConfig, dto.getFileName(), fileFormat, uuid,
signUrlUpload.getDownloadSignUrl(), Utility.getMd5(signUrlUpload.getDownloadSignUrl()), expiration);
return SignUrlUploadResponse.builder()
.signUrl(UrlUtil.httpToHttps(signUrlUpload.getSignUrl()))
.fileKey(uuid)
.contentType(signUrlUpload.getContentType())
.host(signUrlUpload.getHost())
.channelCode(signUrlUpload.getChannelCode())
.downloadSignUrl(UrlUtil.httpToHttps(signUrlUpload.getDownloadSignUrl()))
.fileName(dto.getFileName())
.build();
}
@Override
public String fetchServiceName() {
return "handleFileService";
}
private File saveOssFile(FileUploadConfig fileUploadConfig, String fileName, String fileConform, String uuid,
String fileUrl, String fileMd5, Long expiration) {
File ossFile = new File();
ossFile.setAppChannelBucketNo(fileUploadConfig.getAppChannelBucketNo());
ossFile.setAppCode(fileUploadConfig.getAppCode());
ossFile.setChannelCode(fileUploadConfig.getChannelCode());
ossFile.setBucketName(fileUploadConfig.getBucketName());
ossFile.setDirectory(fileUploadConfig.getDirectory());
ossFile.setStatus(FileStatusEnum.STATUS_UPLOAD_FAIL.getCode());
ossFile.setStorageUnit(fileUploadConfig.getStorageUnit());
ossFile.setStorageSize(fileUploadConfig.getStorageSize());
ossFile.setFileFormat(fileConform);
ossFile.setFileUuid(uuid);
ossFile.setFileUrl(fileUrl);
ossFile.setUrlMd5(Utility.getMd5(fileUrl));
ossFile.setStatus(FileStatusEnum.STATUS_UPLOAD_SUCCESS.getCode());
ossFile.setFileName(fileName);
ossFile.setFileMd5(fileMd5);
fileDao.save(ossFile);
return ossFile;
}
// @Override
// public void afterPropertiesSet() throws Exception {
// withFileFactory.putService("handleFileService", this);
// }
}

View File

@ -0,0 +1,62 @@
package cn.axzo.oss.service.metafile.impl;
import cn.axzo.oss.common.utils.UrlUtil;
import cn.axzo.oss.dal.entity.AppChannelBucket;
import cn.axzo.oss.dal.entity.FileBusinessScene;
import cn.axzo.oss.dal.entity.FileUploadConfig;
import cn.axzo.oss.manager.api.FileManager;
import cn.axzo.oss.manager.api.dto.request.SignUrlUploadDto;
import cn.axzo.oss.manager.api.dto.response.SignUrlUploadResponse;
import cn.axzo.oss.manager.api.vo.SignUrlUploadVo;
import cn.axzo.oss.service.metafile.WithFileService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import java.util.Objects;
/**
* @Author xudawei@axzo.cn
* @Description 忽略file操作
* @Date 2024/06/25
**/
@Service("ignoreFileService")
@RefreshScope
public class IgnoreFileService extends WithFileService{
@Autowired
private FileManager fileManager;
public SignUrlUploadResponse doSaveFile(SignUrlUploadDto dto, FileUploadConfig fileUploadConfig, FileBusinessScene scene, AppChannelBucket appChannelBucket,String fileFormat) {
// 失效时间
Long expiration = this.buildExpiration(dto, scene);
//1 调用阿里云/华为云 获取临时授权signUrl
SignUrlUploadVo signUrlUpload = this.fileManager.signUrlUpload(fileUploadConfig.getBucketName(), dto.getBucketKey(), dto.getFileName(),expiration
, fileUploadConfig.getChannelCode()
, StringUtils.isNotBlank(dto.getContentType()) ? dto.getContentType() : "multipart/form-data", appChannelBucket.getBucketType()
, Objects.isNull(dto.getHasFileName()) ? true: dto.getHasFileName() );
return SignUrlUploadResponse.builder()
.signUrl(UrlUtil.httpToHttps(signUrlUpload.getSignUrl()))
.fileKey(dto.getBucketKey())
.contentType(signUrlUpload.getContentType())
.host(signUrlUpload.getHost())
.channelCode(signUrlUpload.getChannelCode())
.downloadSignUrl(UrlUtil.httpToHttps(signUrlUpload.getDownloadSignUrl()))
.fileName(dto.getFileName())
.build();
}
@Override
public String fetchServiceName() {
return "ignoreFileService";
}
// @Override
// public void afterPropertiesSet() throws Exception {
// withFileFactory.putService("ignoreFileService", this);
// }
}