|
@@ -7,13 +7,19 @@ import com.backendsys.entity.System.SysFile.SysFileCategoryDTO;
|
|
|
import com.backendsys.entity.System.SysFile.SysFileDTO;
|
|
|
import com.backendsys.entity.Tencent.TencentCos.MultipartUploadRespDTO;
|
|
|
import com.backendsys.exception.CustException;
|
|
|
+import com.backendsys.modules.common.config.security.utils.HttpRequestUtil;
|
|
|
+import com.backendsys.modules.sdk.tencent.cos.entity.Progress;
|
|
|
import com.backendsys.modules.sdk.tencent.cos.service.TencentCosService;
|
|
|
import com.backendsys.modules.sdk.tencent.cos.utils.TencentCosUtil;
|
|
|
+import com.backendsys.modules.sse.utils.SseUtil;
|
|
|
import com.backendsys.utils.CommonUtil;
|
|
|
import com.qcloud.cos.COSClient;
|
|
|
import com.qcloud.cos.ClientConfig;
|
|
|
import com.qcloud.cos.auth.BasicCOSCredentials;
|
|
|
import com.qcloud.cos.auth.COSCredentials;
|
|
|
+import com.qcloud.cos.http.HttpMethodName;
|
|
|
+import com.qcloud.cos.model.GeneratePresignedUrlRequest;
|
|
|
+import com.qcloud.cos.model.ObjectMetadata;
|
|
|
import com.qcloud.cos.model.PutObjectRequest;
|
|
|
import com.qcloud.cos.model.UploadResult;
|
|
|
import com.qcloud.cos.region.Region;
|
|
@@ -23,22 +29,30 @@ import com.qcloud.cos.transfer.TransferProgress;
|
|
|
import com.qcloud.cos.transfer.Upload;
|
|
|
import com.qcloud.cos.utils.IOUtils;
|
|
|
import net.coobird.thumbnailator.Thumbnails;
|
|
|
+import org.joda.time.DateTime;
|
|
|
+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;
|
|
|
|
|
|
-import java.io.File;
|
|
|
-import java.io.FileOutputStream;
|
|
|
-import java.io.IOException;
|
|
|
-import java.io.InputStream;
|
|
|
+import java.io.*;
|
|
|
+import java.net.URL;
|
|
|
import java.util.Arrays;
|
|
|
+import java.util.Date;
|
|
|
import java.util.List;
|
|
|
import java.util.concurrent.ExecutorService;
|
|
|
import java.util.concurrent.Executors;
|
|
|
|
|
|
+import static org.aspectj.weaver.tools.cache.SimpleCacheFactory.path;
|
|
|
+
|
|
|
@Service
|
|
|
public class TencentCosServiceImpl implements TencentCosService {
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private HttpRequestUtil httpRequestUtil;
|
|
|
+ @Autowired
|
|
|
+ private SseUtil sseUtil;
|
|
|
+
|
|
|
@Value("${tencent.cos.max-size}")
|
|
|
private long MAX_SIZE;
|
|
|
@Value("${tencent.cos.region}")
|
|
@@ -61,40 +75,66 @@ public class TencentCosServiceImpl implements TencentCosService {
|
|
|
return cosClient;
|
|
|
}
|
|
|
|
|
|
+ // [腾讯云COS][高级接口] 获取进度函数
|
|
|
+ private void showTransferProgress(String md5, Transfer transfer) {
|
|
|
+ // 这里的 Transfer 是异步上传结果 Upload 的父类
|
|
|
+ System.out.println(transfer.getDescription());
|
|
|
+ // 查询上传是否已经完成
|
|
|
+ while (transfer.isDone() == false) {
|
|
|
+
|
|
|
+ // 每秒获取一次进度
|
|
|
+ try { Thread.sleep(1000); } catch (InterruptedException e) { return; }
|
|
|
+
|
|
|
+ TransferProgress transferProgress = transfer.getProgress();
|
|
|
+ long current = transferProgress.getBytesTransferred();
|
|
|
+ long total = transferProgress.getTotalBytesToTransfer();
|
|
|
+ double percent = transferProgress.getPercentTransferred();
|
|
|
+ System.out.printf("upload Progress: [%d / %d] = %.02f%%\n", current, total, percent);
|
|
|
+
|
|
|
+ Progress progress = new Progress();
|
|
|
+ progress.setCurrent(current);
|
|
|
+ progress.setTotal(total);
|
|
|
+ progress.setPercent(percent);
|
|
|
+ sseUtil.send(httpRequestUtil.getUserId(), progress);
|
|
|
+
|
|
|
+ }
|
|
|
+ // 完成了 Completed,或者失败了 Failed
|
|
|
+ System.out.println(transfer.getState());
|
|
|
+ sseUtil.send(httpRequestUtil.getUserId(), transfer.getState());
|
|
|
+ }
|
|
|
+
|
|
|
// [腾讯云COS] 上传对象
|
|
|
@Override
|
|
|
- public UploadResult putObject(MultipartFile file, String object_key) {
|
|
|
+ public UploadResult putObject(MultipartFile multipartFile, String object_key) {
|
|
|
|
|
|
- if (file.isEmpty()) throw new CustException("file 上传文件不能为空");
|
|
|
+ if (multipartFile.isEmpty()) throw new CustException("file 上传文件不能为空");
|
|
|
|
|
|
COSClient cosClient = getClient();
|
|
|
try {
|
|
|
|
|
|
- InputStream inputStream = file.getInputStream();
|
|
|
-
|
|
|
- // 将文件内容写入临时文件
|
|
|
- String tempFilename = CommonUtil.generateFilename(null);
|
|
|
- File tempFile = File.createTempFile(tempFilename, null);
|
|
|
- try (FileOutputStream outputStream = new FileOutputStream(tempFile)) {
|
|
|
- IOUtils.copy(inputStream, outputStream);
|
|
|
- }
|
|
|
-
|
|
|
// 如果不传 object_key,则默认使用临时文件夹 (/temp) + MD5文件名
|
|
|
+ String md5 = DigestUtil.md5Hex(multipartFile.getInputStream());
|
|
|
if (StrUtil.isEmpty(object_key)) {
|
|
|
- String md5 = DigestUtil.md5Hex(file.getInputStream());
|
|
|
- String suffix = FileUtil.extName(file.getOriginalFilename()).toLowerCase();
|
|
|
+ String suffix = FileUtil.extName(multipartFile.getOriginalFilename()).toLowerCase();
|
|
|
String filename = md5 + "." + suffix;
|
|
|
object_key = "temp/" + filename;
|
|
|
}
|
|
|
|
|
|
+ URL url = generateUrl(object_key, 15);
|
|
|
+ System.out.println("url = " + url);
|
|
|
+
|
|
|
// 创建 PutObjectRequest 对象,PutObject 请求。(异步)
|
|
|
- PutObjectRequest putObjectRequest = new PutObjectRequest(BUCKET_NAME, object_key, tempFile);
|
|
|
-// cosClient.putObject(putObjectRequest); // 普通上传 (没有进度)
|
|
|
+ ObjectMetadata metadata = new ObjectMetadata();
|
|
|
+ metadata.setContentLength(multipartFile.getSize());
|
|
|
+ PutObjectRequest putObjectRequest = new PutObjectRequest(BUCKET_NAME, object_key, multipartFile.getInputStream(), metadata);
|
|
|
+
|
|
|
+ // 普通上传 (没有进度)
|
|
|
+// cosClient.putObject(putObjectRequest);
|
|
|
|
|
|
// 高级上传
|
|
|
TransferManager transferManager = TencentCosUtil.createTransferManager(cosClient);
|
|
|
Upload upload = transferManager.upload(putObjectRequest); // 返回一个异步结果Upload
|
|
|
- TencentCosUtil.showTransferProgress(upload); // 打印上传进度,直到上传结束
|
|
|
+ showTransferProgress(md5, upload); // 查询上传进度,直到上传结束
|
|
|
UploadResult uploadResult = upload.waitForUploadResult(); // 捕获可能出现的异常
|
|
|
return uploadResult;
|
|
|
|
|
@@ -106,34 +146,17 @@ public class TencentCosServiceImpl implements TencentCosService {
|
|
|
if (cosClient != null) cosClient.shutdown();
|
|
|
}
|
|
|
|
|
|
-//
|
|
|
-// MultipartUploadRespDTO resp = new MultipartUploadRespDTO();
|
|
|
-// try {
|
|
|
-//
|
|
|
-// String md5 = DigestUtil.md5Hex(file.getInputStream());
|
|
|
-// String suffix = FileUtil.extName(file.getOriginalFilename()).toLowerCase();
|
|
|
-// String filename = md5 + "." + suffix;
|
|
|
-// String filenameThumb = filename.replaceAll("." + suffix, "-thumb." + suffix);
|
|
|
-// String key = "temp/" + filename;
|
|
|
-// String keyThumb = "temp/" + filenameThumb;
|
|
|
-// String remotePath = accessibleDomain + "/" + key;
|
|
|
-// String remotePathThumb = accessibleDomain + "/" + keyThumb;
|
|
|
-//
|
|
|
// // 获得文件分类列表
|
|
|
// SysFileCategoryDTO categoryDTO = new SysFileCategoryDTO();
|
|
|
// List<SysFileCategoryDTO> categoryList = sysFileCategoryMapper.queryFileCategoryList(categoryDTO);
|
|
|
//
|
|
|
// // 获得图片分类的后缀 (待做),再进行以下判断
|
|
|
-//
|
|
|
// // 还有删除也要同时删除缩略图
|
|
|
-//
|
|
|
// // 还有大文件分片也要做缩略图
|
|
|
-//
|
|
|
// // 还有 视频要做截图生成
|
|
|
//
|
|
|
// boolean isImage = Arrays.asList("jpg", "jpeg", "png", "gif", "bmp", "tiff", "webp").contains(suffix.toLowerCase());
|
|
|
//
|
|
|
-//
|
|
|
// // 检查对象是否存在于存储桶中
|
|
|
// if (checkObjectExist(cosClient, key)) {
|
|
|
// // -- [COS] 对象存在时,直接返回路径 -------------------------------
|
|
@@ -170,42 +193,16 @@ public class TencentCosServiceImpl implements TencentCosService {
|
|
|
// tempFile.delete();
|
|
|
//
|
|
|
// }
|
|
|
-//
|
|
|
-// // -- [DB] 查询数据 ---------------------------------------------
|
|
|
-// SysFileDTO fileDetail = sysFileMapper.queryFileByKey(key);
|
|
|
-// // 如果表中没有数据,则添加数据
|
|
|
-// if (fileDetail == null) {
|
|
|
-// // -- [DB] 插入数据 -----------------------------------------
|
|
|
-// SysFileDTO fileDTO = new SysFileDTO();
|
|
|
-// fileDTO.setUser_id(httpRequestAspect.getUserId());
|
|
|
-// fileDTO.setName(filename);
|
|
|
-// fileDTO.setFile_key(key);
|
|
|
-// fileDTO.setFile_remote_path(remotePath);
|
|
|
-// if (isImage) {
|
|
|
-// fileDTO.setFile_remote_path_thumb(remotePathThumb);
|
|
|
-// }
|
|
|
-// fileDTO.setCategory_id(getCategoryIdBySuffix(suffix));
|
|
|
-// fileDTO.setSize(file.getSize());
|
|
|
-// fileDTO.setMd5(md5);
|
|
|
-// sysFileMapper.insertFile(fileDTO);
|
|
|
-// }
|
|
|
-// // -------------------------------------------------------------
|
|
|
-//
|
|
|
-// resp.setFilename(filename);
|
|
|
-// resp.setKey(key);
|
|
|
-// resp.setMd5(md5);
|
|
|
-// resp.setSize(file.getSize());
|
|
|
-// resp.setPath(remotePath);
|
|
|
-//
|
|
|
-// } catch (IOException e) {
|
|
|
-// throw new CustException(e.getMessage());
|
|
|
-// } finally {
|
|
|
-// if (cosClient != null) {
|
|
|
-// cosClient.shutdown();
|
|
|
-// }
|
|
|
-// }
|
|
|
-// return resp;
|
|
|
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public URL generateUrl(String object_key, Integer minutes) {
|
|
|
+ // 生成临时访问的URL (15分钟)
|
|
|
+ GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(BUCKET_NAME, object_key, HttpMethodName.GET);
|
|
|
+ Date expirationDate = new DateTime().plusMinutes(minutes).toDate();
|
|
|
+ request.setExpiration(expirationDate);
|
|
|
+ URL url = getClient().generatePresignedUrl(request);
|
|
|
+ return url;
|
|
|
+ }
|
|
|
}
|