|
@@ -19,10 +19,12 @@ import org.springframework.stereotype.Service;
|
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.LinkedHashMap;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.concurrent.atomic.AtomicReference;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
@Service
|
|
|
public class SysFileMultipartServiceImpl implements SysFileMultipartService {
|
|
@@ -41,9 +43,12 @@ public class SysFileMultipartServiceImpl implements SysFileMultipartService {
|
|
|
查一下 upload_id 多久会过期
|
|
|
*/
|
|
|
|
|
|
- // 初始化分块上传 (获得 upload_id, object_key)
|
|
|
+ // 1.初始化分块上传 (获得 upload_id, object_key)
|
|
|
@Override
|
|
|
- public Map<String, Object> initiateMultipartUpload(MultipartFile multipartFile, Long category_id) {
|
|
|
+ public Map<String, Object> multipartUploadInit(MultipartFile multipartFile, Long category_id, Integer upload_chunk_count) {
|
|
|
+
|
|
|
+ if (multipartFile.isEmpty()) throw new CustException("file 上传文件不能为空");
|
|
|
+ if (upload_chunk_count == null) throw new CustException("upload_chunk_count 分块数量不能为空");
|
|
|
|
|
|
// 获得公共配置
|
|
|
List<SysCommon> sysCommonList = sysCommonService.getCommonByCategory("UPLOAD");
|
|
@@ -54,12 +59,13 @@ public class SysFileMultipartServiceImpl implements SysFileMultipartService {
|
|
|
|
|
|
System.out.println("[系统配置] 上传目标(-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云): " + UPLOAD_TARGET);
|
|
|
|
|
|
-
|
|
|
+ String target_label = "";
|
|
|
String upload_id = null;
|
|
|
String object_key = null;
|
|
|
|
|
|
// target: 上传目标 (-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云)
|
|
|
if (UPLOAD_TARGET.get() == 1) {
|
|
|
+ target_label = "腾讯云初始化分块";
|
|
|
InitiateMultipartUploadResult uploadResult = tencentCosService.initiateMultipartUpload(multipartFile);
|
|
|
upload_id = uploadResult.getUploadId();
|
|
|
object_key = uploadResult.getKey();
|
|
@@ -75,6 +81,8 @@ public class SysFileMultipartServiceImpl implements SysFileMultipartService {
|
|
|
sysFileEntity.setCategory_id(category_id);
|
|
|
sysFileEntity.setUser_id(httpRequestUtil.getUserId());
|
|
|
sysFileEntity.setUpload_id(upload_id);
|
|
|
+ sysFileEntity.setUpload_chunk_count(upload_chunk_count);
|
|
|
+ sysFileEntity.setUpload_chunk_index(0);
|
|
|
sysFileEntity.setName(FileNameUtil.getName(object_key));
|
|
|
sysFileEntity.setObject_key(object_key);
|
|
|
sysFileEntity.setTarget(UPLOAD_TARGET.get());
|
|
@@ -83,64 +91,101 @@ public class SysFileMultipartServiceImpl implements SysFileMultipartService {
|
|
|
sysFileDao.insert(sysFileEntity);
|
|
|
|
|
|
Map<String, Object> resp = new LinkedHashMap<>();
|
|
|
+ resp.put("target", UPLOAD_TARGET.get());
|
|
|
+ resp.put("target_label", target_label);
|
|
|
+ resp.put("upload_chunk_count", upload_chunk_count);
|
|
|
resp.put("upload_id", upload_id);
|
|
|
resp.put("object_key", object_key);
|
|
|
return resp;
|
|
|
}
|
|
|
|
|
|
- // 上传分块
|
|
|
+ // 2.上传分块
|
|
|
@Override
|
|
|
- public Map<String, Object> uploadMultipart(MultipartFile multipartFile, String upload_id) {
|
|
|
+ public Map<String, Object> multipartUpload(MultipartFile multipartFile, String upload_id, Integer upload_chunk_index) {
|
|
|
|
|
|
+ if (multipartFile.isEmpty()) throw new CustException("file 上传文件不能为空");
|
|
|
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("upload_id 不存在");
|
|
|
-
|
|
|
+ if (sysFileEntity == null) throw new CustException("分块记录不存在");
|
|
|
String object_key = sysFileEntity.getObject_key();
|
|
|
+ Integer upload_chunk_size = sysFileEntity.getUpload_chunk_count();
|
|
|
+ if (upload_chunk_index > upload_chunk_size) throw new CustException("分块索引(index)不能大于分块数量(count)");
|
|
|
+
|
|
|
+ // 获得公共配置
|
|
|
+ List<SysCommon> sysCommonList = sysCommonService.getCommonByCategory("UPLOAD");
|
|
|
+ AtomicReference<Integer> UPLOAD_TARGET = new AtomicReference<>();
|
|
|
+ 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();
|
|
|
+ }
|
|
|
|
|
|
- // 查询分块上传情况 (获得下次要上传的位置)
|
|
|
- PartListing partListing = listParts(upload_id, object_key);
|
|
|
- Integer partNumberMarker = partListing.getPartNumberMarker() + 1;
|
|
|
+// // 查询分块上传情况 (获得下次要上传的位置)
|
|
|
+// PartListing partListing = listParts(upload_id, object_key);
|
|
|
+// Integer partNumberMarker = partListing.getPartNumberMarker() + 1;
|
|
|
|
|
|
- UploadPartResult partResult = tencentCosService.uploadPart(multipartFile, upload_id, object_key, partNumberMarker);
|
|
|
- System.out.println("partResult:");
|
|
|
- System.out.println(partResult);
|
|
|
+
|
|
|
+ // [Update] 更新分块文件信息
|
|
|
+ sysFileEntity.setUpload_chunk_index(upload_chunk_index);
|
|
|
+ sysFileDao.updateById(sysFileEntity);
|
|
|
|
|
|
Map<String, Object> resp = new LinkedHashMap<>();
|
|
|
+ resp.put("upload_chunk_index", upload_chunk_index);
|
|
|
resp.put("upload_id", upload_id);
|
|
|
resp.put("object_key", object_key);
|
|
|
- resp.put("part_number", partNumberMarker);
|
|
|
- resp.put("part_etag", partResult.getPartETag());
|
|
|
+ resp.put("part_etag", part_etag);
|
|
|
return resp;
|
|
|
}
|
|
|
|
|
|
- // 查询分块上传情况
|
|
|
- @Override
|
|
|
- public PartListing listParts(String upload_id, String object_key) {
|
|
|
- return tencentCosService.listParts(upload_id, object_key);
|
|
|
- }
|
|
|
-
|
|
|
// 完成分块上传
|
|
|
@Override
|
|
|
- public Map<String, Object> completeMultipartUpload(String upload_id) {
|
|
|
+ public Map<String, Object> multipartUploadComplete(String upload_id) {
|
|
|
|
|
|
if (StrUtil.isEmpty(upload_id)) throw new CustException("upload_id 不能为空");
|
|
|
|
|
|
+ // [Get] 查询文件分块记录
|
|
|
SysFile sysFileEntity = sysFileDao.selectOne(new LambdaQueryWrapper<SysFile>().eq(SysFile::getUpload_id, upload_id));
|
|
|
if (sysFileEntity == null) throw new CustException("upload_id 不存在");
|
|
|
|
|
|
- String object_key = sysFileEntity.getObject_key();
|
|
|
+ // 判断分块索引和分块数量是否一致
|
|
|
+ if (sysFileEntity.getUpload_chunk_index() != sysFileEntity.getUpload_chunk_count()) {
|
|
|
+ throw new CustException("分块索引和分块数量不一致");
|
|
|
+ }
|
|
|
|
|
|
-// // 查询分块上传情况 (获得下次要上传的位置)
|
|
|
-// PartListing partListing = listParts(upload_id, object_key);
|
|
|
-// List<PartSummary> partSummaryList = partListing.getParts();
|
|
|
-//
|
|
|
-// List<PartETag> partETags = new ArrayList<>();
|
|
|
-//
|
|
|
-// tencentCosService.completeMultipartUpload(upload_id, object_key, partETags);
|
|
|
+ // 查询分块集合 (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("分块索引异常,请重新上传");
|
|
|
+ }
|
|
|
|
|
|
+ // 合并分块
|
|
|
+ tencentCosService.completeMultipartUpload(upload_id, sysFileEntity.getObject_key(), etags);
|
|
|
return Map.of("upload_id", upload_id);
|
|
|
}
|
|
|
|
|
|
+ // 查询分块上传情况
|
|
|
+ @Override
|
|
|
+ public PartListing listParts(String upload_id, String object_key) {
|
|
|
+ return tencentCosService.listParts(upload_id, object_key);
|
|
|
+ }
|
|
|
+
|
|
|
}
|