|
@@ -1,12 +1,14 @@
|
|
package com.backendsys.modules.upload.service.impl;
|
|
package com.backendsys.modules.upload.service.impl;
|
|
|
|
|
|
import cn.hutool.core.codec.Base64;
|
|
import cn.hutool.core.codec.Base64;
|
|
|
|
+import cn.hutool.core.collection.CollectionUtil;
|
|
import cn.hutool.core.convert.Convert;
|
|
import cn.hutool.core.convert.Convert;
|
|
import cn.hutool.core.date.DateUtil;
|
|
import cn.hutool.core.date.DateUtil;
|
|
import cn.hutool.core.util.StrUtil;
|
|
import cn.hutool.core.util.StrUtil;
|
|
import cn.hutool.crypto.digest.DigestUtil;
|
|
import cn.hutool.crypto.digest.DigestUtil;
|
|
import cn.hutool.json.JSONArray;
|
|
import cn.hutool.json.JSONArray;
|
|
import com.backendsys.exception.CustException;
|
|
import com.backendsys.exception.CustException;
|
|
|
|
+import com.backendsys.modules.common.config.security.enums.SecurityEnum;
|
|
import com.backendsys.modules.common.config.security.utils.HttpRequestUtil;
|
|
import com.backendsys.modules.common.config.security.utils.HttpRequestUtil;
|
|
import com.backendsys.modules.common.config.security.utils.SecurityUtil;
|
|
import com.backendsys.modules.common.config.security.utils.SecurityUtil;
|
|
import com.backendsys.modules.sdk.douyincloud.tos.service.DouyinTosService;
|
|
import com.backendsys.modules.sdk.douyincloud.tos.service.DouyinTosService;
|
|
@@ -17,12 +19,14 @@ import com.backendsys.modules.upload.dao.SysFileCategoryDao;
|
|
import com.backendsys.modules.upload.dao.SysFileDao;
|
|
import com.backendsys.modules.upload.dao.SysFileDao;
|
|
import com.backendsys.modules.upload.entity.SysFile;
|
|
import com.backendsys.modules.upload.entity.SysFile;
|
|
import com.backendsys.modules.upload.entity.SysFileCategory;
|
|
import com.backendsys.modules.upload.entity.SysFileCategory;
|
|
|
|
+import com.backendsys.modules.upload.entity.SysFileMergeByMd5;
|
|
import com.backendsys.modules.upload.entity.SysFileResult;
|
|
import com.backendsys.modules.upload.entity.SysFileResult;
|
|
import com.backendsys.modules.upload.enums.StyleEnums;
|
|
import com.backendsys.modules.upload.enums.StyleEnums;
|
|
import com.backendsys.modules.upload.service.SysFileService;
|
|
import com.backendsys.modules.upload.service.SysFileService;
|
|
import com.backendsys.modules.upload.utils.UploadUtil;
|
|
import com.backendsys.modules.upload.utils.UploadUtil;
|
|
import com.backendsys.utils.response.PageEntity;
|
|
import com.backendsys.utils.response.PageEntity;
|
|
import com.backendsys.utils.response.PageInfoResult;
|
|
import com.backendsys.utils.response.PageInfoResult;
|
|
|
|
+import com.backendsys.utils.response.ResultEnum;
|
|
import com.backendsys.utils.v2.PageUtils;
|
|
import com.backendsys.utils.v2.PageUtils;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
@@ -30,6 +34,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.util.StringUtils;
|
|
import org.springframework.util.StringUtils;
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
@@ -44,7 +49,8 @@ public class SysFileServiceImpl extends ServiceImpl<SysFileDao, SysFile> impleme
|
|
|
|
|
|
@Autowired
|
|
@Autowired
|
|
private HttpRequestUtil httpRequestUtil;
|
|
private HttpRequestUtil httpRequestUtil;
|
|
-
|
|
|
|
|
|
+ @Autowired
|
|
|
|
+ private SecurityUtil securityUtil;
|
|
@Autowired
|
|
@Autowired
|
|
private TencentCosService tencentCosService;
|
|
private TencentCosService tencentCosService;
|
|
@Autowired
|
|
@Autowired
|
|
@@ -270,9 +276,10 @@ public class SysFileServiceImpl extends ServiceImpl<SysFileDao, SysFile> impleme
|
|
LambdaQueryWrapper<SysFile> wrapperFile = new LambdaQueryWrapper<>();
|
|
LambdaQueryWrapper<SysFile> wrapperFile = new LambdaQueryWrapper<>();
|
|
wrapperFile.eq(SysFile::getMd5, md5);
|
|
wrapperFile.eq(SysFile::getMd5, md5);
|
|
wrapperFile.eq(SysFile::getUser_id, SecurityUtil.getUserId());
|
|
wrapperFile.eq(SysFile::getUser_id, SecurityUtil.getUserId());
|
|
|
|
+ wrapperFile.isNull(SysFile::getUpload_id);
|
|
List<SysFile> sysFileEntityList = sysFileDao.selectList(wrapperFile);
|
|
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 + ") 的文件", ResultEnum.STATUS_CONFLICT.getCode());
|
|
}
|
|
}
|
|
|
|
|
|
if (sysFileEntityList != null && sysFileEntityList.size() > 0) {
|
|
if (sysFileEntityList != null && sysFileEntityList.size() > 0) {
|
|
@@ -427,4 +434,77 @@ public class SysFileServiceImpl extends ServiceImpl<SysFileDao, SysFile> impleme
|
|
return Map.of("ids", ids);
|
|
return Map.of("ids", ids);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * 根据 MD5 获取文件列表 (我的)
|
|
|
|
+ */
|
|
|
|
+ @Override
|
|
|
|
+ public List<Map<String, Object>> getUploadFileListByMd5(SysFile sysFile) {
|
|
|
|
+ SysFile entity = new SysFile();
|
|
|
|
+ entity.setUser_id(sysFile.getUser_id());
|
|
|
|
+ entity.setUpload_id("");
|
|
|
|
+ entity.setMd5(sysFile.getMd5());
|
|
|
|
+ return sysFileDao.selectUploadFileSimple(entity);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 合并重复 MD5 文件 { md5, ids }
|
|
|
|
+ */
|
|
|
|
+ @Override
|
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
|
+ public Map<String, Object> mergeFileByMd5(SysFileMergeByMd5 sysFileMergeByMd5) {
|
|
|
|
+
|
|
|
|
+ Long user_id = sysFileMergeByMd5.getUser_id();
|
|
|
|
+ List<String> object_keys = sysFileMergeByMd5.getObject_keys();
|
|
|
|
+ String target_object_key = sysFileMergeByMd5.getTarget_object_key();
|
|
|
|
+ String target_file_name = sysFileMergeByMd5.getTarget_file_name();
|
|
|
|
+
|
|
|
|
+ // 判断 target_object 是否存在于 object_keys 中
|
|
|
|
+ boolean exists = CollectionUtil.contains(object_keys, target_object_key);
|
|
|
|
+ if (!exists) throw new CustException("合并目标文件ID不存在于列表中");
|
|
|
|
+
|
|
|
|
+ // 判断权限 (需要子权限或超级管理员)
|
|
|
|
+ if (!SecurityUtil.isSuper() && !securityUtil.hasPermission("1.1.5")) {
|
|
|
|
+ throw new CustException(SecurityEnum.NOAUTH);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // --------------------------------------------------------------------------------
|
|
|
|
+ // 更新文件命名
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // --------------------------------------------------------------------------------
|
|
|
|
+ // 过滤一个没有 target_object_key 的 object_keys 集合
|
|
|
|
+ List<String> file_object_keys_without_target = object_keys.stream().filter(object_key -> !object_key.equals(target_object_key)).collect(Collectors.toList());
|
|
|
|
+
|
|
|
|
+ // 查询文件列表 (不包含 target_object_key、当前用户ID、upload_id 为空)
|
|
|
|
+ LambdaQueryWrapper<SysFile> wrapperFile = new LambdaQueryWrapper<>();
|
|
|
|
+ wrapperFile.in(SysFile::getUser_id, user_id);
|
|
|
|
+ wrapperFile.in(SysFile::getObject_key, file_object_keys_without_target);
|
|
|
|
+ wrapperFile.isNull(SysFile::getUpload_id);
|
|
|
|
+ List<SysFile> querySysFileList = sysFileDao.selectList(wrapperFile);
|
|
|
|
+
|
|
|
|
+ // 筛选出待删除的文件 object_key
|
|
|
|
+ List<String> delete_object_keys = querySysFileList.stream().map(entity -> entity.getObject_key()).collect(Collectors.toList());
|
|
|
|
+
|
|
|
|
+ // [Delete] 批量删除
|
|
|
|
+ sysFileDao.delete(new LambdaQueryWrapper<SysFile>().in(SysFile::getObject_key, delete_object_keys));
|
|
|
|
+
|
|
|
|
+ // [异步任务] 创建一个 CompletableFuture 来执行异步任务
|
|
|
|
+ CompletableFuture.runAsync(() -> {
|
|
|
|
+ querySysFileList.stream().forEach(entity -> {
|
|
|
|
+ deleteObject(entity.getObject_key(), entity.getTarget());
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ // --------------------------------------------------------------------------------
|
|
|
|
+
|
|
|
|
+ Map<String, Object> resp = new LinkedHashMap<>();
|
|
|
|
+ resp.put("delete_object_keys", delete_object_keys);
|
|
|
|
+ resp.put("target_object_key", target_object_key);
|
|
|
|
+
|
|
|
|
+ return resp;
|
|
|
|
+ }
|
|
|
|
+
|
|
}
|
|
}
|