|
@@ -1,5 +1,6 @@
|
|
|
package com.backendsys.modules.upload.service.impl;
|
|
|
|
|
|
+import cn.hutool.core.codec.Base64;
|
|
|
import cn.hutool.core.convert.Convert;
|
|
|
import cn.hutool.core.io.file.FileNameUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
@@ -11,10 +12,12 @@ import com.backendsys.modules.system.entity.SysCommon;
|
|
|
import com.backendsys.modules.system.service.SysCommonService;
|
|
|
import com.backendsys.modules.upload.dao.SysFileDao;
|
|
|
import com.backendsys.modules.upload.entity.SysFile;
|
|
|
+import com.backendsys.modules.upload.enums.StyleEnums;
|
|
|
import com.backendsys.modules.upload.service.SysFileMultipartService;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.qcloud.cos.model.*;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
@@ -29,19 +32,41 @@ import java.util.stream.Collectors;
|
|
|
@Service
|
|
|
public class SysFileMultipartServiceImpl implements SysFileMultipartService {
|
|
|
|
|
|
+ @Value("${tencent.cos.accessible-domain}")
|
|
|
+ private String ACCESSIBLE_DOMAIN;
|
|
|
@Autowired
|
|
|
private HttpRequestUtil httpRequestUtil;
|
|
|
@Autowired
|
|
|
private TencentCosService tencentCosService;
|
|
|
@Autowired
|
|
|
- private SysFileDao sysFileDao;
|
|
|
- @Autowired
|
|
|
private SysCommonService sysCommonService;
|
|
|
+ @Autowired
|
|
|
+ private SysFileDao sysFileDao;
|
|
|
|
|
|
|
|
|
- /*
|
|
|
- 查一下 upload_id 多久会过期
|
|
|
- */
|
|
|
+ // [方法] 设置缩略图 (参数)
|
|
|
+ // 不同的云环境 (target),缩略图配置也不一样
|
|
|
+ // -1:本地:
|
|
|
+ // 1:腾讯云: https://cloud.tencent.com/document/product/436/113295
|
|
|
+ // 2:阿里云:
|
|
|
+ // 3:抖音云: https://www.volcengine.com/docs/6349/153626
|
|
|
+ private SysFile setThumbUrl(SysFile sysFile, Integer width, Integer height, String backgroundColor) {
|
|
|
+ // 本地上传
|
|
|
+ if (sysFile.getTarget() == -1) {
|
|
|
+ sysFile.setUrl_thumb(sysFile.getUrl() + "?w=" + width + "&h=" + height);
|
|
|
+ }
|
|
|
+ // 腾讯云 (color值通过base64加密, #f8f8f8)
|
|
|
+ if (sysFile.getTarget() == 1) {
|
|
|
+ System.out.println("base64 encode: " + Base64.encode(backgroundColor));
|
|
|
+ sysFile.setUrl_thumb(sysFile.getUrl() + "?imageMogr2/thumbnail/" + width + "x" + height + "/pad/1/color/" + Base64.encode(backgroundColor));
|
|
|
+ }
|
|
|
+ // 抖音云
|
|
|
+ if (sysFile.getTarget() == 3) {
|
|
|
+ sysFile.setUrl_thumb(sysFile.getUrl() + "?x-tos-process=image/resize,w_" + width + ",h_" + height + ",m_pad,color_" + backgroundColor);
|
|
|
+ }
|
|
|
+ return sysFile;
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
// 1.初始化分块上传 (获得 upload_id, object_key)
|
|
|
@Override
|
|
@@ -107,6 +132,7 @@ public class SysFileMultipartServiceImpl implements SysFileMultipartService {
|
|
|
if (StrUtil.isEmpty(upload_id)) throw new CustException("upload_id 不能为空");
|
|
|
if (upload_chunk_index == null) throw new CustException("upload_chunk_index 不能为空");
|
|
|
|
|
|
+
|
|
|
// [Get] 获得初始化分块信息
|
|
|
SysFile sysFileEntity = sysFileDao.selectOne(new LambdaQueryWrapper<SysFile>().eq(SysFile::getUpload_id, upload_id));
|
|
|
if (sysFileEntity == null) throw new CustException("分块记录不存在");
|
|
@@ -120,16 +146,14 @@ public class SysFileMultipartServiceImpl implements SysFileMultipartService {
|
|
|
sysCommonList.stream().forEach(sysCommon -> {
|
|
|
if (sysCommon.getTag().equals("UPLOAD_TARGET")) UPLOAD_TARGET.set(Convert.toInt(sysCommon.getValue()));
|
|
|
});
|
|
|
-
|
|
|
System.out.println("[系统配置] 上传目标(-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云): " + UPLOAD_TARGET);
|
|
|
|
|
|
+
|
|
|
PartETag part_etag = null;
|
|
|
|
|
|
// target: 上传目标 (-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云)
|
|
|
if (UPLOAD_TARGET.get() == 1) {
|
|
|
UploadPartResult partResult = tencentCosService.uploadPart(multipartFile, upload_id, object_key, upload_chunk_index);
|
|
|
- System.out.println("partResult:");
|
|
|
- System.out.println(partResult);
|
|
|
part_etag = partResult.getPartETag();
|
|
|
}
|
|
|
|
|
@@ -137,7 +161,6 @@ public class SysFileMultipartServiceImpl implements SysFileMultipartService {
|
|
|
// PartListing partListing = listParts(upload_id, object_key);
|
|
|
// Integer partNumberMarker = partListing.getPartNumberMarker() + 1;
|
|
|
|
|
|
-
|
|
|
// [Update] 更新分块文件信息
|
|
|
sysFileEntity.setUpload_chunk_index(upload_chunk_index);
|
|
|
sysFileDao.updateById(sysFileEntity);
|
|
@@ -165,21 +188,58 @@ public class SysFileMultipartServiceImpl implements SysFileMultipartService {
|
|
|
throw new CustException("分块索引和分块数量不一致");
|
|
|
}
|
|
|
|
|
|
- // 查询分块集合 (etag)
|
|
|
- PartListing partListing = listParts(upload_id, sysFileEntity.getObject_key());
|
|
|
- List<PartSummary> partSummaryList = partListing.getParts();
|
|
|
- List<PartETag> etags = partSummaryList.stream()
|
|
|
- .map(partSummary -> new PartETag(partSummary.getPartNumber(), partSummary.getETag()))
|
|
|
- .collect(Collectors.toList());
|
|
|
|
|
|
- // 如果分块数量对不上,最好还是重新上传
|
|
|
- if (sysFileEntity.getUpload_chunk_count() != etags.size()) {
|
|
|
- throw new CustException("分块索引异常,请重新上传");
|
|
|
+ // 获得公共配置
|
|
|
+ List<SysCommon> sysCommonList = sysCommonService.getCommonByCategory("UPLOAD");
|
|
|
+ AtomicReference<Integer> UPLOAD_TARGET = new AtomicReference<>();
|
|
|
+ AtomicReference<Integer> UPLOAD_THUMB_SIZE = new AtomicReference<>();
|
|
|
+ sysCommonList.stream().forEach(sysCommon -> {
|
|
|
+ if (sysCommon.getTag().equals("UPLOAD_TARGET")) UPLOAD_TARGET.set(Convert.toInt(sysCommon.getValue()));
|
|
|
+ if (sysCommon.getTag().equals("UPLOAD_THUMB_SIZE")) UPLOAD_THUMB_SIZE.set(Convert.toInt(sysCommon.getValue()));
|
|
|
+ });
|
|
|
+ System.out.println("[系统配置] 上传目标(-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云): " + UPLOAD_TARGET);
|
|
|
+ System.out.println("[系统配置] 图片的缩略图宽高尺寸 (px): " + UPLOAD_THUMB_SIZE);
|
|
|
+
|
|
|
+
|
|
|
+ // target: 上传目标 (-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云)
|
|
|
+ if (UPLOAD_TARGET.get() == 1) {
|
|
|
+
|
|
|
+ // 查询分块集合 (etag)
|
|
|
+ PartListing partListing = listParts(upload_id, sysFileEntity.getObject_key());
|
|
|
+ List<PartSummary> partSummaryList = partListing.getParts();
|
|
|
+ List<PartETag> etags = partSummaryList.stream()
|
|
|
+ .map(partSummary -> new PartETag(partSummary.getPartNumber(), partSummary.getETag()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 如果分块数量对不上,最好还是重新上传
|
|
|
+ if (sysFileEntity.getUpload_chunk_count() != etags.size()) {
|
|
|
+ throw new CustException("分块索引异常,请重新上传");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 合并分块
|
|
|
+ CompleteMultipartUploadResult completeResult = tencentCosService.completeMultipartUpload(upload_id, sysFileEntity.getObject_key(), etags);
|
|
|
+ if (completeResult == null) throw new CustException("合并失败");
|
|
|
+
|
|
|
+ String url = ACCESSIBLE_DOMAIN + "/" + completeResult.getKey();
|
|
|
+ sysFileEntity.setUrl(url);
|
|
|
+
|
|
|
+ // 设置封面
|
|
|
+ setThumbUrl(sysFileEntity, UPLOAD_THUMB_SIZE.get(), UPLOAD_THUMB_SIZE.get(), StyleEnums.THUMB_BACKGROUND.getValue());
|
|
|
+
|
|
|
+ // [db] 更新分块记录
|
|
|
+ sysFileEntity.setRequest_id(completeResult.getRequestId());
|
|
|
+ sysFileDao.updateCompleteFile(sysFileEntity);
|
|
|
+
|
|
|
+ Map<String, Object> resp = new LinkedHashMap<>();
|
|
|
+ resp.put("upload_id", upload_id);
|
|
|
+ resp.put("request_id", completeResult.getRequestId());
|
|
|
+ resp.put("object_key", completeResult.getKey());
|
|
|
+ resp.put("url", url);
|
|
|
+ return resp;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
- // 合并分块
|
|
|
- tencentCosService.completeMultipartUpload(upload_id, sysFileEntity.getObject_key(), etags);
|
|
|
- return Map.of("upload_id", upload_id);
|
|
|
+ return null;
|
|
|
}
|
|
|
|
|
|
// 查询分块上传情况
|