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 561bdd6..db5039e 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 @@ -18,7 +18,7 @@ import java.util.Date; @Accessors(chain = true) @Data @FieldNameConstants -public class EdFileInfo extends BaseModel { +public class EdFileInfo extends BaseModel{ public void newInit() { String userId = UserThreadLocal.getUserId(); diff --git a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/FileSystemService.java b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/FileSystemService.java index 41cd016..f92c639 100644 --- a/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/FileSystemService.java +++ b/electrmangnetic/src/main/java/com/electromagnetic/industry/software/manage/service/FileSystemService.java @@ -8,7 +8,7 @@ public interface FileSystemService { void copyFile(String source, String destination); - void moveFile(String source, String destination); + void moveFile(String source, String destination, boolean deleteSource); void save(InputStream inputStream, String destination); @@ -17,4 +17,8 @@ public interface FileSystemService { void renameFile(String sourcePath, String sourceName, String newName); boolean checkFolderExist(String newPath); + + boolean writeStringToFile(String filePath, String contents); + + boolean deleteFile(String filePath); } 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 2d6fbd5..856838a 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 @@ -317,4 +317,23 @@ public class CommonService { } return null; } + + public String getPrjNameByDbPath(String dbPath) { + List paths = StrUtil.split(dbPath, MYSQL_FILE_PATH_SPLIT); + String prjId = paths.get(0); + return edFileInfoMapper.selectById(prjId).getFileName(); + } + + + + + + + + + + + + + } 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 95927a4..ebb7279 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 @@ -7,6 +7,7 @@ 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.IdUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.ZipUtil; import cn.hutool.crypto.SecureUtil; @@ -49,7 +50,6 @@ import javax.annotation.PostConstruct; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.*; -import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; @@ -71,7 +71,6 @@ public class EdFileInfoServiceImpl extends ServiceImpl mergeChunks(String identifier, String fileName, Integer totalChunks) { - String destZipPath = doSysFileMerge(identifier, fileName, totalChunks); - int index = destZipPath.lastIndexOf(".zip"); - String zipDirPath = destZipPath.substring(0, index); + String currentUserId = UserThreadLocal.getUserId(); + String destColibPath = doSysFileMerge(identifier, fileName, totalChunks); + String mainName = FileUtil.mainName(destColibPath); + String parentDir = FileUtil.getParent(destColibPath, 1); + String zipDirPath = parentDir + File.separator + mainName + ".zip"; AES aes = SecureUtil.aes(password.getBytes()); try( - InputStream inputStream = Files.newInputStream(Paths.get(destZipPath)); + InputStream inputStream = Files.newInputStream(Paths.get(destColibPath)); 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()); + throw new BizException(-1, info); } + String uuid = IdUtil.fastSimpleUUID(); + String tmpDir = uploadDataDir + currentUserId + File.separator + uuid + File.separator; + ZipUtil.unzip(zipDirPath, tmpDir); update2Database(zipDirPath); - update2FileSystem(zipDirPath); return null; } - private void update2Database(String colibDirPath) { + @Transactional(rollbackFor = Exception.class) + public void update2Database(String prjDirPath) { - // 首先解密该文件 - AES aes = SecureUtil.aes(password.getBytes()); - String zipFilePath = ""; - try( - InputStream inputStream = Files.newInputStream(Paths.get(colibDirPath)); - OutputStream outputStream = Files.newOutputStream(Paths.get(zipFilePath)); - ) { - aes.decrypt(inputStream, outputStream, true); - } catch (Exception e) { - String info = "文件上传失败"; - log.error(info, e); - throw new BizException(-1, info); + List importFileInfos = JSONUtil.toList(prjDirPath + File.separator + "mysql.info", EdFileInfo.class); + // 首先处理导入的文件夹及其下属文件 + // 找出文件夹 + List needMove2FileSystemFiles = new ArrayList<>(); + List importDirs = importFileInfos.stream() + .filter(e -> e.getDataType().equals(EleDataTypeEnum.FOLDER.code)) + .filter(e -> !e.getPrjDir()).collect(Collectors.toList()); + for (EdFileInfo edFileInfo : importDirs) { + String fileName = edFileInfo.getFileName(); + String parentId = edFileInfo.getParentId(); + List folders = queryChildFolders(parentId); + Map foldersMap = folders.stream().collect(Collectors.toMap(EdFileInfo::getId, e -> e)); + List folderNames = folders.stream().map(EdFileInfo::getFileName).collect(Collectors.toList()); + String saveSysFilePath; + if (folderNames.contains(fileName)) { // 有同名文件夹 + // 判断id是否相同 + if (foldersMap.get(fileName).getId().equals(edFileInfo.getId())) { // id相同,不做处理 + log.info("id相同,不做处理"); + } else { // 文件名重复,导入的文件名需要添加“_1” + edFileInfo.setFileNote(fileName + "_1"); + this.baseMapper.insert(edFileInfo); + } + } else { // 没有同名文件夹 + this.saveOrUpdate(edFileInfo); // 如果导出的文件夹在线上已经被作废,这里则直接恢复,需要注意的是,在作废文件时,需要将作废文件移动到回收站 + } + needMove2FileSystemFiles.add(edFileInfo); } - String tmpDir = ""; + // 处理文件 + importFileInfos = importFileInfos.stream() + .filter(e -> e.getDataType().equals(EleDataTypeEnum.FILE.code)) + .collect(Collectors.toList()); -// ZipUtil.unzipq + Map> fileInfoMap = new HashMap<>(); + for (EdFileInfo edFileInfo : importFileInfos) { + List list = fileInfoMap.getOrDefault(edFileInfo.getFileId(), new ArrayList<>()); + list.add(edFileInfo); + fileInfoMap.put(edFileInfo.getFileId(), list); + } - // TODO 注意 需要reversion + fileInfoMap.forEach((k, v) -> { + List dbFileInfos = this.baseMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class).eq(EdFileInfo::getFileId, k).orderByAsc(EdFileInfo::getFileVersion)); + if (CollUtil.isEmpty(dbFileInfos)) { // 在线上没有找到,则该批文件是从线下上传的 + EdFileInfo fileInfo = v.stream().filter(e -> e.getEffectFlag().equals(EffectFlagEnum.EFFECT.code)).findFirst().get(); + resetFileInfoName(fileInfo); + this.saveBatch(v); + needMove2FileSystemFiles.addAll(v); + } else { + Map dbIdMap = dbFileInfos.stream().collect(Collectors.toMap(EdFileInfo::getId, e -> e)); + Map importIdMap = v.stream().collect(Collectors.toMap(EdFileInfo::getId, e -> e)); + importIdMap.putAll(dbIdMap); + List deepCopyV = JSONUtil.toList(JSONUtil.toJsonStr(v), EdFileInfo.class); + List deepCopyDb = JSONUtil.toList(JSONUtil.toJsonStr(dbFileInfos), EdFileInfo.class); + EdFileInfo importEffectFile = deepCopyV.stream().filter(e -> e.getEffectFlag().equals(EffectFlagEnum.EFFECT.code)).findFirst().get(); + EdFileInfo dbEffectFile = deepCopyDb.stream().filter(e -> e.getEffectFlag().equals(EffectFlagEnum.EFFECT.code)).findFirst().get(); + String effectId = importEffectFile.getUpdateTime().after(dbEffectFile.getUpdateTime()) ? importEffectFile.getId() : dbEffectFile.getId(); + Map importVersionRelation = getVersionRelation(deepCopyV); + Map dbVersionRelation = getVersionRelation(deepCopyDb); + dbVersionRelation.putAll(importVersionRelation); + int start = FILE_START_VERSION; + List saveObjs = new ArrayList<>(); + for (EdFileInfo importFileInfo : v) { + if (dbIdMap.containsKey(importFileInfo.getId())) { // 该文件在数据库中存在,是从线上导出的。 + EdFileInfo dbFileInfo = dbIdMap.get(importFileInfo.getId()); + if (dbFileInfo.getUpdateTime().before(importFileInfo.getUpdateTime())) { // 线下版本的修改时间比线上的新,用线下的版本 + importFileInfo.setFileVersion(start); + saveObjs.add(importFileInfo); + } else { // 线上版本的修改时间比线下新,用线上的版本。 + dbFileInfo.setFileVersion(start); + saveObjs.add(dbFileInfo); + } + } else { // 该文件是线下上传的。 + importFileInfo.setFileVersion(start); + saveObjs.add(importFileInfo); + needMove2FileSystemFiles.add(importFileInfo); + } + ++start; + } + for (EdFileInfo saveObj : saveObjs) { + String id = saveObj.getId(); + String preVersionId = dbVersionRelation.get(id); + EdFileInfo tmp = importIdMap.get(preVersionId); + saveObj.setPreVersion(tmp.getFileVersion()); + int effect = Objects.equals(saveObj.getId(), effectId) ? EffectFlagEnum.EFFECT.code : EffectFlagEnum.NOT_EFFECTIVE.code; + saveObj.setEffectFlag(effect); + } + this.saveOrUpdateBatch(saveObjs); + } + }); + update2FileSystem(needMove2FileSystemFiles, prjDirPath); } - private void update2FileSystem(String zipDirPath) { + private void resetFileInfoName(EdFileInfo fileInfo) { + String fileName = fileInfo.getFileName(); + String parentId = fileInfo.getParentId(); + for (int i = 0; i < 1000; ++i) { + long count = this.baseMapper.selectCount(Wrappers.lambdaQuery(EdFileInfo.class) + .eq(EdFileInfo::getFileName, fileName) + .eq(EdFileInfo::getParentId, parentId) + .eq(EdFileInfo::getDataType, EleDataTypeEnum.FILE.code) + .eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code)); + if (count > 0) { + fileName = fileName + "_1"; + } else { + fileInfo.setFileName(fileName); + return; + } + } + } + + private void update2FileSystem(List needMove2FileSystemFiles, String prjDirPath) { + Map idNameMaps = needMove2FileSystemFiles.stream().collect(Collectors.toMap(EdFileInfo::getId, EdFileInfo::getFileName)); + List files = needMove2FileSystemFiles.stream().filter(e -> e.getDataType().equals(EleDataTypeEnum.FILE.code)).collect(Collectors.toList()); + for (EdFileInfo edFileInfo : files) { + String filePath = edFileInfo.getFilePath(); + StringBuilder sysFilePath = new StringBuilder(); + for (String id : filePath.split(MYSQL_FILE_PATH_SPLIT)) { + sysFilePath.append(idNameMaps.get(id)).append(File.separator); + } + String destPath = commonService.getEleDataPath() + File.separator + sysFilePath; + String sourcePath = prjDirPath + File.separator + sysFilePath; + fileSystemService.moveFile(sourcePath, destPath, true); + } + } + + private Map getVersionRelation(List edFileInfos) { + Map versionRelation = new HashMap<>(); + Map versionMap = edFileInfos.stream().collect(Collectors.toMap(EdFileInfo::getFileVersion, e -> e)); + for (EdFileInfo edFileInfo : edFileInfos) { + Integer preVersion = edFileInfo.getPreVersion(); + EdFileInfo fileInfo = versionMap.get(preVersion); + String preVersionId = Objects.isNull(fileInfo) ? null : fileInfo.getId(); + versionRelation.put(edFileInfo.getId(), preVersionId); + } + return versionRelation; + } + + private List queryChildFolders(String parentId) { + return this.baseMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class).eq(EdFileInfo::getParentId, parentId) + .eq(EdFileInfo::getDataType, EleDataTypeEnum.FOLDER.code) + .eq(EdFileInfo::getEffectFlag, false)); } /** * 导出 - * * @param dataIdArr * @return */ @@ -368,20 +493,27 @@ public class EdFileInfoServiceImpl extends ServiceImpl e.getParentId().equals(PRJ_PARENT_ID)).findFirst().get().getFileName(); + + List prjFolders = this.baseMapper.selectList(Wrappers.lambdaQuery(EdFileInfo.class).eq(EdFileInfo::getPrjDir, true).eq(EdFileInfo::getEffectFlag, EffectFlagEnum.EFFECT.code)); + Map prjFoldersMap = prjFolders.stream().collect(Collectors.toMap(EdFileInfo::getId, e -> e)); + Map tmps = resFiles.stream().collect(Collectors.toMap(EdFileInfo::getId, e -> e)); + resFiles.clear(); + resFiles.addAll(tmps.values()); + resFiles.addAll(prjFoldersMap.values()); + String prjName = commonService.getPrjNameByDbPath(resFiles.get(0).getFilePath()); 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); + fileSystemService.createDirectory(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); + fileSystemService.copyFile(filePath, destPath); } String mysqlInfo = JSONUtil.toJsonStr(resFiles); - FileUtil.writeString(mysqlInfo, downloadDataDir + File.separator + "mysql.info", Charset.defaultCharset()); + fileSystemService.writeStringToFile(downloadDataDir + File.separator + "mysql.info", mysqlInfo); String exportZipFile = downloadDataDir + File.separator + prjName + ".zip"; String exportColibFile = downloadDataDir + File.separator + prjName + EXPORT_FILE_SUFFIX; ZipUtil.zip(downloadDataDir + File.separator + prjName, exportZipFile); @@ -396,18 +528,16 @@ public class EdFileInfoServiceImpl extends ServiceImpl FileUtil.del(e.getAbsolutePath())); - return destZipPath; + return destColibPath; } } 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 cfe4c2a..bbc806e 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 @@ -6,6 +6,7 @@ import org.springframework.stereotype.Service; import java.io.File; import java.io.InputStream; +import java.nio.charset.Charset; @Service public class FileSystemServiceImpl implements FileSystemService { @@ -17,10 +18,16 @@ public class FileSystemServiceImpl implements FileSystemService { @Override public void copyFile(String source, String destination) { + moveFile(source, destination, false); } @Override - public void moveFile(String source, String destination) { + public void moveFile(String source, String destination, boolean deleteSource) { + if (deleteSource) { + FileUtil.move(new File(source), new File(destination), true); + return; + } + FileUtil.copy(new File(source), new File(destination), false); } @Override @@ -43,4 +50,16 @@ public class FileSystemServiceImpl implements FileSystemService { public boolean checkFolderExist(String newPath) { return FileUtil.exist(newPath); } + + @Override + public boolean writeStringToFile(String filePath, String contents) { + FileUtil.writeString(contents, filePath, Charset.defaultCharset()); + return true; + } + + @Override + public boolean deleteFile(String filePath) { + FileUtil.del(filePath); + return false; + } }