diff --git a/bootstrap/src/main/java/com/electromagnetic/industry/software/data/manage/controller/EDDataBaseController.java b/bootstrap/src/main/java/com/electromagnetic/industry/software/data/manage/controller/EDDataBaseController.java new file mode 100644 index 0000000..5a4c1ab --- /dev/null +++ b/bootstrap/src/main/java/com/electromagnetic/industry/software/data/manage/controller/EDDataBaseController.java @@ -0,0 +1,28 @@ +package com.electromagnetic.industry.software.data.manage.controller; + +import com.electromagnetic.industry.software.data.manage.facade.EDDataFacade; +import com.electromagnetic.industry.software.data.manage.request.indicator.EDDataRequest; +import electromagnetic.data.framework.share.model.ElectromagneticResult; +import electromagnetic.data.framework.share.model.ElectromagneticResultUtil; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.util.Date; + +@RequestMapping("/data/ed/database") +@RestController +public class EDDataBaseController { + + @Resource + private EDDataFacade edDataFacade; + + @ApiOperation(value = "数据导出",notes = "") + @RequestMapping(value = "/export",method = RequestMethod.POST) + public ElectromagneticResult export(@RequestBody EDDataRequest request){ + return edDataFacade.batchExport(request); + } + + +} diff --git a/bootstrap/src/main/resources/application.properties b/bootstrap/src/main/resources/application.properties index 49e9923..5e345dd 100644 --- a/bootstrap/src/main/resources/application.properties +++ b/bootstrap/src/main/resources/application.properties @@ -1,4 +1,4 @@ -#required +#required spring.application.name=electromagnetic-data # security run.mode=NORMAL @@ -26,6 +26,7 @@ spring.datasource.type=com.alibaba.druid.pool.DruidDataSource mybatis.mapper-locations=classpath:sqlmapper/*.xml pagehelper.helperDialect=mysql pagehelper.reasonable=false -server.port=12352 +server.port=8888 +zip.password=~~BYE6cWGBJJjsU9DczYtZIQ== -upload.file.dest.path=G:/data/ \ No newline at end of file +upload.file.dest.path=G:/data/ diff --git a/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/user/service/CategoryService.java b/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/user/service/CategoryService.java index 792916a..df82817 100644 --- a/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/user/service/CategoryService.java +++ b/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/user/service/CategoryService.java @@ -3,6 +3,7 @@ package com.electromagnetic.industry.software.data.manage.domain.boardservice.us import com.electromagnetic.industry.software.data.manage.domain.boardservice.category.model.Category; import java.util.List; +import java.util.Map; public interface CategoryService { @@ -32,7 +33,23 @@ public interface CategoryService { List selectChildCategories(Category category); /** - * 获取 指定节点的 父节点 从所有节点数组中 + * 通过 节点 获取到顶级节点的树路径 从指定的节点数组中 + * @param category + * @param categoryMap + * @return + */ + List getTopCategoriesPathList(Category category, Map categoryMap); + + /** + * 通过 节点 获取父节点 从指定的节点数组中 + * @param category + * @param categoryList + * @return + */ + Category getParentCategories(Category category, List categoryList); + + /** + * 通过 节点ID 获取父节点 从指定的节点数组中 * @param categoryId * @param categoryList * @return diff --git a/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/user/service/impl/CategoryServiceImpl.java b/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/user/service/impl/CategoryServiceImpl.java index ef441ea..bd30ee8 100644 --- a/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/user/service/impl/CategoryServiceImpl.java +++ b/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/user/service/impl/CategoryServiceImpl.java @@ -10,8 +10,10 @@ import javax.annotation.Resource; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; + @Service public class CategoryServiceImpl implements CategoryService { @@ -102,24 +104,38 @@ public class CategoryServiceImpl implements CategoryService { public List selectChildCategories(Category category) { return categoryRepository.selectChildCategories(category); } /** - * 获取 指定节点的 父节点 从所有节点数组中 - * @param categoryId + * 通过 节点 获取到顶级节点的树路径 从指定的节点数组中 + * @param category + * @param categoryMap + * @return + */ + public List getTopCategoriesPathList(Category category, Map categoryMap) + { + Category categoryParent = categoryMap.get(category.getParentId()); + if(categoryParent != null) + { + List topCategoriesPathList = getTopCategoriesPathList(categoryParent, categoryMap); + if(topCategoriesPathList == null) + { + topCategoriesPathList = new ArrayList(); + } + + topCategoriesPathList.add(0, categoryParent); + return topCategoriesPathList; + } + return null; + } + + /** + * 通过 节点 获取父节点 从指定的节点数组中 + * @param category * @param categoryList * @return */ - public Category getParentCategories(String categoryId, List categoryList) + public Category getParentCategories(Category category, List categoryList) { - Category category = null; Category categoryParent = null; for(Category iter : categoryList) - { - if(category == null && iter.getCategoryId().equals(categoryId)) - { - category = iter; - break; - } - } - for(Category iter : categoryList) { if(categoryParent == null && iter.getCategoryId().equals(category.getParentId())) { @@ -127,8 +143,29 @@ public class CategoryServiceImpl implements CategoryService { break; } } - return categoryParent; } + + /** + * 获通过 节点ID 获取父节点 从指定的节点数组中 + * @param categoryId + * @param categoryList + * @return + */ + public Category getParentCategories(String categoryId, List categoryList) + { + Category category = null; + for(Category iter : categoryList) + { + if(category == null && iter.getCategoryId().equals(categoryId)) + { + category = iter; + break; + } + } + return getParentCategories(category, categoryList); + } + + } diff --git a/electromagnetic-framework/pom.xml b/electromagnetic-framework/pom.xml index 9e7d955..718c99d 100644 --- a/electromagnetic-framework/pom.xml +++ b/electromagnetic-framework/pom.xml @@ -75,6 +75,11 @@ org.springframework spring-webmvc + + net.lingala.zip4j + zip4j + 2.11.5 + \ No newline at end of file diff --git a/electromagnetic-framework/src/main/java/electromagnetic/data/framework/share/util/ZipUtil.java b/electromagnetic-framework/src/main/java/electromagnetic/data/framework/share/util/ZipUtil.java new file mode 100644 index 0000000..bb5c8a1 --- /dev/null +++ b/electromagnetic-framework/src/main/java/electromagnetic/data/framework/share/util/ZipUtil.java @@ -0,0 +1,149 @@ +package electromagnetic.data.framework.share.util; + +import cn.hutool.core.util.StrUtil; +import net.lingala.zip4j.ZipFile; +import net.lingala.zip4j.exception.ZipException; +import net.lingala.zip4j.model.ZipParameters; +import net.lingala.zip4j.model.enums.AesKeyStrength; +import net.lingala.zip4j.model.enums.CompressionLevel; +import net.lingala.zip4j.model.enums.CompressionMethod; +import net.lingala.zip4j.model.enums.EncryptionMethod; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +/** + * @desc zip解压缩工具 + * @author: wcy + * @date: 2024/1/12 + * @version: 1.0 + */ +public class ZipUtil { + /** + * 压缩指定路径的文件 + * @param srcFilePath 待压缩文件路径 + * @param zipPathFileName zip文件全路径名 + * @param password 加密密码 + * @return + */ + public static boolean zipFile(String srcFilePath, String zipPathFileName, String password){ + + try { + // 生成的压缩文件 + ZipFile zipFile = new ZipFile(zipPathFileName); + if (StrUtil.isNotEmpty(password)) { + zipFile.setPassword(password.toCharArray()); + } + ZipParameters parameters = new ZipParameters(); + // 压缩级别 + parameters.setCompressionMethod(CompressionMethod.DEFLATE); + parameters.setCompressionLevel(CompressionLevel.NORMAL); + + if(StrUtil.isNotEmpty(password)){ + parameters.setEncryptFiles(true); + parameters.setEncryptionMethod(EncryptionMethod.AES); + parameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256); + } + + // 要打包的文件夹 + File file = new File(srcFilePath); + if (file.isDirectory()) { + zipFile.addFolder(file, parameters); + } else { + zipFile.addFile(file, parameters); + } + return true; + } catch (ZipException e) { + e.printStackTrace(); + return false; + } + } + + /** + * @param zipFileFullName zip文件所在的路径名 + * @param filePath 解压到的路径 + * @param password 需要解压的密码 + * @return + */ + public static boolean unZipFile(String zipFileFullName, String filePath, String password) { + try { + ZipFile zipFile = new ZipFile(zipFileFullName); + // 如果解压需要密码 + if(StrUtil.isNotEmpty(password) && zipFile.isEncrypted()) { + zipFile.setPassword(password.toCharArray()); + } + zipFile.extractAll(filePath); + return true; + } catch (ZipException e) { + e.printStackTrace(); + return false; + } + } + + /** + * 添加文件到压缩文件中 + * @param zipFullFileName zip文件所在路径及全名 + * @param fullFileNameList 待添加的文件全路径集合 + * @param rootFolderInZip 在压缩文件里的文件夹名 + * @return + */ + public static boolean addFilesToZip(String zipFullFileName, List fullFileNameList, String rootFolderInZip) { + try { + ZipFile zipFile = new ZipFile(zipFullFileName); + ArrayList addFiles = new ArrayList<>(); + for (String fileName : fullFileNameList) { + addFiles.add(new File(fileName)); + } + + ZipParameters parameters = new ZipParameters(); + parameters.setCompressionMethod(CompressionMethod.DEFLATE); + parameters.setCompressionLevel(CompressionLevel.NORMAL); + if(StrUtil.isNotEmpty(rootFolderInZip)){ + if(!rootFolderInZip.endsWith("/")){ + rootFolderInZip = rootFolderInZip+"/"; + } + parameters.setRootFolderNameInZip(rootFolderInZip); + } + zipFile.addFiles(addFiles, parameters); + return true; + } catch (ZipException e) { + e.printStackTrace(); +// log.error("添加文件失败:\n"+e.getMessage()); + return false; + } + } + + /** + * 从压缩文件中删除路径 + * @param zipFullFileName + * @param fileName + * @return + */ + public static boolean deleteFileInZip(String zipFullFileName, String fileName) { + try { + ZipFile zipFile = new ZipFile(zipFullFileName); + zipFile.removeFile(fileName); + return true; + } catch (ZipException e) { + e.printStackTrace(); + return false; + } + } + +// public static void main(String[] args) throws ZipException { +// String srcFilePath = "G:/comac_desk_app"; +// String desFilePath = "C:\\Users\\test\\Desktop\\project\\file"; +// String zipPathFileName = "G:/tmp/comac_desk_app.zip"; +// String password = "123456"; +// long begin = System.currentTimeMillis(); +// boolean zipResult = zipFile(srcFilePath, zipPathFileName, password); +// long end = System.currentTimeMillis(); +// System.out.println("压缩结果:" + zipResult + ",耗时:" + (end - begin) + "ms"); +// +// boolean unZipResult = unZipFile(zipPathFileName, desFilePath, password); +// long end2 = System.currentTimeMillis(); +// System.out.println("解压结果:" + unZipResult + ",耗时:" + (end2 - end) + "ms"); +// System.out.println(unZipResult); +// } + +} diff --git a/service/src/main/java/com/electromagnetic/industry/software/data/manage/service/facade/EDDataFacadeImpl.java b/service/src/main/java/com/electromagnetic/industry/software/data/manage/service/facade/EDDataFacadeImpl.java index 99884e9..017bce3 100644 --- a/service/src/main/java/com/electromagnetic/industry/software/data/manage/service/facade/EDDataFacadeImpl.java +++ b/service/src/main/java/com/electromagnetic/industry/software/data/manage/service/facade/EDDataFacadeImpl.java @@ -1,4 +1,4 @@ -package com.electromagnetic.industry.software.data.manage.service.facade; +package com.electromagnetic.industry.software.data.manage.service.facade; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IoUtil; @@ -18,10 +18,13 @@ import com.electromagnetic.industry.software.data.manage.request.indicator.FileC import com.electromagnetic.industry.software.data.manage.request.indicator.FileChunkResultDTO; import com.electromagnetic.industry.software.data.manage.response.indicator.EDDataPageResponse; import com.electromagnetic.industry.software.data.manage.service.mappers.EDDataMappers; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import electromagnetic.data.framework.share.id.IdWorker; import electromagnetic.data.framework.share.model.ElectromagneticResult; import electromagnetic.data.framework.share.model.ElectromagneticResultUtil; import lombok.extern.slf4j.Slf4j; +import electromagnetic.data.framework.share.util.ZipUtil; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; @@ -29,9 +32,8 @@ import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; +import java.io.IOException; +import java.nio.file.*; import java.util.*; import java.util.stream.Collectors; @@ -41,10 +43,14 @@ public class EDDataFacadeImpl implements EDDataFacade { @Resource private EDDataService edDataService; + + @Resource private CategoryService categoryService; @Value("${upload.file.dest.path}") private String uploadFilePath; + @Value("${zip.password}") + private String passwordZIP; private static final String UPLOAD_FILE_CHUNK_SUFFIX = ".part"; @@ -381,68 +387,124 @@ public class EDDataFacadeImpl implements EDDataFacade { // **********在导出的过程中可能会出现有用户上传文件的情况 - // 获取目录编码ID - String categoryId = request.getParentId(); - - // 获取缓存文件夹的绝对路径 - String userHome = System.getProperty("user.home"); - File cacheDirectory = new File(userHome + "\\AppData\\Local\\Temp\\EDData\\Export"); - if (!cacheDirectory.exists()) { - cacheDirectory.mkdirs(); - } - - String cacheFolder = cacheDirectory.getAbsolutePath(); // 缓存文件夹的绝对路径 + // 获取文件夹编码ID数组 + List categoryIdInputList = Arrays.asList(request.getDataIdArr()); - List categoryList = categoryService.selectAllCategories(); + String cacheFolder = ""; // 缓存文件夹的绝对路径 + String exportDataDirectory = ""; { - // 遍历客户端上传的 - EDDataParams folderParames = new EDDataParams(); - for (String dataId : request.getDataIdArr()) { - Category category = new Category(); - category.setCategoryId(dataId); - categoryService.selectCategories(category); - - //folderParames.setDataId(dataId); - //EDDataInfo edDataInfo = edDataService.getDataInfo(folderParames); - //if(edDataInfo != null) - //{ - // JSONObject implantJsonObject = JSON.parseObject(edDataInfo.getImplantJson()); - // String filePath = implantJsonObject.getString("folderPath"); - // filePath = storageDirectory + "/" + filePath + "/" + edDataInfo.getDataName(); - // dataPathArr.add(filePath); - //} + // 获取缓存文件夹的绝对路径 + String userHome = System.getProperty("user.home"); + cacheFolder = userHome + "\\AppData\\Local\\Temp\\EDData"; // 缓存文件夹的绝对路径 + exportDataDirectory = cacheFolder + "\\ExportData"; + File cacheDirectory = new File(exportDataDirectory); + if (!cacheDirectory.exists()) { + cacheDirectory.mkdirs(); } } - - String parentFolderPath = ""; //上级文件夹路径 - String parentFolderIdPath = ""; //上级文件夹ID路径 - String parentFolderName = ""; //上级文件夹名称 - - // 获取上级文件夹路径 + List categoryAllList = categoryService.selectAllCategories(); + Map categoryAllMap = new HashMap(); //所有目录数组map + List categoryInputList = new ArrayList(); //客户端输入的目录数组map + Map categoryInputMap = new HashMap(); //客户端输入的目录数组map + for (Category category : categoryAllList) { - EDDataParams folderParames = new EDDataParams(); - folderParames.setDataId(categoryId); - EDDataInfo edDataInfoParent = edDataService.getDataInfo(folderParames); - if(edDataInfoParent == null) { - ElectromagneticResultUtil.fail(HttpStatus.BAD_REQUEST.toString(),"上级文件夹为空!"); - } - JSONObject implantJsonObject = JSON.parseObject(edDataInfoParent.getImplantJson()); - parentFolderPath = implantJsonObject.getString("folderPath"); - parentFolderIdPath = implantJsonObject.getString("folderIdPath"); - if(!parentFolderPath.isEmpty()) - parentFolderPath += "/" ; - if(!parentFolderIdPath.isEmpty()) - parentFolderIdPath += "/" ; - parentFolderPath += edDataInfoParent.getDataName(); - parentFolderIdPath += edDataInfoParent.getDataId(); - parentFolderName = edDataInfoParent.getDataName(); + categoryAllMap.put(category.getCategoryId(), category); + } + for (String categoryId : categoryIdInputList) + { + Category category = categoryAllMap.get(categoryId); + categoryInputList.add(category); + categoryInputMap.put(categoryId, category); } - return null; + List categoryHighestList = new ArrayList(); + List highestToTopCategoriesPathList = new ArrayList(); //输入的最高级目录到 所有目录的顶级目录的 路径目录数组 + + // 从客户端上传的输入目录数组中 找到最高级(不是最顶级)目录树节点 + { + Category categoryHighestParent = null; + Category categoryHighestParentTemp = null; + String categoryIdParent = ""; + for (Category category : categoryInputList) + { + // 从输入目录数组找到最高级父节点目录 + categoryHighestParentTemp = category; + do{ + categoryIdParent = categoryHighestParentTemp.getParentId(); + categoryHighestParent = categoryHighestParentTemp; + categoryHighestParentTemp = categoryInputMap.get(categoryIdParent); + } + while(categoryHighestParentTemp != null); + + categoryHighestList.add(categoryHighestParent); + } + + for (Category category : categoryHighestList) { + List topCategoriesPathList = categoryService.getTopCategoriesPathList(category, categoryAllMap); + for (Category categoryPath : topCategoriesPathList) { + if(!highestToTopCategoriesPathList.contains(categoryPath)) { + highestToTopCategoriesPathList.add(categoryPath); + } + } + } + } + + // 导出目录数据为json文件 + { + List categoryExportList = new ArrayList(); //需要导出的目录数据数组 + categoryExportList.addAll(highestToTopCategoriesPathList); + for (Category category : categoryInputList) { + if(!categoryExportList.contains(category)) { + categoryExportList.add(category); + } + } + + // 创建ObjectMapper对象,用于JSON处理 + ObjectMapper objectMapper = new ObjectMapper(); + + // 将List转换为JSON字符串 + String jsonString = ""; + try { + jsonString = objectMapper.writeValueAsString(categoryExportList); + } catch (JsonProcessingException e) { + e.printStackTrace(); + } + + // 将JSON字符串写入文件 + File jsonFile = new File(exportDataDirectory + "/categoryList.json"); + try { + objectMapper.writeValue(jsonFile, jsonString); + } catch (IOException e) { + e.printStackTrace(); + } + + System.out.println("目录树数据已成功导出为JSON文件。" + jsonFile.getAbsolutePath()); + } + + // 导出文件和文件夹数据 + { + String storageDirectory = "D:/fileTemp"; + Path source = Paths.get(storageDirectory + "/testFolder3"); + Path target = Paths.get(exportDataDirectory); + FileUtil.copy(source, target); // StandardCopyOption.REPLACE_EXISTING + System.out.println("文件数据已成功复制到目标目录。"); + } + + // 将目录树数据 和 文件夹及文件夹内数据 进行压缩打包 + { + String zipPathFileName = cacheFolder + "/comac_exportData.comac"; + ZipUtil.zipFile(exportDataDirectory, zipPathFileName, passwordZIP); + System.out.println("目录树数据+文件数据已成功复制到目标目录。" + zipPathFileName); + } + + // 删除 导出数据的 缓存目录 + FileUtil.del(exportDataDirectory); + + return ElectromagneticResultUtil.success(cacheFolder + "\\comac_exportData.zip"); } /**