فهرست منبع

修改分块上传,秒传配置下的返回值

tsurumure 3 ماه پیش
والد
کامیت
20d428681d

+ 96 - 23
src/main/java/com/backendsys/modules/upload/service/impl/SysFileMultipartServiceImpl.java

@@ -2,6 +2,7 @@ package com.backendsys.modules.upload.service.impl;
 
 
 import cn.hutool.core.codec.Base64;
 import cn.hutool.core.codec.Base64;
 import cn.hutool.core.convert.Convert;
 import cn.hutool.core.convert.Convert;
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.io.file.FileNameUtil;
 import cn.hutool.core.io.file.FileNameUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.crypto.digest.DigestUtil;
 import cn.hutool.crypto.digest.DigestUtil;
@@ -91,38 +92,25 @@ public class SysFileMultipartServiceImpl implements SysFileMultipartService {
         return sysFile;
         return sysFile;
     }
     }
 
 
-
-    // 1.初始化分块上传 (获得 upload_id, object_key)
-    @Override
-    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 分块数量不能为空");
+    // [方法] 上传事件
+    private SysFile uploadInitEvent(MultipartFile multipartFile, Long category_id, Integer target, Integer upload_chunk_count) {
+        System.out.println("[系统配置] 上传目标(-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云): " + target);
 
 
         String filename = multipartFile.getOriginalFilename();
         String filename = multipartFile.getOriginalFilename();
         if (filename.length() > 50) throw new CustException("文件名长度不能超过 50 字符");
         if (filename.length() > 50) throw new CustException("文件名长度不能超过 50 字符");
 
 
-        // 获得公共配置
-        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);
-
-        String target_label = StyleEnums.targetToLabel(UPLOAD_TARGET.get());
+        String target_label = StyleEnums.targetToLabel(target);
         String upload_id = null;
         String upload_id = null;
         String object_key = null;
         String object_key = null;
 
 
         // target: 上传目标 (-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云)
         // target: 上传目标 (-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云)
-        if (UPLOAD_TARGET.get() == 1) {
+        if (target == 1) {
             InitiateMultipartUploadResult uploadResult = tencentCosService.initiateMultipartUpload(multipartFile);
             InitiateMultipartUploadResult uploadResult = tencentCosService.initiateMultipartUpload(multipartFile);
             upload_id = uploadResult.getUploadId();
             upload_id = uploadResult.getUploadId();
             object_key = uploadResult.getKey();
             object_key = uploadResult.getKey();
         }
         }
         // 3: 抖音云
         // 3: 抖音云
