From 12a4d198a6d565292d0b80ca5004cd6329b3f4c8 Mon Sep 17 00:00:00 2001 From: chenxudong Date: Fri, 20 Dec 2024 14:15:07 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E4=BA=86=E9=83=A8?= =?UTF-8?q?=E5=88=86=E6=8E=A5=E5=8F=A3=EF=BC=8C=E6=8F=90=E4=BA=A4=E5=A4=87?= =?UTF-8?q?=E4=BB=BD=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/EdFileInfoController.java | 42 ++- .../manage/pojo/req/UpdateFileInfoDTO.java | 12 + .../manage/service/EdFileInfoService.java | 46 +++ .../service/serviceimpl/CommonService.java | 28 +- .../serviceimpl/EdFileInfoServiceImpl.java | 288 +++++++++++++++++- .../service/serviceimpl/EdPrjServiceImpl.java | 6 +- .../src/main/resources/application.properties | 9 +- .../common/cons/ElectromagneticConstants.java | 2 + 8 files changed, 396 insertions(+), 37 deletions(-) create mode 100644 electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/pojo/req/UpdateFileInfoDTO.java diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/EdFileInfoController.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/EdFileInfoController.java index 3c6af82..33a26dd 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/EdFileInfoController.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/EdFileInfoController.java @@ -1,14 +1,14 @@ package com.electromagnetic.industry.software.manage.controller; import com.electromagnetic.industry.software.common.resp.ElectromagneticResult; +import com.electromagnetic.industry.software.manage.pojo.req.FileChunkDTO; import com.electromagnetic.industry.software.manage.pojo.req.FileInfoQueryDTO; +import com.electromagnetic.industry.software.manage.pojo.req.UpdateFileInfoDTO; import com.electromagnetic.industry.software.manage.service.EdFileInfoService; +import io.swagger.annotations.ApiOperation; import org.springframework.core.io.InputStreamResource; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; @@ -52,13 +52,8 @@ public class EdFileInfoController { } @RequestMapping("updateFileInfo") - public ElectromagneticResult updateFileInfo() { - return null; - } - - @RequestMapping("deleteFile") - public ElectromagneticResult deleteFile() { - return null; + public ElectromagneticResult updateFileInfo(@RequestBody UpdateFileInfoDTO updateFileInfoDTO) { + return edFileInfoService.updateFileInfo(updateFileInfoDTO); } @RequestMapping("moveFile") @@ -77,12 +72,29 @@ public class EdFileInfoController { } @RequestMapping("versionBack") - public ElectromagneticResult versionBack() { - return null; + public ElectromagneticResult versionBack(@RequestParam String fileId, @RequestParam int targetVersion) { + return edFileInfoService.versionBack(fileId, targetVersion); } @RequestMapping("batchExport") - public ElectromagneticResult batchExport() { - return null; + public ResponseEntity batchExport(@RequestParam String dataIdArr, HttpServletResponse response) throws IOException { + return edFileInfoService.batchExport(dataIdArr, response); + } + + @RequestMapping(value = "/mergeChunks",method = RequestMethod.GET) + public ElectromagneticResult mergeChunks(@RequestParam String identifier, + @RequestParam String fileName, + @RequestParam Integer totalChunks) { + return edFileInfoService.mergeChunks(identifier, fileName, totalChunks); + } + + @RequestMapping(value = "/batchImport",method = RequestMethod.POST) + public ElectromagneticResult batchImport(FileChunkDTO fileChunkDTO) { + return edFileInfoService.batchImport(fileChunkDTO); + } + + @RequestMapping(value = "/batchImport",method = RequestMethod.GET) + public ElectromagneticResult checkChunkExist(FileChunkDTO fileChunkDTO) { + return edFileInfoService.checkChunkExist(fileChunkDTO); } } diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/pojo/req/UpdateFileInfoDTO.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/pojo/req/UpdateFileInfoDTO.java new file mode 100644 index 0000000..68d493b --- /dev/null +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/pojo/req/UpdateFileInfoDTO.java @@ -0,0 +1,12 @@ +package com.electromagnetic.industry.software.manage.pojo.req; + +import lombok.Data; + +@Data +public class UpdateFileInfoDTO { + + private String id; + private String fileName; + private String fileNote; + +} diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/EdFileInfoService.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/EdFileInfoService.java index ac7e497..8134528 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/EdFileInfoService.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/EdFileInfoService.java @@ -1,7 +1,9 @@ package com.electromagnetic.industry.software.manage.service; import com.electromagnetic.industry.software.common.resp.ElectromagneticResult; +import com.electromagnetic.industry.software.manage.pojo.req.FileChunkDTO; import com.electromagnetic.industry.software.manage.pojo.req.FileInfoQueryDTO; +import com.electromagnetic.industry.software.manage.pojo.req.UpdateFileInfoDTO; import org.springframework.core.io.InputStreamResource; import org.springframework.http.ResponseEntity; @@ -46,4 +48,48 @@ public interface EdFileInfoService { * @return */ ResponseEntity download(String id, HttpServletResponse response); + + /** + * 更新文件信息 + * @param updateFileInfoDTO + */ + ElectromagneticResult updateFileInfo(UpdateFileInfoDTO updateFileInfoDTO); + + /** + * 版本回退 + * @param fileId + * @param targetVersion + * @return + */ + ElectromagneticResult versionBack(String fileId, int targetVersion); + + /** + * 查看分片是否存在 + * @param fileChunkDTO + * @return + */ + ElectromagneticResult checkChunkExist(FileChunkDTO fileChunkDTO); + + /** + * 批量导入 + * @param fileChunkDTO + * @return + */ + ElectromagneticResult batchImport(FileChunkDTO fileChunkDTO); + + /** + * 合并分片 + * @param identifier + * @param fileName + * @param totalChunks + * @return + */ + ElectromagneticResult mergeChunks(String identifier, String fileName, Integer totalChunks); + + /** + * 导出 + * @param dataIdArr + * @return + */ + ResponseEntity batchExport(String dataIdArr, HttpServletResponse response) throws IOException; } diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/CommonService.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/CommonService.java index ebd6ad5..80b4899 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/CommonService.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/CommonService.java @@ -33,6 +33,7 @@ import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.io.File; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import static com.electromagnetic.industry.software.common.cons.ElectromagneticConstants.*; @@ -42,6 +43,9 @@ public class CommonService { private final EleLog log = new EleLog(CommonService.class); private static final Map FILE_TYPE_ENUM = new HashMap<>(); + + private static final Map ID_NAME = new ConcurrentHashMap<>(); + @Value("${prj.folder.max.length}") private int prjFolderMaxLength; @@ -98,11 +102,19 @@ public class CommonService { public String getFileSysPath(String dbPath) { ArrayList paths = CollUtil.newArrayList(dbPath.split(MYSQL_FILE_PATH_SPLIT)); - String path = getPath(paths); + String path = getDbPath(paths); return eleDataPath + File.separator + path; } - public String getPath(List ids) { + public String getDbPath(String dbPath) { + List paths = CollUtil.newArrayList(dbPath.split(MYSQL_FILE_PATH_SPLIT)); + return getDbPath(paths); + } + + public String getDbPath(List ids) { + + // TODO cache + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(EdFileInfo.class) .select(EdFileInfo::getId, EdFileInfo::getFileName) .in(EdFileInfo::getId, ids); @@ -128,7 +140,7 @@ public class CommonService { .likeRight(EdFileInfo::getFilePath, id)); } - public ElectromagneticResult addFolder(String parentId, String folderName, boolean maxLengthCheck, boolean isPrjDir) { + public ElectromagneticResult addFolder(String parentId, String folderName, boolean maxLengthCheck, boolean isPrjDir, String folderId) { // 验证名称是否合法 Assert.isTrue(EleCommonUtil.isFileNameValid(folderName), "文件名不符合规范,只能包含中文字符、下划线、连字符、加号、数字和英文字符且长度小于32。"); @@ -165,15 +177,13 @@ public class CommonService { } try { - int id = Integer.parseInt(edFileInfoMapper.maxPrjId()); Date now = new Date(); String currentUserId = UserThreadLocal.getUserId(); - String newFolderId = String.valueOf(id + 1); - String path = currentPath + MYSQL_FILE_PATH_SPLIT + newFolderId; + String path = currentPath + MYSQL_FILE_PATH_SPLIT + folderId; EdFileInfo fileInfo = new EdFileInfo(); String nowTimeStr = EleCommonUtil.getNowTimeStr(); - fileInfo.setId(newFolderId) - .setFileId(newFolderId) + fileInfo.setId(folderId) + .setFileId(folderId) .setFileName(folderName) .setFileVersion(FILE_START_VERSION) .setParentId(parentId) @@ -192,7 +202,7 @@ public class CommonService { .setUpdatedBy(currentUserId); edFileInfoMapper.insert(fileInfo); // 保存到文件系统 - String targetFilePath = getEleDataPath() + File.separator + getPath(paths) + File.separator + folderName; + String targetFilePath = getEleDataPath() + File.separator + getDbPath(paths) + File.separator + folderName; fileSystemService.createDirectory(targetFilePath); return ElectromagneticResultUtil.success(true); } catch (Exception e) { diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdFileInfoServiceImpl.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdFileInfoServiceImpl.java index 7316021..6361f3f 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdFileInfoServiceImpl.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdFileInfoServiceImpl.java @@ -2,44 +2,84 @@ package com.electromagnetic.industry.software.manage.service.serviceimpl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.codec.Base64; +import cn.hutool.core.collection.ListUtil; import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.IoUtil; import cn.hutool.core.lang.Assert; +import cn.hutool.core.text.StrFormatter; import cn.hutool.core.util.StrUtil; +import cn.hutool.core.util.ZipUtil; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.symmetric.AES; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.electromagnetic.industry.software.common.enums.EleDataTypeEnum; import com.electromagnetic.industry.software.common.exception.BizException; import com.electromagnetic.industry.software.common.resp.ElectromagneticResult; import com.electromagnetic.industry.software.common.util.EleLog; import com.electromagnetic.industry.software.common.util.ElectromagneticResultUtil; +import com.electromagnetic.industry.software.common.util.IdWorker; +import com.electromagnetic.industry.software.common.util.UserThreadLocal; import com.electromagnetic.industry.software.manage.mapper.EdFileInfoMapper; import com.electromagnetic.industry.software.manage.pojo.models.EdFileInfo; import com.electromagnetic.industry.software.manage.pojo.other.FileInfoDTO; +import com.electromagnetic.industry.software.manage.pojo.req.FileChunkDTO; +import com.electromagnetic.industry.software.manage.pojo.req.FileChunkResultDTO; import com.electromagnetic.industry.software.manage.pojo.req.FileInfoQueryDTO; +import com.electromagnetic.industry.software.manage.pojo.req.UpdateFileInfoDTO; import com.electromagnetic.industry.software.manage.pojo.resp.FileInfoQueryPageVO; import com.electromagnetic.industry.software.manage.service.EdFileInfoService; +import com.electromagnetic.industry.software.manage.service.FileSystemService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.InputStreamResource; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import javax.annotation.PostConstruct; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.net.BindException; -import java.util.List; -import java.util.Objects; +import java.io.*; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.*; +import java.util.stream.Collectors; + +import static com.electromagnetic.industry.software.common.cons.ElectromagneticConstants.*; @Service public class EdFileInfoServiceImpl extends ServiceImpl implements EdFileInfoService { @Resource private CommonService commonService; - private EleLog log = new EleLog(EdFileInfoServiceImpl.class); + @Autowired + private FileSystemService fileSystemService; + @Resource + private Environment environment; + + private String downloadDataDir = ""; + private String uploadDataDir = ""; + + + @Value("${file.security.passwd}") + private String password; + + + @PostConstruct + public void init() { + String osName = System.getProperty("os.name").toLowerCase(); + uploadDataDir = osName.startsWith("win") ? environment.getProperty("data.upload.windows.tmp.path") : environment.getProperty("data.upload.linux.tmp.path"); + downloadDataDir = osName.startsWith("win") ? environment.getProperty("data.download.windows.tmp.path") : environment.getProperty("data.download.linux.tmp.path"); + } /** * 查询文件列表 @@ -86,12 +126,12 @@ public class EdFileInfoServiceImpl extends ServiceImpl createFolder(String parentId, String newFolderName) { - return commonService.addFolder(parentId, newFolderName, false, false); + String folderId = IdWorker.getSnowFlakeIdString(); + return commonService.addFolder(parentId, newFolderName, false, false, folderId); } /** * 项目层级结构查询 - * * @return */ @Override @@ -121,7 +161,6 @@ public class EdFileInfoServiceImpl extends ServiceImpl updateFileInfo(UpdateFileInfoDTO updateFileInfoDTO) { + try { + EdFileInfo fileInfo = this.baseMapper.selectById(updateFileInfoDTO.getId()); + this.baseMapper.update(null, Wrappers.lambdaUpdate(EdFileInfo.class) + .eq(EdFileInfo::getId, updateFileInfoDTO.getId()) + .set(EdFileInfo::getFileName, updateFileInfoDTO.getFileName()) + .set(EdFileInfo::getFileNote, updateFileInfoDTO.getFileNote())); + String sysFilePath = commonService.getFileSysPath(fileInfo.getFilePath()); + fileSystemService.renameFile(sysFilePath, updateFileInfoDTO.getFileName()); + return ElectromagneticResultUtil.success(true); + } catch (Exception e) { + String info = "更新文件信息失败。"; + log.error(info, e); + throw new BizException(-1, e.getMessage()); + } + } + + /** + * 版本回退 + * + * @param fileId + * @param targetVersion + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public ElectromagneticResult versionBack(String fileId, int targetVersion) { + + try { + this.baseMapper.update(null, Wrappers.lambdaUpdate(EdFileInfo.class) + .set(EdFileInfo::getFileId, fileId) + .set(EdFileInfo::getEffectFlag, false)); + this.baseMapper.update(null, Wrappers.lambdaUpdate(EdFileInfo.class) + .set(EdFileInfo::getEffectFlag, true) + .eq(EdFileInfo::getFileId, fileId) + .eq(EdFileInfo::getFileVersion, targetVersion)); + } catch (Exception e) { + String info = "版本回退失败。"; + log.error(info, e); + throw new BizException(-1, info); + } + return ElectromagneticResultUtil.success(true); + } + + /** + * 查看分片是否存在 + * @param fileChunkDTO + * @return + */ + @Override + public ElectromagneticResult checkChunkExist(FileChunkDTO fileChunkDTO) { + String currentUserId = UserThreadLocal.getUserId(); + String userUploadFolder = uploadDataDir + File.separator + currentUserId; + String identifier = fileChunkDTO.getIdentifier(); + List uploadedChunks = getUploadedChunks(identifier, userUploadFolder); + return ElectromagneticResultUtil.success(new FileChunkResultDTO(false, new HashSet<>(uploadedChunks))); + } + + private List getUploadedChunks(String identifier, String destPath) { + String filePath = destPath + File.separator + identifier; + if (!FileUtil.exist(new File(filePath))) { + return new ArrayList<>(); + } + + return FileUtil.listFileNames(destPath) + .stream() + .map(e -> e.replace(UPLOAD_FILE_CHUNK_SUFFIX, "")) + .map(Integer::parseInt) + .collect(Collectors.toList()); + } + + /** + * 批量导入 + * @param fileChunkDTO + * @return + */ + @Override + public ElectromagneticResult batchImport(FileChunkDTO fileChunkDTO) { + String currentUserId = UserThreadLocal.getUserId(); + String identifier = fileChunkDTO.getIdentifier(); + // 首先检查该分片有没被上传,如果有则禁止上传 + String destPath = uploadDataDir + File.separator + currentUserId + File.separator + identifier + fileChunkDTO.getChunkNumber() + UPLOAD_FILE_CHUNK_SUFFIX; + boolean exist = FileUtil.exist(destPath); + if (exist) { + return ElectromagneticResultUtil.fail("-1", "文件已经存在,请勿重复上传"); + } + try ( + InputStream inputStream = fileChunkDTO.getFile().getInputStream(); + FileOutputStream fileOutputStream = new FileOutputStream(destPath); + ) { + IoUtil.copy(inputStream, fileOutputStream); + } catch (IOException ioException) { + log.error("上传文件失败...", ioException); + throw new BizException(-1, "上传文件失败"); + } + return ElectromagneticResultUtil.success(fileChunkDTO.getIdentifier()); + } + + /** + * 合并分片 + * @param identifier + * @param fileName + * @param totalChunks + * @return + */ + @Override + public ElectromagneticResult mergeChunks(String identifier, String fileName, Integer totalChunks) { + String destZipPath = doSysFileMerge(identifier, fileName, totalChunks); + int index = destZipPath.lastIndexOf(".zip"); + String zipDirPath = destZipPath.substring(0, index); + AES aes = SecureUtil.aes(password.getBytes()); + try( + InputStream inputStream = Files.newInputStream(Paths.get(destZipPath)); + OutputStream outputStream = Files.newOutputStream(Paths.get(zipDirPath)); + ) { + aes.decrypt(inputStream, outputStream, true); + } catch (Exception e) { + String info = "文件上传错误"; + log.error(info, e); + throw new BizException(-1, e.getMessage()); + } + update2Database(zipDirPath); + return null; + } + + /** + * 导出 + * + * @param dataIdArr + * @return + */ + @Override + public ResponseEntity batchExport(String dataIdArr, HttpServletResponse response) throws IOException { + String[] ids = dataIdArr.split(","); + List resFiles = new ArrayList<>(); + for (String id : ids) { + List edFileInfos = this.baseMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class) + .like(EdFileInfo::getFilePath, MYSQL_FILE_PATH_SPLIT + id + MYSQL_FILE_PATH_SPLIT) + .eq(EdFileInfo::getEffectFlag, true)); + resFiles.addAll(edFileInfos); + } + String prjName = resFiles.stream().filter(e -> e.getParentId().equals(PRJ_PARENT_ID)).findFirst().get().getFileName(); + List folders = resFiles.stream().filter(e -> e.getDataType().equals(EleDataTypeEnum.FOLDER.code)).collect(Collectors.toList()); + List files = resFiles.stream().filter(e -> e.getDataType().equals(EleDataTypeEnum.FILE.code)).collect(Collectors.toList()); + for (EdFileInfo edFileInfo : folders) { + String destFolderPath = downloadDataDir + File.separator + commonService.getFileSysPath(edFileInfo.getFileId()); + FileUtil.mkdir(destFolderPath); + } + for (EdFileInfo edFileInfo : files) { + String filePath = commonService.getFileSysPath(edFileInfo.getFileId()) + edFileInfo.getFileCode() + "." + edFileInfo.getFileCode(); + String destPath = downloadDataDir + File.separator + commonService.getDbPath(edFileInfo.getFileId()); + FileUtil.copy(filePath, destPath, false); + } + String mysqlInfo = getMysqlInfo(); + FileUtil.writeString(mysqlInfo, downloadDataDir + File.separator + "mysql.info", Charset.defaultCharset()); + String exportZipFile = downloadDataDir + File.separator + prjName + ".zip"; + String exportColibFile = downloadDataDir + File.separator + prjName + EXPORT_FILE_SUFFIX; + ZipUtil.zip(downloadDataDir + File.separator + prjName, exportZipFile); + AES aes = SecureUtil.aes(password.getBytes()); + try( + InputStream inputStream = Files.newInputStream(Paths.get(exportZipFile)); + OutputStream outputStream = Files.newOutputStream(Paths.get(exportColibFile)); + ) { + aes.encrypt(inputStream, outputStream, true); + } catch (Exception e) { + String info = "导出失败。"; + log.error(info, e); + throw new BizException(-1, info); + } finally { + FileUtil.del(exportZipFile); + } + File file = new File(exportColibFile); + FileSystemResource fileSystemResource = new FileSystemResource(file); + + HttpHeaders headers = new HttpHeaders(); + headers.add("Cache-Control", "no-cache, no-store, must-revalidate"); + String fileName = Base64.encode(fileSystemResource.getFilename()); + headers.add("Pragma", "no-cache"); + headers.add("Expires", "0"); + response.setHeader("content-disposition","attachment;filename=" + fileName); + + // 构建响应实体(可以返回 FileUtil.del(e.getAbsolutePath())); + return destZipPath; + } } diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdPrjServiceImpl.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdPrjServiceImpl.java index 99cf88e..9ea77a9 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdPrjServiceImpl.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdPrjServiceImpl.java @@ -198,7 +198,6 @@ public class EdPrjServiceImpl extends ServiceImpl /** * 添加子集 - * * @param parentId * @param folderName * @return @@ -206,12 +205,13 @@ public class EdPrjServiceImpl extends ServiceImpl @Override @Transactional(rollbackFor = Exception.class) public ElectromagneticResult addFolder(String parentId, String folderName) { - return commonService.addFolder(parentId, folderName, true, true); + int id = Integer.parseInt(this.baseMapper.maxPrjId()); + String folderId = String.valueOf(id + 1); + return commonService.addFolder(parentId, folderName, true, true, folderId); } /** * 查询所有项目 - * * @return */ @Override diff --git a/electrmangnetic/src/main/resources/application.properties b/electrmangnetic/src/main/resources/application.properties index a7b155a..b63fb91 100644 --- a/electrmangnetic/src/main/resources/application.properties +++ b/electrmangnetic/src/main/resources/application.properties @@ -13,8 +13,13 @@ spring.servlet.multipart.max-request-size=10MB pagehelper.helperDialect=mysql pagehelper.reasonable=false server.port=12395 +file.security.passwd=adknfhkj87654knd #windows文件存储目录,用于测试 -data.windows.path=E:/tmp/eleData/ -data.linux.path=/szsd/data/eleData +data.windows.path=D:/tmp/eleData/project/ +data.linux.path=/szsd/data/eleData/project/ +data.upload.windows.tmp.path=D:/tmp/eleData/upload/ +data.upload.linux.tmp.path=/szsd/data/eleData/upload/ +data.download.windows.tmp.path=D:/tmp/eleData/download/ +data.download.linux.tmp.path=/szsd/data/eleData/download/ prj.folder.max.length=6 diff --git a/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/cons/ElectromagneticConstants.java b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/cons/ElectromagneticConstants.java index f07299c..c304a15 100644 --- a/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/cons/ElectromagneticConstants.java +++ b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/cons/ElectromagneticConstants.java @@ -9,4 +9,6 @@ public interface ElectromagneticConstants { int FILE_START_VERSION = 100; String PRJ_PARENT_ID = "0"; + + String UPLOAD_FILE_CHUNK_SUFFIX = ".part"; } From 4cd57f64b41be6e746d839baab0a0d0f778d2368 Mon Sep 17 00:00:00 2001 From: chenxudong Date: Mon, 23 Dec 2024 16:46:14 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0=E3=80=81=E5=A4=8D=E5=88=B6=E5=92=8C=E7=A7=BB?= =?UTF-8?q?=E5=8A=A8=E7=9A=84=E6=8E=A5=E5=8F=A3=EF=BC=8C=E5=85=B6=E4=BD=99?= =?UTF-8?q?=E5=BE=85=E5=AE=8C=E6=88=90=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/EdFileInfoController.java | 25 +- .../manage/pojo/models/EdFileInfo.java | 22 ++ .../manage/pojo/resp/FileVersionViewVO.java | 13 + .../manage/service/EdFileInfoService.java | 33 ++ .../service/serviceimpl/CommonService.java | 13 + .../serviceimpl/EdFileInfoServiceImpl.java | 289 +++++++++++++++++- .../serviceimpl/FileSystemServiceImpl.java | 1 + .../software/common/util/EleCommonUtil.java | 4 +- 8 files changed, 379 insertions(+), 21 deletions(-) create mode 100644 electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/pojo/resp/FileVersionViewVO.java diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/EdFileInfoController.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/EdFileInfoController.java index 33a26dd..b514500 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/EdFileInfoController.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/controller/EdFileInfoController.java @@ -9,6 +9,7 @@ import io.swagger.annotations.ApiOperation; import org.springframework.core.io.InputStreamResource; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; @@ -42,8 +43,10 @@ public class EdFileInfoController { } @RequestMapping("upload") - public ElectromagneticResult upload() { - return null; + public ElectromagneticResult upload(@RequestParam("parentId") String parentId, + @RequestParam("file") MultipartFile file, + @RequestParam("strategy") Integer strategy) { + return edFileInfoService.upload(parentId, file, strategy); } @RequestMapping("download") @@ -57,19 +60,23 @@ public class EdFileInfoController { } @RequestMapping("moveFile") - public ElectromagneticResult moveFile() { - return null; + public ElectromagneticResult moveFile(@RequestParam("id") String id, + @RequestParam("targetFolderId") String targetFolderId, + @RequestParam("strategy") Integer strategy) { + return edFileInfoService.moveFile(id, targetFolderId, strategy); } @RequestMapping("copyFile") - public ElectromagneticResult copyFile() { - return null; + public ElectromagneticResult copyFile(@RequestParam("id") String id, + @RequestParam("targetFolderId") String targetFolderId, + @RequestParam("strategy") Integer strategy) { + return edFileInfoService.copyFile(id, targetFolderId, strategy); } @RequestMapping("versionView") - public ElectromagneticResult versionView() { - return null; - } + public ElectromagneticResult versionView(@RequestParam String fileId) { + return edFileInfoService.versionView(fileId); + } @RequestMapping("versionBack") public ElectromagneticResult versionBack(@RequestParam String fileId, @RequestParam int targetVersion) { diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/pojo/models/EdFileInfo.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/pojo/models/EdFileInfo.java index 2c6a826..561bdd6 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/pojo/models/EdFileInfo.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/pojo/models/EdFileInfo.java @@ -2,17 +2,39 @@ package com.electromagnetic.industry.software.manage.pojo.models; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; +import com.electromagnetic.industry.software.common.enums.EffectFlagEnum; +import com.electromagnetic.industry.software.common.util.EleCommonUtil; +import com.electromagnetic.industry.software.common.util.IdWorker; +import com.electromagnetic.industry.software.common.util.UserThreadLocal; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import lombok.experimental.FieldNameConstants; +import java.util.Date; + @EqualsAndHashCode(callSuper = true) @TableName("ed_file_info") @Accessors(chain = true) @Data @FieldNameConstants public class EdFileInfo extends BaseModel { + + public void newInit() { + String userId = UserThreadLocal.getUserId(); + String newFileDbId = IdWorker.getSnowFlakeIdString(); + String fileTime = EleCommonUtil.getNowTimeStr(); + Date now = new Date(); + this.setUpdatedBy(userId); + this.setId(newFileDbId); + this.setUpdateTime(now); + this.setCreatedTime(now); + this.setFileTime(fileTime); + this.setCreatedBy(userId); + this.setFileId(newFileDbId); + this.setEffectFlag(EffectFlagEnum.EFFECT.code); + } + /** * 主键ID */ diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/pojo/resp/FileVersionViewVO.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/pojo/resp/FileVersionViewVO.java new file mode 100644 index 0000000..dd48a27 --- /dev/null +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/pojo/resp/FileVersionViewVO.java @@ -0,0 +1,13 @@ +package com.electromagnetic.industry.software.manage.pojo.resp; + +import lombok.Data; + +@Data +public class FileVersionViewVO { + private String id; + private String fileName; + private Integer fileVersion; + private Integer preVersion; + private String fileCode; + private Integer effectFlag; +} diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/EdFileInfoService.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/EdFileInfoService.java index 8134528..52ad34c 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/EdFileInfoService.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/EdFileInfoService.java @@ -6,6 +6,7 @@ import com.electromagnetic.industry.software.manage.pojo.req.FileInfoQueryDTO; import com.electromagnetic.industry.software.manage.pojo.req.UpdateFileInfoDTO; import org.springframework.core.io.InputStreamResource; import org.springframework.http.ResponseEntity; +import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @@ -92,4 +93,36 @@ public interface EdFileInfoService { * @return */ ResponseEntity batchExport(String dataIdArr, HttpServletResponse response) throws IOException; + + /** + * 文件上传 + * @param parentId + * @param file + * @param strategy + * @return + */ + ElectromagneticResult upload(String parentId, MultipartFile file, Integer strategy); + + /** + * 版本查看 + * @param fileId + * @return + */ + ElectromagneticResult versionView(String fileId); + + /** + * 移动文件 + * @param id + * @param targetFolderId + * @return + */ + ElectromagneticResult moveFile(String id, String targetFolderId, Integer strategy); + + /** + * 复制文件 + * @param id + * @param targetFolderId + * @return + */ + ElectromagneticResult copyFile(String id, String targetFolderId, Integer strategy); } diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/CommonService.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/CommonService.java index 80b4899..2d6fbd5 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/CommonService.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/CommonService.java @@ -6,7 +6,9 @@ import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.TreeNodeConfig; import cn.hutool.core.lang.tree.TreeUtil; import cn.hutool.core.text.StrFormatter; +import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; +import com.baomidou.mybatisplus.core.MybatisConfiguration; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; @@ -304,4 +306,15 @@ public class CommonService { throw new BizException(-1, info); } } + + public String getCodePathByDbPath(String dbPath) { + List paths = StrUtil.split(dbPath, MYSQL_FILE_PATH_SPLIT); + List reversePaths = CollUtil.reverse(paths); + for (String path : reversePaths) { + if (path.length() == 6) { + return path; + } + } + return null; + } } diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdFileInfoServiceImpl.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdFileInfoServiceImpl.java index 6361f3f..95927a4 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdFileInfoServiceImpl.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/EdFileInfoServiceImpl.java @@ -2,7 +2,7 @@ package com.electromagnetic.industry.software.manage.service.serviceimpl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.codec.Base64; -import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IoUtil; import cn.hutool.core.lang.Assert; @@ -11,17 +11,17 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.ZipUtil; import cn.hutool.crypto.SecureUtil; import cn.hutool.crypto.symmetric.AES; +import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.electromagnetic.industry.software.common.enums.EffectFlagEnum; import com.electromagnetic.industry.software.common.enums.EleDataTypeEnum; +import com.electromagnetic.industry.software.common.enums.PublishEnum; import com.electromagnetic.industry.software.common.exception.BizException; import com.electromagnetic.industry.software.common.resp.ElectromagneticResult; -import com.electromagnetic.industry.software.common.util.EleLog; -import com.electromagnetic.industry.software.common.util.ElectromagneticResultUtil; -import com.electromagnetic.industry.software.common.util.IdWorker; -import com.electromagnetic.industry.software.common.util.UserThreadLocal; +import com.electromagnetic.industry.software.common.util.*; import com.electromagnetic.industry.software.manage.mapper.EdFileInfoMapper; import com.electromagnetic.industry.software.manage.pojo.models.EdFileInfo; import com.electromagnetic.industry.software.manage.pojo.other.FileInfoDTO; @@ -30,6 +30,7 @@ import com.electromagnetic.industry.software.manage.pojo.req.FileChunkResultDTO; import com.electromagnetic.industry.software.manage.pojo.req.FileInfoQueryDTO; import com.electromagnetic.industry.software.manage.pojo.req.UpdateFileInfoDTO; import com.electromagnetic.industry.software.manage.pojo.resp.FileInfoQueryPageVO; +import com.electromagnetic.industry.software.manage.pojo.resp.FileVersionViewVO; import com.electromagnetic.industry.software.manage.service.EdFileInfoService; import com.electromagnetic.industry.software.manage.service.FileSystemService; import org.springframework.beans.factory.annotation.Autowired; @@ -42,6 +43,7 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.PostConstruct; import javax.annotation.Resource; @@ -169,7 +171,7 @@ public class EdFileInfoServiceImpl extends ServiceImpllambdaQuery().eq(EdFileInfo::getId, id)); - String fileSysPath = commonService.getFileSysPath(fileInfo.getFilePath()); + String fileSysPath = commonService.getFileSysPath(fileInfo.getFilePath()) + "." + fileInfo.getFileCode(); Assert.isTrue(FileUtil.exist(fileSysPath), "下载文件不存在。"); FileSystemResource fileSystemResource = new FileSystemResource(fileSysPath); HttpHeaders headers = new HttpHeaders(); @@ -304,6 +306,7 @@ public class EdFileInfoServiceImpl extends ServiceImpl mergeChunks(String identifier, String fileName, Integer totalChunks) { String destZipPath = doSysFileMerge(identifier, fileName, totalChunks); int index = destZipPath.lastIndexOf(".zip"); @@ -320,9 +323,35 @@ public class EdFileInfoServiceImpl extends ServiceImpl upload(String parentId, MultipartFile file, Integer strategy) { + // 首先检查是否是同名文件 + try { + String fileName = file.getOriginalFilename(); + String mainName = FileUtil.mainName(fileName); + String suffix = FileUtil.getSuffix(fileName); + Assert.isTrue(EleCommonUtil.isFileNameValid(fileName), "文件名不符合规范,只能包含中文字符、下划线、连字符、加号、数字和英文字符且长度小于32。"); + Long count = this.baseMapper.selectCount(Wrappers.lambdaQuery(EdFileInfo.class) + .eq(EdFileInfo::getParentId, parentId) + .eq(EdFileInfo::getFileName, mainName) + .eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code) + .eq(EdFileInfo::getFileType, suffix)); + if (count > 0) { + handUploadRepeatFile(parentId, file, strategy); + } else { + EdFileInfo parentFolderInfo = this.baseMapper.selectOne(Wrappers.lambdaQuery(EdFileInfo.class) + .eq(EdFileInfo::getId, parentId) + .eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code)); + EdFileInfo newEdFileInfo = new EdFileInfo(); + newEdFileInfo.newInit(); + String codePathByDbPath = commonService.getCodePathByDbPath(parentFolderInfo.getFilePath()); + String fileCode = commonService.createFileCode(codePathByDbPath, suffix, FILE_START_VERSION, newEdFileInfo.getFileTime()); + newEdFileInfo.setParentId(parentId) + .setFileCode(fileCode) + .setFileName(mainName) + .setFileType(suffix) + .setFileVersion(FILE_START_VERSION) + .setFileSize(file.getSize()) + .setFilePath(parentFolderInfo.getFilePath() + MYSQL_FILE_PATH_SPLIT + newEdFileInfo.getId()) + .setDataType(EleDataTypeEnum.FILE.code) + .setDataStatus(PublishEnum.PUBLISHED.getCode()) + .setEffectFlag(EffectFlagEnum.EFFECT.code) + .setFileCode(fileCode) + .setPrjDir(false); + this.baseMapper.insert(newEdFileInfo); + String fileDestPath = commonService.getFileSysPath(parentFolderInfo.getFileId()) + File.separator + mainName + suffix + "." + fileCode; + fileSystemService.save(file.getInputStream(), fileDestPath); + } + } catch (Exception e) { + String info = "上传文件失败"; + log.error(info, e); + throw new BizException(-1, info); + } + return ElectromagneticResultUtil.success(true); } - private void update2Database(String zipDirPath) { - // TODO 注意 需要reversion + /** + * 版本查看 + * + * @param fileId + * @return + */ + @Override + public ElectromagneticResult versionView(String fileId) { + List edFileInfos = this.baseMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class) + .select(EdFileInfo::getId, EdFileInfo::getFileId, EdFileInfo::getFileVersion, EdFileInfo::getPreVersion, EdFileInfo::getFileCode, EdFileInfo::getEffectFlag) + .eq(EdFileInfo::getFileId, fileId)); + List fileVersionViewVOS = BeanUtil.copyToList(edFileInfos, FileVersionViewVO.class); + return ElectromagneticResultUtil.success(fileVersionViewVOS); } + /** + * 移动文件 + * + * @param id + * @param targetFolderId + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public ElectromagneticResult moveFile(String id, String targetFolderId, Integer strategy) { + return moveFile(id, targetFolderId, strategy, true); + } + + private void handMoveConflict(String targetFolderId, Integer strategy, EdFileInfo srcFileInfo, EdFileInfo destFolderInfo, boolean deleteSrc) { + if (strategy == 2) { + // 做版本更新 + List sameFileInfos = this.baseMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class) + .eq(EdFileInfo::getParentId, targetFolderId) + .eq(EdFileInfo::getFileName, srcFileInfo.getFileName()) + .eq(EdFileInfo::getFileType, srcFileInfo.getFileType())); + Integer maxFileVersion = Collections.max(sameFileInfos, Comparator.comparing(EdFileInfo::getFileVersion)).getFileVersion(); + String newFileDbId = IdWorker.getSnowFlakeIdString(); + String fileTime = EleCommonUtil.getNowTimeStr(); + String fileCode = commonService.createFileCode(targetFolderId, srcFileInfo.getFileType(), maxFileVersion + 1, fileTime); + EdFileInfo destSaveFileInfo = BeanUtil.copyProperties(sameFileInfos.get(0), EdFileInfo.class); + destSaveFileInfo.newInit(); + destSaveFileInfo.setFileVersion(maxFileVersion + 1) + .setFilePath(destSaveFileInfo + MYSQL_FILE_PATH_SPLIT + newFileDbId) + .setPreVersion(maxFileVersion) + .setEffectFlag(EffectFlagEnum.EFFECT.code) + .setFileCode(fileCode); + this.baseMapper.insert(destSaveFileInfo); + } else if (strategy == 3) { + // 文件名加“_1”,版本号从100开始 + // 处理MySQL相关逻辑 + EdFileInfo newEdFileInfo = BeanUtil.copyProperties(srcFileInfo, EdFileInfo.class); + newEdFileInfo.newInit(); + newEdFileInfo.setParentId(targetFolderId) + .setFileVersion(FILE_START_VERSION) + .setFileName(srcFileInfo.getFileName() + "_1") + .setFileCode(commonService.createFileCode(targetFolderId, srcFileInfo.getFileType(), FILE_START_VERSION, newEdFileInfo.getFileTime())) + .setFilePath(destFolderInfo.getFilePath() + MYSQL_FILE_PATH_SPLIT + newEdFileInfo.getId()); + this.baseMapper.insert(newEdFileInfo); + // 移动文件 + String srcFileSysPath = commonService.getFileSysPath(srcFileInfo.getFilePath()); + String destFileSysPath = commonService.getFileSysPath(destFolderInfo.getFilePath()); + fileSystemService.moveFile(srcFileSysPath, destFileSysPath); + } + } + + private ElectromagneticResult moveFile(String id, String targetFolderId, Integer strategy, boolean deleteSrc) { + // 获取原文件mysql模型 + EdFileInfo srcFileInfo = this.baseMapper.selectById(id); + // 判断目标路径下是否有同名文件,如果所有的同名文件:1)如果所有文件都已经被作废,则该文件为新文件,版本号从100开始。2)如果有没有被作废的文件,则冲突处理方式按---1-跳过冲突文件 2-做版本更新 3-重命名,文件名加"_1" + List destFolderFiles = this.baseMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class).eq(EdFileInfo::getParentId, targetFolderId)); + EdFileInfo destFolderInfo = this.baseMapper.selectOne(Wrappers.lambdaQuery(EdFileInfo.class).eq(EdFileInfo::getId, targetFolderId)); + List effectFileInfos = destFolderFiles.stream().filter(e -> Objects.equals(e.getEffectFlag(), EffectFlagEnum.EFFECT.code)).collect(Collectors.toList()); + if (CollUtil.isEmpty(effectFileInfos) || CollUtil.isEmpty(destFolderFiles)) { + // 没有同名文件 + // 首先将信息保存到MySQL + EdFileInfo destSaveFileInfo = BeanUtil.copyProperties(srcFileInfo, EdFileInfo.class); + destSaveFileInfo.newInit(); + String fileTime = EleCommonUtil.getNowTimeStr(); + String newFileCode = commonService.createFileCode(targetFolderId, srcFileInfo.getFileType(), FILE_START_VERSION, fileTime); + destSaveFileInfo.setParentId(targetFolderId) + .setFileVersion(FILE_START_VERSION) + .setFileTime(fileTime) + .setFilePath(destFolderInfo.getFilePath() + MYSQL_FILE_PATH_SPLIT + destSaveFileInfo.getId()) + .setFileCode(newFileCode); + this.baseMapper.insert(destSaveFileInfo); + // 文件系统移动文件 + String srcFilePath = commonService.getFileSysPath(srcFileInfo.getFileId()) + File.separator + srcFileInfo.getFileCode(); + String destFilePath = commonService.getFileSysPath(destFolderInfo.getFileId()) + File.separator + destFolderInfo.getFileCode(); + fileSystemService.moveFile(srcFilePath, destFilePath); + } else { + handMoveConflict(targetFolderId, strategy, srcFileInfo, destFolderInfo, deleteSrc); + } + // 将以前的版本effect全部置为false,删除原目录下的同名文件 + if (deleteSrc) { + this.baseMapper.update(null, Wrappers.lambdaUpdate(EdFileInfo.class) + .set(EdFileInfo::getEffectFlag, EffectFlagEnum.NOT_EFFECTIVE.code) + .eq(EdFileInfo::getParentId, srcFileInfo.getParentId()) + .eq(EdFileInfo::getFileName, srcFileInfo.getFileName()) + .eq(EdFileInfo::getFileType, srcFileInfo.getFileType())); + } + return null; + } + + /** + * 复制文件 + * @param id + * @param targetFolderId + * @return + */ + @Override + public ElectromagneticResult copyFile(String id, String targetFolderId, Integer strategy) { + return moveFile(id, targetFolderId, strategy, false); + } + + private void handUploadRepeatFile(String parentId, MultipartFile file, Integer strategy) throws IOException { + Assert.isTrue(Arrays.asList(1, 2, 3).contains(strategy), "解决同名文件参数错误"); + String fileName = file.getOriginalFilename(); + String mainName = FileUtil.mainName(fileName); + String suffix = FileUtil.getSuffix(fileName); + if (strategy == 2) { + // 版本更新 + // step1:找到同名文件的MySQL对象 + List parentFileInfos = this.baseMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class) + .eq(EdFileInfo::getParentId, parentId) + .eq(EdFileInfo::getFileName, mainName) + .eq(EdFileInfo::getFileType, suffix)); + EdFileInfo parentFileInfo = this.baseMapper.selectOne(Wrappers.lambdaQuery(EdFileInfo.class) + .eq(EdFileInfo::getId, parentId) + .eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code)); + Integer maxFileVersion = Collections.max(parentFileInfos, Comparator.comparing(EdFileInfo::getFileVersion)).getFileVersion(); + // 找到当前展示的版本 + EdFileInfo effectFileInfo = parentFileInfos.stream().filter(e -> e.getEffectFlag().equals(true)).collect(Collectors.toList()).get(0); + String codePathByDbPath = commonService.getCodePathByDbPath(effectFileInfo.getFilePath()); + String timeStr = EleCommonUtil.getNowTimeStr(); + String fileCode = commonService.createFileCode(codePathByDbPath, suffix, FILE_START_VERSION, timeStr); + // 将原有效的版本置为false + this.baseMapper.update(null, Wrappers.lambdaUpdate(EdFileInfo.class) + .set(EdFileInfo::getEffectFlag, EffectFlagEnum.NOT_EFFECTIVE.code) + .eq(EdFileInfo::getId, effectFileInfo.getId())); + // 新增文件 + EdFileInfo newEdFileInfo = new EdFileInfo(); + newEdFileInfo.newInit(); + newEdFileInfo.setFileId(effectFileInfo.getFileId()) + .setParentId(parentId) + .setFileCode(fileCode) + .setFileName(mainName) + .setFileType(suffix) + .setFileContent("") + .setFileVersion(maxFileVersion + 1) + .setPreVersion(maxFileVersion) + .setFileNote("") + .setFileTime(timeStr) + .setFileSize(file.getSize()) + .setFilePath(parentFileInfo.getFilePath() + MYSQL_FILE_PATH_SPLIT + newEdFileInfo.getId()) + .setDataType(EleDataTypeEnum.FILE.code) + .setDataStatus(PublishEnum.PUBLISHED.getCode()) + .setEffectFlag(EffectFlagEnum.EFFECT.code) + .setFileCode(fileCode) + .setPrjDir(false); + this.baseMapper.insert(newEdFileInfo); + String fileDestPath = commonService.getFileSysPath(newEdFileInfo.getFileId()) + File.separator + mainName + suffix + "." + fileCode; + FileUtil.writeFromStream(file.getInputStream(), fileDestPath); + } else if (strategy == 3) { + // 文件名加”_1“,存为新文件 + EdFileInfo parentFileInfo = this.baseMapper.selectOne(Wrappers.lambdaQuery(EdFileInfo.class) + .eq(EdFileInfo::getId, parentId) + .eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code)); + String codePathByDbPath = commonService.getCodePathByDbPath(parentFileInfo.getFilePath()); + EdFileInfo newEdFileInfo = new EdFileInfo(); + newEdFileInfo.newInit(); + String fileCode = commonService.createFileCode(codePathByDbPath, suffix, FILE_START_VERSION, newEdFileInfo.getFileTime()); + newEdFileInfo.setParentId(parentId) + .setFileCode(fileCode) + .setFileName(mainName + "_1") + .setFileType(suffix) + .setFileVersion(FILE_START_VERSION) + .setFileTime(newEdFileInfo.getFileTime()) + .setFileSize(file.getSize()) + .setFilePath(parentFileInfo.getFilePath() + MYSQL_FILE_PATH_SPLIT + newEdFileInfo.getId()) + .setDataType(EleDataTypeEnum.FILE.code) + .setDataStatus(PublishEnum.PUBLISHED.getCode()) + .setEffectFlag(EffectFlagEnum.EFFECT.code) + .setFileCode(fileCode) + .setPrjDir(false); + this.baseMapper.insert(newEdFileInfo); + String fileDestPath = commonService.getFileSysPath(parentFileInfo.getFileId()) + File.separator + mainName + "_1." + suffix + "." + fileCode; + FileUtil.writeFromStream(file.getInputStream(), fileDestPath); + } + + } + + private String doSysFileMerge(String identifier, String fileName, Integer totalChunks) { String currentUserId = UserThreadLocal.getUserId(); for (int i = 1; i <= totalChunks; i++) { diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/FileSystemServiceImpl.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/FileSystemServiceImpl.java index 2bc3ec6..cfe4c2a 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/FileSystemServiceImpl.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/serviceimpl/FileSystemServiceImpl.java @@ -25,6 +25,7 @@ public class FileSystemServiceImpl implements FileSystemService { @Override public void save(InputStream inputStream, String destination) { + FileUtil.writeFromStream(inputStream, destination); } @Override diff --git a/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/util/EleCommonUtil.java b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/util/EleCommonUtil.java index bfd381c..d8ec8f8 100644 --- a/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/util/EleCommonUtil.java +++ b/electromagnetic-common/src/main/java/com/electromagnetic/industry/software/common/util/EleCommonUtil.java @@ -1,5 +1,7 @@ package com.electromagnetic.industry.software.common.util; +import cn.hutool.core.util.StrUtil; + import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.regex.Pattern; @@ -35,7 +37,7 @@ public final class EleCommonUtil { } public static boolean isFileNameValid(String fileFullName) { - if (fileFullName.length() > 32) { + if (StrUtil.isEmpty(fileFullName) || fileFullName.length() > 32) { return false; } return pattern.matcher(fileFullName).matches();