diff --git a/pom.xml b/pom.xml index 891a977..83d2226 100644 --- a/pom.xml +++ b/pom.xml @@ -6,11 +6,11 @@ com.qiwenshare qiwenshare - 1.2.7 + 1.2.8 qiwen-file - 1.2.7-SNAPSHOT + 1.2.8-SNAPSHOT qiwen-file pan.qiwenshare.com jar diff --git a/src/main/java/com/qiwenshare/file/component/AsyncTaskComp.java b/src/main/java/com/qiwenshare/file/component/AsyncTaskComp.java index b9619e9..7cc36d6 100644 --- a/src/main/java/com/qiwenshare/file/component/AsyncTaskComp.java +++ b/src/main/java/com/qiwenshare/file/component/AsyncTaskComp.java @@ -75,12 +75,16 @@ public class AsyncTaskComp { if (filePointCount != null && filePointCount == 0 && userFileItem.getIsDir() == 0) { FileBean fileBean = fileMapper.selectById(userFileItem.getFileId()); - try { - filetransferService.deleteFile(fileBean); - fileMapper.deleteById(fileBean.getFileId()); - } catch (Exception e) { - log.error("删除本地文件失败:" + JSON.toJSONString(fileBean)); + if (fileBean != null) { + try { + filetransferService.deleteFile(fileBean); + fileMapper.deleteById(fileBean.getFileId()); + } catch (Exception e) { + log.error("删除本地文件失败:" + JSON.toJSONString(fileBean)); + } } + + } } } else { @@ -145,7 +149,7 @@ public class AsyncTaskComp { String saveFileUrl = ufopFactory.getCopier().copy(fileInputStream, createFile); FileBean tempFileBean = new FileBean(saveFileUrl, currentFile.length(), storageType, md5Str, userFile.getUserId()); -; + fileMapper.insert(tempFileBean); fileId = tempFileBean.getFileId(); } diff --git a/src/main/java/com/qiwenshare/file/config/security/filter/JwtAuthenticationTokenFilter.java b/src/main/java/com/qiwenshare/file/config/security/filter/JwtAuthenticationTokenFilter.java index 9b2b1de..ee00ba6 100644 --- a/src/main/java/com/qiwenshare/file/config/security/filter/JwtAuthenticationTokenFilter.java +++ b/src/main/java/com/qiwenshare/file/config/security/filter/JwtAuthenticationTokenFilter.java @@ -42,7 +42,7 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { "/notice/list", "/notice/detail", "/param/grouplist", - + "/v3/api-docs", "/swagger-ui.html", "/office/IndexServlet" }; diff --git a/src/main/java/com/qiwenshare/file/controller/FileController.java b/src/main/java/com/qiwenshare/file/controller/FileController.java index 97b7b40..ac06316 100644 --- a/src/main/java/com/qiwenshare/file/controller/FileController.java +++ b/src/main/java/com/qiwenshare/file/controller/FileController.java @@ -7,7 +7,9 @@ import co.elastic.clients.elasticsearch.core.SearchResponse; import co.elastic.clients.elasticsearch.core.search.HighlighterEncoder; import co.elastic.clients.elasticsearch.core.search.Hit; import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.qiwenshare.common.anno.MyLog; import com.qiwenshare.common.exception.QiwenException; @@ -51,6 +53,11 @@ import java.io.FileInputStream; import java.io.IOException; import java.net.URLDecoder; import java.util.*; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; @Tag(name = "file", description = "该接口为文件接口,主要用来做一些文件的基本操作,如创建目录,删除,移动,复制等。") @RestController @@ -72,6 +79,9 @@ public class FileController { private ElasticsearchClient elasticsearchClient; @Value("${ufop.storage-type}") private Integer storageType; + + public static Executor executor = Executors.newFixedThreadPool(20); + public static final String CURRENT_MODULE = "文件接口"; @Operation(summary = "创建文件", description = "创建文件", tags = {"file"}) @@ -253,7 +263,8 @@ public class FileController { List list = userFileService.selectUserFileByLikeRightFilePath(new QiwenFile(userFile.getFilePath(), userFile.getFileName(), true).getPath(), sessionUserBean.getUserId()); for (UserFile newUserFile : list) { - newUserFile.setFilePath(newUserFile.getFilePath().replaceFirst(new QiwenFile(userFile.getFilePath(), userFile.getFileName(), userFile.getIsDir() == 1).getPath(), + String escapedPattern = Pattern.quote(new QiwenFile(userFile.getFilePath(), userFile.getFileName(), userFile.getIsDir() == 1).getPath()); + newUserFile.setFilePath(newUserFile.getFilePath().replaceFirst(escapedPattern, new QiwenFile(userFile.getFilePath(), renameFileDto.getFileName(), userFile.getIsDir() == 1).getPath())); userFileService.updateById(newUserFile); } @@ -287,8 +298,12 @@ public class FileController { public RestResult deleteImageByIds(@RequestBody BatchDeleteFileDTO batchDeleteFileDto) { String userFileIds = batchDeleteFileDto.getUserFileIds(); String[] userFileIdList = userFileIds.split(","); + userFileService.update(new UpdateWrapper().lambda().set(UserFile::getDeleteFlag, 1).in(UserFile::getUserFileId, Arrays.asList(userFileIdList))); for (String userFileId : userFileIdList) { - userFileService.deleteUserFile(userFileId, SessionUtil.getUserId()); + executor.execute(()->{ + userFileService.deleteUserFile(userFileId, SessionUtil.getUserId()); + }); + fileDealComp.deleteESByUserFileId(userFileId); } diff --git a/src/main/java/com/qiwenshare/file/domain/FileBean.java b/src/main/java/com/qiwenshare/file/domain/FileBean.java index 63f85fe..3f0f6a0 100644 --- a/src/main/java/com/qiwenshare/file/domain/FileBean.java +++ b/src/main/java/com/qiwenshare/file/domain/FileBean.java @@ -39,7 +39,7 @@ public class FileBean { @Column(columnDefinition="int(1) comment '存储类型'") private Integer storageType; - @Column(columnDefinition="varchar(32) comment 'md5唯一标识'") + @Column(columnDefinition="varchar(200) comment 'md5唯一标识'") private String identifier; @Column(columnDefinition="varchar(25) comment '创建时间'") diff --git a/src/main/java/com/qiwenshare/file/domain/Image.java b/src/main/java/com/qiwenshare/file/domain/Image.java index a81457a..3d4b6d0 100644 --- a/src/main/java/com/qiwenshare/file/domain/Image.java +++ b/src/main/java/com/qiwenshare/file/domain/Image.java @@ -23,7 +23,7 @@ public class Image { @TableId(type = IdType.AUTO) @Column(columnDefinition="bigint(20)") private Long imageId; - @Column(columnDefinition = "bigint(20) comment '文件id'") + @Column(columnDefinition = "varchar(20) comment '文件id'") private String fileId; @Column(columnDefinition="int(5) comment '图像的宽'") private Integer imageWidth; diff --git a/src/main/java/com/qiwenshare/file/domain/RecoveryFile.java b/src/main/java/com/qiwenshare/file/domain/RecoveryFile.java index 6d2e59b..e4a2d07 100644 --- a/src/main/java/com/qiwenshare/file/domain/RecoveryFile.java +++ b/src/main/java/com/qiwenshare/file/domain/RecoveryFile.java @@ -8,7 +8,9 @@ import lombok.Data; import javax.persistence.*; @Data -@Table(name = "recoveryfile") +@Table(name = "recoveryfile", uniqueConstraints = { + @UniqueConstraint(name = "user_file_id_index3", columnNames = {"userFileId"}) +}) @Entity @TableName("recoveryfile") public class RecoveryFile { diff --git a/src/main/java/com/qiwenshare/file/domain/StorageBean.java b/src/main/java/com/qiwenshare/file/domain/StorageBean.java index 6249283..22faf91 100644 --- a/src/main/java/com/qiwenshare/file/domain/StorageBean.java +++ b/src/main/java/com/qiwenshare/file/domain/StorageBean.java @@ -11,7 +11,9 @@ import javax.persistence.*; * 存储信息类 */ @Data -@Table(name = "storage") +@Table(name = "storage", uniqueConstraints = { + @UniqueConstraint(name = "userid_index", columnNames = {"userId"}) +}) @Entity @TableName("storage") public class StorageBean { diff --git a/src/main/java/com/qiwenshare/file/domain/UploadTask.java b/src/main/java/com/qiwenshare/file/domain/UploadTask.java index ec2a349..79488ba 100644 --- a/src/main/java/com/qiwenshare/file/domain/UploadTask.java +++ b/src/main/java/com/qiwenshare/file/domain/UploadTask.java @@ -22,7 +22,7 @@ public class UploadTask { @Column(columnDefinition = "bigint(20) comment '用户id'") private String userId; - @Column(columnDefinition="varchar(32) comment 'md5唯一标识'") + @Column(columnDefinition="varchar(200) comment 'md5唯一标识'") private String identifier; @Column(columnDefinition="varchar(100) comment '文件名称'") diff --git a/src/main/java/com/qiwenshare/file/domain/UploadTaskDetail.java b/src/main/java/com/qiwenshare/file/domain/UploadTaskDetail.java index 7d3223e..c6bba8b 100644 --- a/src/main/java/com/qiwenshare/file/domain/UploadTaskDetail.java +++ b/src/main/java/com/qiwenshare/file/domain/UploadTaskDetail.java @@ -37,6 +37,6 @@ public class UploadTaskDetail { @Column(columnDefinition="bigint(10) comment '文件总大小'") private Integer totalSize; - @Column(columnDefinition="varchar(32) comment '文件md5唯一标识'") + @Column(columnDefinition="varchar(200) comment '文件md5唯一标识'") private String identifier; } diff --git a/src/main/java/com/qiwenshare/file/io/QiwenFile.java b/src/main/java/com/qiwenshare/file/io/QiwenFile.java index 53719da..90fd585 100644 --- a/src/main/java/com/qiwenshare/file/io/QiwenFile.java +++ b/src/main/java/com/qiwenshare/file/io/QiwenFile.java @@ -18,17 +18,17 @@ public class QiwenFile { private boolean isDirectory; public QiwenFile(String pathname, boolean isDirectory) { - if (StringUtils.isEmpty(pathname)) { - throw new QiwenException("file name format error,pathname:" + pathname); - } +// if (StringUtils.isEmpty(pathname)) { +// throw new QiwenException("file name format error,pathname:" + pathname); +// } this.path = formatPath(pathname); this.isDirectory = isDirectory; } public QiwenFile(String parent, String child, boolean isDirectory) { - if (StringUtils.isEmpty(child)) { - throw new QiwenException("file name format error,parent:" + parent +", child:" + child); - } +// if (StringUtils.isEmpty(child)) { +// throw new QiwenException("file name format error,parent:" + parent +", child:" + child); +// } if (parent != null) { String parentPath = separator.equals(formatPath(parent)) ? "" : formatPath(parent); String childPath = formatPath(child); @@ -47,6 +47,9 @@ public class QiwenFile { if ("/".equals(path)) { return path; } + if (!path.startsWith(separator)) { + path = separator + path; + } if (path.endsWith("/")) { int length = path.length(); return path.substring(0, length - 1); diff --git a/src/main/java/com/qiwenshare/file/service/FiletransferService.java b/src/main/java/com/qiwenshare/file/service/FiletransferService.java index 87031f6..f11f2e8 100644 --- a/src/main/java/com/qiwenshare/file/service/FiletransferService.java +++ b/src/main/java/com/qiwenshare/file/service/FiletransferService.java @@ -1,6 +1,7 @@ package com.qiwenshare.file.service; import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; @@ -35,6 +36,7 @@ import com.qiwenshare.ufop.operation.upload.domain.UploadFileResult; import com.qiwenshare.ufop.util.UFOPUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -107,11 +109,8 @@ public class FiletransferService implements IFiletransferService { userFileMapper.insert(userFile); fileDealComp.uploadESByUserFileId(userFile.getUserFileId()); } catch (Exception e) { - log.warn("文件冲突重命名处理: {}", e.getMessage()); - String fileName = fileDealComp.getRepeatFileName(userFile, userFile.getFilePath()); - userFile.setFileName(fileName); - userFileMapper.insert(userFile); - fileDealComp.uploadESByUserFileId(userFile.getUserFileId()); + log.warn("极速上传文件冲突重命名处理: {}", JSON.toJSONString(userFile)); + } if (relativePath.contains("/")) { @@ -187,8 +186,12 @@ public class FiletransferService implements IFiletransferService { if (UploadFileStatusEnum.SUCCESS.equals(uploadFileResult.getStatus())){ FileBean fileBean = new FileBean(uploadFileResult); fileBean.setCreateUserId(userId); - fileMapper.insert(fileBean); - + try { + fileMapper.insert(fileBean); + } catch (Exception e) { + log.warn("identifier Duplicate: {}", fileBean.getIdentifier()); + fileBean = fileMapper.selectOne(new QueryWrapper().lambda().eq(FileBean::getIdentifier, fileBean.getIdentifier())); + } UserFile userFile = new UserFile(qiwenFile, userId, fileBean.getFileId()); @@ -197,11 +200,21 @@ public class FiletransferService implements IFiletransferService { userFileMapper.insert(userFile); fileDealComp.uploadESByUserFileId(userFile.getUserFileId()); } catch (Exception e) { - log.warn("文件冲突重命名处理: {}", e.getMessage()); - String fileName = fileDealComp.getRepeatFileName(userFile, userFile.getFilePath()); - userFile.setFileName(fileName); - userFileMapper.insert(userFile); - fileDealComp.uploadESByUserFileId(userFile.getUserFileId()); + UserFile userFile1 = userFileMapper.selectOne(new QueryWrapper().lambda() + .eq(UserFile::getUserId, userFile.getUserId()) + .eq(UserFile::getFilePath, userFile.getFilePath()) + .eq(UserFile::getFileName, userFile.getFileName()) + .eq(UserFile::getExtendName, userFile.getExtendName()) + .eq(UserFile::getDeleteFlag, userFile.getDeleteFlag()) + .eq(UserFile::getIsDir, userFile.getIsDir())); + FileBean file1 = fileMapper.selectById(userFile1.getFileId()); + if (!StringUtils.equals(fileBean.getIdentifier(), file1.getIdentifier())) { + log.warn("文件冲突重命名处理: {}", JSON.toJSONString(userFile1)); + String fileName = fileDealComp.getRepeatFileName(userFile, userFile.getFilePath()); + userFile.setFileName(fileName); + userFileMapper.insert(userFile); + fileDealComp.uploadESByUserFileId(userFile.getUserFileId()); + } } diff --git a/src/main/java/com/qiwenshare/file/service/UserFileService.java b/src/main/java/com/qiwenshare/file/service/UserFileService.java index c2b53b2..946eef0 100644 --- a/src/main/java/com/qiwenshare/file/service/UserFileService.java +++ b/src/main/java/com/qiwenshare/file/service/UserFileService.java @@ -21,6 +21,7 @@ import com.qiwenshare.file.mapper.RecoveryFileMapper; import com.qiwenshare.file.mapper.UserFileMapper; import com.qiwenshare.file.vo.file.FileListVO; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -30,6 +31,7 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.Executor; import java.util.concurrent.Executors; +import java.util.stream.Collectors; @Slf4j @Service @@ -212,12 +214,11 @@ public class UserFileService extends ServiceImpl imple updateFileDeleteStateByFilePath(filePath, uuid, sessionUserId); } else { - UserFile userFileTemp = userFileMapper.selectById(userFileId); LambdaUpdateWrapper userFileLambdaUpdateWrapper = new LambdaUpdateWrapper<>(); userFileLambdaUpdateWrapper.set(UserFile::getDeleteFlag, RandomUtil.randomInt(1, FileConstant.deleteFileRandomSize)) .set(UserFile::getDeleteTime, DateUtil.getCurrentTime()) .set(UserFile::getDeleteBatchNum, uuid) - .eq(UserFile::getUserFileId, userFileTemp.getUserFileId()); + .eq(UserFile::getUserFileId, userFileId); userFileMapper.update(null, userFileLambdaUpdateWrapper); } @@ -238,17 +239,20 @@ public class UserFileService extends ServiceImpl imple private void updateFileDeleteStateByFilePath(String filePath, String deleteBatchNum, String userId) { executor.execute(() -> { List fileList = selectUserFileByLikeRightFilePath(filePath, userId); - for (int i = 0; i < fileList.size(); i++) { - UserFile userFileTemp = fileList.get(i); + List userFileIds = fileList.stream().map(UserFile::getUserFileId).collect(Collectors.toList()); + //标记删除标志 + if (CollectionUtils.isNotEmpty(userFileIds)) { LambdaUpdateWrapper userFileLambdaUpdateWrapper1 = new LambdaUpdateWrapper<>(); userFileLambdaUpdateWrapper1.set(UserFile::getDeleteFlag, RandomUtil.randomInt(FileConstant.deleteFileRandomSize)) .set(UserFile::getDeleteTime, DateUtil.getCurrentTime()) .set(UserFile::getDeleteBatchNum, deleteBatchNum) - .eq(UserFile::getUserFileId, userFileTemp.getUserFileId()) + .in(UserFile::getUserFileId, userFileIds) .eq(UserFile::getDeleteFlag, 0); userFileMapper.update(null, userFileLambdaUpdateWrapper1); - + } + for (String userFileId : userFileIds) { + fileDealComp.deleteESByUserFileId(userFileId); } }); }