-        if (UPLOAD_TARGET.get() == 3) {
+        if (target == 3) {
             CreateMultipartUploadOutput uploadResult = douyinTosService.initiateMultipartUpload(multipartFile);
             CreateMultipartUploadOutput uploadResult = douyinTosService.initiateMultipartUpload(multipartFile);
             upload_id = uploadResult.getUploadID();
             upload_id = uploadResult.getUploadID();
             object_key = uploadResult.getKey();
             object_key = uploadResult.getKey();
@@ -143,18 +131,103 @@ public class SysFileMultipartServiceImpl implements SysFileMultipartService {
 //        sysFileEntity.setName(FileNameUtil.getName(object_key));
 //        sysFileEntity.setName(FileNameUtil.getName(object_key));
         sysFileEntity.setName(filename);
         sysFileEntity.setName(filename);
         sysFileEntity.setObject_key(object_key);
         sysFileEntity.setObject_key(object_key);
-        sysFileEntity.setTarget(UPLOAD_TARGET.get());
+        sysFileEntity.setTarget(target);
         sysFileEntity.setContent_type(multipartFile.getContentType());
         sysFileEntity.setContent_type(multipartFile.getContentType());
         sysFileEntity.setSize(multipartFile.getSize());
         sysFileEntity.setSize(multipartFile.getSize());
         sysFileDao.insert(sysFileEntity);
         sysFileDao.insert(sysFileEntity);
 
 
+        return sysFileEntity;
+    }
+
+
+    // 1.初始化分块上传 (获得 upload_id, object_key)
+    @Override
+    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 分块数量不能为空");
+
+        String filename = multipartFile.getOriginalFilename();
+        if (filename.length() > 50) throw new CustException("文件名长度不能超过 50 字符");
+
+        // 获得公共配置
+        List<SysCommon> sysCommonList = sysCommonService.getCommonByCategory("UPLOAD");
+        AtomicReference<Integer> UPLOAD_TARGET = new AtomicReference<>();
+        AtomicReference<Integer> UPLOAD_THUMB_SIZE = new AtomicReference<>();
+        AtomicReference<Boolean> UPLOAD_MD5_DUPLICATE = 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()));
+            if (sysCommon.getTag().equals("UPLOAD_MD5_DUPLICATE")) UPLOAD_MD5_DUPLICATE.set(Convert.toBool(sysCommon.getValue()));
+        });
+
+
+        // 如果开启了 MD5秒传,则判断文件是否上传过,是的话就直接返回
+        // [系统配置] 是否启用文件MD5查重 (仅判断用户自己上传过的文件)
+        // - 存在,则根据文件MD5 判断是否上传过文件 (仅更新时间,不上传已存在的文件,允许更新文件分类)
+        // - 存在,如果存在两个相同 md5 以上的文件,则需要排重后再上传 (如果是不同用户
+        // - 不存在,则走上传流程
+        Boolean is_exist = false;
+        SysFile sysFileEntity = null;
+        if (UPLOAD_MD5_DUPLICATE.get()) {
+            try {
+                String md5 = DigestUtil.md5Hex(multipartFile.getInputStream());
+
+                // 排除文件异常的情况(出现两个以上相同MD5的文件)
+                LambdaQueryWrapper<SysFile> wrapperFile = new LambdaQueryWrapper<>();
+                wrapperFile.eq(SysFile::getMd5, md5);
+                wrapperFile.eq(SysFile::getUser_id, SecurityUtil.getUserId());
+
+                // [DB] 查询已存在的文件分块记录 (只有完全上传成功,才会有 MD5)
+                // - 异常情况:如果有两个相同的文件,一个上传50%,一个上传成功,就会出现以下这种情况,需要手动解决
+                List<SysFile> sysFileEntityList = sysFileDao.selectList(wrapperFile);
+                if (sysFileEntityList != null && sysFileEntityList.size() > 1) {
+                    throw new CustException("存在 " + sysFileEntityList.size() + " 个相同Md5 (" + md5 + ") 的文件,请先排重后再上传");
+                }
+
+                if (sysFileEntityList != null && sysFileEntityList.size() > 0) {
+
+                    is_exist = true;
+                    // 将已存在的文件,赋值
+                    sysFileEntity = sysFileEntityList.get(0);
+                    // [DB] 更新文件 (支持更换文件分类)
+                    sysFileEntity.setCategory_id(category_id);
+                    sysFileEntity.setUpdate_time(DateUtil.now());
+
+                    System.out.println("-----------------");
+                    System.out.println(sysFileEntity);
+                    System.out.println("-----------------");
+
+                    sysFileDao.updateById(sysFileEntity);
+                } else {
+                    // [DB] 创建新的文件
+                    sysFileEntity = uploadInitEvent(multipartFile, category_id, UPLOAD_TARGET.get(), upload_chunk_count);
+                    // [格式化] 封面 (图片类型)
+                    sysFileEntity = setThumbUrl(sysFileEntity, UPLOAD_THUMB_SIZE.get(), UPLOAD_THUMB_SIZE.get(), StyleEnums.THUMB_BACKGROUND.getValue());
+                }
+
+            } catch (IOException e) {
+                throw new RuntimeException(e);
+            }
+        } else {
+            // 不开启 MD5秒 传,则直接初始化分块
+            // [DB] 创建新的文件
+            sysFileEntity = uploadInitEvent(multipartFile, category_id, UPLOAD_TARGET.get(), upload_chunk_count);
+            // [格式化] 封面 (图片类型)
+            sysFileEntity = setThumbUrl(sysFileEntity, UPLOAD_THUMB_SIZE.get(), UPLOAD_THUMB_SIZE.get(), StyleEnums.THUMB_BACKGROUND.getValue());
+        }
+
         Map<String, Object> resp = new LinkedHashMap<>();
         Map<String, Object> resp = new LinkedHashMap<>();
         resp.put("target", UPLOAD_TARGET.get());
         resp.put("target", UPLOAD_TARGET.get());
-        resp.put("target_label", target_label);
+        resp.put("target_label", StyleEnums.targetToLabel(UPLOAD_TARGET.get()));
         resp.put("upload_chunk_count", upload_chunk_count);
         resp.put("upload_chunk_count", upload_chunk_count);
-        resp.put("upload_id", upload_id);
-        resp.put("object_key", object_key);
+        resp.put("upload_id", sysFileEntity.getUpload_id());
+        resp.put("object_key", sysFileEntity.getObject_key());
+        // MD5 秒传,返回已上传的文件信息
+        resp.put("is_exist", is_exist);
+        resp.put("file_info", is_exist ? sysFileEntity : null);
         return resp;
         return resp;
+
     }
     }
 
 
     // 2.上传分块
     // 2.上传分块

+ 28 - 18
src/main/java/com/backendsys/modules/upload/service/impl/SysFileServiceImpl.java

@@ -88,7 +88,7 @@ public class SysFileServiceImpl extends ServiceImpl<SysFileDao, SysFile> impleme
     }
     }
 
 
     /**
     /**
-     * 获取文件列表 (total 有问题)
+     * 获取文件列表
      */
      */
     @Override
     @Override
     public PageEntity selectUploadFileList(SysFile sysFile) {
     public PageEntity selectUploadFileList(SysFile sysFile) {
@@ -100,11 +100,12 @@ public class SysFileServiceImpl extends ServiceImpl<SysFileDao, SysFile> impleme
 
 
         // -- 完成分页渲染之后,再做列表格式化 -----------------------------------
         // -- 完成分页渲染之后,再做列表格式化 -----------------------------------
         // [Common] 根据 Tag 获得 Options
         // [Common] 根据 Tag 获得 Options
-        JSONArray COMMON_OPTIONS = sysCommonService.getCommonOptionByTag("UPLOAD_TARGET");
+        // JSONArray COMMON_OPTIONS = sysCommonService.getCommonOptionByTag("UPLOAD_TARGET");
         // 遍历列表,赋值公共值翻译
         // 遍历列表,赋值公共值翻译
         sysFileList = sysFileList.stream().map(item -> {
         sysFileList = sysFileList.stream().map(item -> {
             // 查询出 上传存储介质(target) 的翻译
             // 查询出 上传存储介质(target) 的翻译
-            String target_label = Convert.toStr(sysCommonService.getLabelByValue(COMMON_OPTIONS, item.getTarget()));
+            // String target_label = Convert.toStr(sysCommonService.getLabelByValue(COMMON_OPTIONS, item.getTarget()));
+            String target_label = StyleEnums.targetToLabel(item.getTarget());
             item.setTarget_label(target_label);
             item.setTarget_label(target_label);
             return item;
             return item;
         }).collect(Collectors.toList());
         }).collect(Collectors.toList());
@@ -255,37 +256,46 @@ public class SysFileServiceImpl extends ServiceImpl<SysFileDao, SysFile> impleme
 
 
         try {
         try {
 
 
-            // [系统配置] 是否启用文件MD5查重
+            // [系统配置] 是否启用文件MD5查重 (仅判断用户自己上传过的文件)
+            // - 存在,则根据文件MD5 判断是否上传过文件 (仅更新时间,不上传已存在的文件,允许更新文件分类)
+            // - 存在,如果存在两个相同 md5 以上的文件,则需要排重后再上传 (如果是不同用户
+            // - 不存在,则走上传流程
+            Boolean is_exist = false;
+            SysFile sysFileEntity = null;
             if (UPLOAD_MD5_DUPLICATE.get()) {
             if (UPLOAD_MD5_DUPLICATE.get()) {
-                // - 是
-                // 根据文件MD5 判断是否上传过文件
-                // - 如果上传过,则仅更新记录,不再上传文件,仅更新文件分类
-                // - 如果存在
+
                 String md5 = DigestUtil.md5Hex(multipartFile.getInputStream());
                 String md5 = DigestUtil.md5Hex(multipartFile.getInputStream());
 
 
                 // 排除文件异常的情况(出现两个以上相同MD5的文件)
                 // 排除文件异常的情况(出现两个以上相同MD5的文件)
-                List<SysFile> sysFileEntityList = sysFileDao.selectList(new LambdaQueryWrapper<SysFile>().eq(SysFile::getMd5, md5));
+                LambdaQueryWrapper<SysFile> wrapperFile = new LambdaQueryWrapper<>();
+                wrapperFile.eq(SysFile::getMd5, md5);
+                wrapperFile.eq(SysFile::getUser_id, SecurityUtil.getUserId());
+                List<SysFile> sysFileEntityList = sysFileDao.selectList(wrapperFile);
                 if (sysFileEntityList != null && sysFileEntityList.size() > 1) {
                 if (sysFileEntityList != null && sysFileEntityList.size() > 1) {
                     throw new CustException("存在 " + sysFileEntityList.size() + " 个相同Md5 (" + md5 + ") 的文件,请先排重后再上传");
                     throw new CustException("存在 " + sysFileEntityList.size() + " 个相同Md5 (" + md5 + ") 的文件,请先排重后再上传");
                 }
                 }
 
 
-                SysFile sysFileEntity = (sysFileEntityList != null && sysFileEntityList.size() > 0) ? sysFileEntityList.get(0) : null;
-                if (sysFileEntity == null) {
-                    // [方法] 上传事件
-                    sysFileEntity = uploadEvent(multipartFile, category_id, UPLOAD_TARGET.get());
-                } else {
-                    // [更新] 上传文件记录 (更换文件分类)
+                if (sysFileEntityList != null && sysFileEntityList.size() > 0) {
+                    is_exist = true;
+                    // 将已存在的文件,赋值
+                    sysFileEntity = sysFileEntityList.get(0);
+                    // [DB] 更新文件 (支持更换文件分类)
                     sysFileEntity.setCategory_id(category_id);
                     sysFileEntity.setCategory_id(category_id);
                     sysFileEntity.setUpdate_time(DateUtil.now());
                     sysFileEntity.setUpdate_time(DateUtil.now());
                     sysFileDao.updateById(sysFileEntity);
                     sysFileDao.updateById(sysFileEntity);
+                } else {
+                    // [DB] 创建新的文件
+                    sysFileEntity = uploadEvent(multipartFile, category_id, UPLOAD_TARGET.get());
+                    // [格式化] 封面 (图片类型)
+                    sysFileEntity = setThumbUrl(sysFileEntity, UPLOAD_THUMB_SIZE.get(), UPLOAD_THUMB_SIZE.get(), StyleEnums.THUMB_BACKGROUND.getValue());
                 }
                 }
-                sysFileEntity = setThumbUrl(sysFileEntity, UPLOAD_THUMB_SIZE.get(), UPLOAD_THUMB_SIZE.get(), StyleEnums.THUMB_BACKGROUND.getValue());
                 return sysFileEntity;
                 return sysFileEntity;
 
 
             } else {
             } else {
-                // - 否
+                // 不开启 MD5秒 传,则直接初始化分块
                 // [方法] 上传事件
                 // [方法] 上传事件
-                SysFile sysFileEntity = uploadEvent(multipartFile, category_id, UPLOAD_TARGET.get());
+                sysFileEntity = uploadEvent(multipartFile, category_id, UPLOAD_TARGET.get());
+                // [格式化] 封面 (图片类型)
                 sysFileEntity = setThumbUrl(sysFileEntity, UPLOAD_THUMB_SIZE.get(), UPLOAD_THUMB_SIZE.get(), StyleEnums.THUMB_BACKGROUND.getValue());
                 sysFileEntity = setThumbUrl(sysFileEntity, UPLOAD_THUMB_SIZE.get(), UPLOAD_THUMB_SIZE.get(), StyleEnums.THUMB_BACKGROUND.getValue());
                 return sysFileEntity;
                 return sysFileEntity;
             }
             }