diff --git a/bootstrap/src/main/java/com/electromagnetic/industry/software/data/manage/controller/EDDataController.java b/bootstrap/src/main/java/com/electromagnetic/industry/software/data/manage/controller/EDDataController.java index 05f14bd..db8002b 100644 --- a/bootstrap/src/main/java/com/electromagnetic/industry/software/data/manage/controller/EDDataController.java +++ b/bootstrap/src/main/java/com/electromagnetic/industry/software/data/manage/controller/EDDataController.java @@ -2,14 +2,21 @@ 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 com.electromagnetic.industry.software.data.manage.request.indicator.FileChunkDTO; +import com.electromagnetic.industry.software.data.manage.request.indicator.FileDownloadDTO; import electromagnetic.data.framework.share.model.ElectromagneticResult; import electromagnetic.data.framework.share.model.ElectromagneticResultUtil; 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; +import java.io.IOException; import java.util.Date; +import java.util.List; @RequestMapping("/data/ed/file") @RestController @@ -55,14 +62,14 @@ public class EDDataController { request.setParentId(parentId); request.setFileData(file); request.setGmtBatchUpload(new Date(gmtBatchUpload)); - return edDataFacade.upload(request); + return edDataFacade.uploadFile(request); } @ApiOperation(value = "下载",notes = "") - @RequestMapping(value = "/download",method = RequestMethod.POST) - public ElectromagneticResult download(@RequestBody EDDataRequest request){ - return edDataFacade.download(request); + @RequestMapping(value = "/download",method = RequestMethod.GET) + public ResponseEntity download(@RequestParam String dataId, HttpServletResponse response) throws IOException { + return edDataFacade.download(dataId, response); } @@ -72,5 +79,36 @@ public class EDDataController { return ElectromagneticResultUtil.success("复制"); } + @ApiOperation(value = "数据导出",notes = "") + @RequestMapping(value = "/batchExport",method = RequestMethod.GET) + public ResponseEntity batchExport(@RequestParam String dataIdArr, HttpServletResponse response) throws IOException { + return edDataFacade.batchExport(dataIdArr, response); + } + + @ApiOperation(value = "获取已经上传的分片",notes = "") + @RequestMapping(value = "/getUploadedChunkNums",method = RequestMethod.GET) + public ElectromagneticResult getUploadedChunkNums(@RequestParam String identifier) { + return edDataFacade.getUploadedChunkNums(identifier); + } + + @ApiOperation(value = "合并分片",notes = "") + @RequestMapping(value = "/mergeChunks",method = RequestMethod.GET) + public ElectromagneticResult mergeChunks(@RequestParam String identifier, + @RequestParam String fileName, + @RequestParam Integer totalChunks) { + return edDataFacade.mergeChunks(identifier, fileName, totalChunks); + } + + @ApiOperation(value = "分片上传",notes = "") + @RequestMapping(value = "/batchImport",method = RequestMethod.POST) + public ElectromagneticResult batchImport(FileChunkDTO fileChunkDTO) { + return edDataFacade.batchImport(fileChunkDTO); + } + + @ApiOperation(value = "检查分片是否存在",notes = "") + @RequestMapping(value = "/batchImport",method = RequestMethod.GET) + public ElectromagneticResult checkChunkExist(FileChunkDTO fileChunkDTO) { + return edDataFacade.checkChunkExist(fileChunkDTO); + } } diff --git a/bootstrap/src/main/resources/application.properties b/bootstrap/src/main/resources/application.properties index cc4dfa0..48730a6 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 @@ -12,13 +12,11 @@ logging.config=classpath:${LOG_CONFIG:log4j2-spring.xml} spring.datasource.typd=com.alibaba.druid.pool.DruidDataSource -#spring.datasource.url=jdbc:mysql://${DATASOURCE_URL:obproxy-0c63.ops.cloud.cic.inter}:3306/${DATASOURCE_HOST:dataplatform_ptst}?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true&rewriteBatchedStatements=true -#spring.datasource.username=${DATASOURCE_NAME:dataplatform@ProjectTest_tenant5#testdb} -#spring.datasource.password=${DATASOURCE_PASSWORD:Y7G6v4_3ijn77K_Kbl_U85} spring.datasource.url=jdbc:mysql://139.224.43.89:3306/em_data?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=GMT%2B8&allowMultiQueries=true&rewriteBatchedStatements=true spring.datasource.username=comac spring.datasource.password=2024*Comac - +spring.servlet.multipart.max-file-size=500MB +spring.servlet.multipart.max-request-size=10MB spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.type=com.alibaba.druid.pool.DruidDataSource @@ -27,3 +25,20 @@ pagehelper.helperDialect=mysql pagehelper.reasonable=false server.port=8888 +#windows文件存储目录 +data.windows.path=E:/comacFileStorage/ +#文件缓存路径 +data.file.cache.dir=/szsd/cache/ +#文件存储路径 +data.file.storage.dir=/szsd/fileStorage/ +#上传文件时文件的缓存文件夹名称 +data.upload.cache.dir=upload +#导出数据时文件的缓存文件夹名称 +data.export.cache.dir=export +#导入数据时文件的缓存文件夹名称 +data.import.cache.dir=import +file.encode.passwd=adknfhkj87654knd +#数据类型中的文件类型为file +data.type.file=file +#数据类型中的文件夹类型为folder +data.type.folder=folder diff --git a/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/indicator/parames/EDDataParams.java b/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/indicator/parames/EDDataParams.java index 23cf20f..1c0031e 100644 --- a/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/indicator/parames/EDDataParams.java +++ b/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/indicator/parames/EDDataParams.java @@ -17,6 +17,14 @@ public class EDDataParams implements Serializable { * 每页数据 */ private Integer pageSize = 10; + /** + * 操作用户id + */ + private String userId; + /** + * 用户名 + */ + private String userName; /** * 上级文件夹数据码,为空是顶级 */ @@ -29,6 +37,10 @@ public class EDDataParams implements Serializable { * 文件夹名称 */ private String name; + /** + * 文件类型 + */ + private String dataType; /** * 创建日期排序 */ diff --git a/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/indicator/repository/EDDataRepository.java b/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/indicator/repository/EDDataRepository.java index 210810d..9dd252f 100644 --- a/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/indicator/repository/EDDataRepository.java +++ b/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/indicator/repository/EDDataRepository.java @@ -42,12 +42,4 @@ public interface EDDataRepository { */ Boolean updateFileInfo(EDDataParams parames); - /** - * 下载 - * @param parames - * @return - */ - Boolean download(EDDataParams parames); - - } \ No newline at end of file diff --git a/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/indicator/service/EDDataService.java b/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/indicator/service/EDDataService.java index 58ad441..d1ba4ba 100644 --- a/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/indicator/service/EDDataService.java +++ b/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/indicator/service/EDDataService.java @@ -4,14 +4,37 @@ import com.electromagnetic.industry.software.data.manage.domain.boardservice.ind import com.electromagnetic.industry.software.data.manage.domain.boardservice.indicator.model.EDDataPage; import com.electromagnetic.industry.software.data.manage.domain.boardservice.indicator.parames.EDDataParams; +import java.io.FileNotFoundException; +import java.util.List; +import java.util.Map; + public interface EDDataService { + /** + * 获取数据存储目录 + * @return + */ + String getDataStoragePath(); + + /** + * 获取数据缓存目录 + * @return + */ + String getDataCachePath(); + + /** + * 获取文件的文件夹路径 + * @param categoryId + * @return + */ + String getFilePathOfFolder(String categoryId); + /** * 创建文件/文件夹数据信息 * @param edDataInfo * @return */ - Boolean createDataInfo(EDDataInfo edDataInfo); + Boolean createDataInfo(EDDataInfo edDataInfo) throws FileNotFoundException; /** * 获取文件信息列表 @@ -32,7 +55,7 @@ public interface EDDataService { * @param parames * @return */ - Boolean updateFileInfo(EDDataParams parames); + Boolean updateFileInfo(EDDataParams parames) throws FileNotFoundException; /** * 获取子文件数量 @@ -42,24 +65,31 @@ public interface EDDataService { Integer getChildFileCount(EDDataParams parames); /** - * 下载 + * 文件上传 * @param parames * @return */ - Boolean download(EDDataParams parames); + Boolean uploadFile(EDDataParams parames) throws FileNotFoundException; /** - * 检查文件夹是否存在 - * @param path + * 文件下载 + * @param parames * @return */ - Boolean checkFolderIsExist(String path); + List downloadFile(EDDataParams parames); /** - * 创建多级目录 - * @param path + * 导出数据 + * @param dataIdList * @return */ - Boolean createMultiLevelDirectory(String path); + String exportData(List dataIdList); + + /** + * 解压后的数据目录 + * @param folderPath + * @return + */ + Map> importData(String folderPath); } diff --git a/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/indicator/service/impl/EDDataServiceImpl.java b/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/indicator/service/impl/EDDataServiceImpl.java index 6ee7448..3ee23f8 100644 --- a/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/indicator/service/impl/EDDataServiceImpl.java +++ b/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/indicator/service/impl/EDDataServiceImpl.java @@ -3,45 +3,185 @@ */ package com.electromagnetic.industry.software.data.manage.domain.boardservice.indicator.service.impl; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.util.ZipUtil; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.symmetric.AES; +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONUtil; +import cn.hutool.poi.excel.cell.CellSetter; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.electromagnetic.industry.software.data.manage.domain.boardservice.category.model.Category; import com.electromagnetic.industry.software.data.manage.domain.boardservice.indicator.model.EDDataInfo; import com.electromagnetic.industry.software.data.manage.domain.boardservice.indicator.model.EDDataPage; import com.electromagnetic.industry.software.data.manage.domain.boardservice.indicator.parames.EDDataParams; import com.electromagnetic.industry.software.data.manage.domain.boardservice.indicator.repository.EDDataRepository; import com.electromagnetic.industry.software.data.manage.domain.boardservice.indicator.service.EDDataService; +import com.electromagnetic.industry.software.data.manage.domain.boardservice.user.repository.CategoryRepository; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import electromagnetic.data.framework.share.exception.LoggerConstant; +import electromagnetic.data.framework.share.id.IdWorker; +import electromagnetic.data.framework.share.model.ElectromagneticResultUtil; +import electromagnetic.data.framework.share.util.EleZipUtil; +import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; -import java.io.IOException; +import java.io.*; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; -import java.util.List; +import java.text.SimpleDateFormat; +import java.util.*; /** * @author * @version $Id: IndicatorCardServiceImpl.java, v 0.1 2024-07-26 17:20 */ @Service +@Slf4j public class EDDataServiceImpl implements EDDataService { - private static final Logger LOGGER = LoggerFactory.getLogger(LoggerConstant.DOMAIN_SERVICE); - @Resource private EDDataRepository edDataRepository; + @Resource + private CategoryRepository categoryRepository; + @Value("${data.windows.path}") + private String windowsDir; + @Value("${data.file.cache.dir}") + private String fileCacheDir; + @Value("${data.file.storage.dir}") + private String fileStorageDir; + @Value("${data.upload.cache.dir}") + private String uploadCacheDir; + @Value("${data.export.cache.dir}") + private String exportCacheDir; + @Value("${file.encode.passwd}") + private String encodePasswd; + @Value("${data.type.file}") + private String dataTypeFile; + @Value("${data.type.folder}") + private String dataTypeFolder; + + + // 文件夹名称分隔符 + private static final String FOLDER_NAME_SEPARATOR = "_"; + + /** + * 获取时间戳字符串 + * @return + */ + public String getTimeStampString() { + long timestamp = System.currentTimeMillis(); + return String.valueOf(timestamp); + } + + /** + * 获取数据存储目录 + * @return + */ + public String getDataStoragePath() + { + String osName = System.getProperty("os.name").toLowerCase(); + return osName.startsWith("win") ? windowsDir + fileStorageDir : fileStorageDir; + } + + /** + * 获取数据缓存目录 + * @return + */ + public String getDataCachePath() + { + String osName = System.getProperty("os.name").toLowerCase(); + return osName.startsWith("win") ? windowsDir + fileCacheDir : fileCacheDir; + } + + /** + * 获取文件的文件夹路径 + * @param categoryId + * @return + */ + public String getFilePathOfFolder(String categoryId) + { + String filePathOfFolder = ""; //文件存放在文件夹的路径 + + String categoryIdHighest = categoryId; //最高级的目录编码 + EDDataParams folderParames = new EDDataParams(); + folderParames.setDataId(categoryId); + EDDataInfo edDataInfoParent = edDataRepository.getDataInfo(folderParames); + if(edDataInfoParent != null) { + categoryIdHighest = edDataInfoParent.getCategoryId(); + } + + Category categoryParent = new Category(); + categoryParent.setCategoryId(categoryIdHighest); + List categoryParentList = categoryRepository.selectCategories(categoryParent); + if(categoryParentList.size() > 0){ + categoryParent = categoryParentList.get(0); + filePathOfFolder = categoryParent.getCategoryId() + FOLDER_NAME_SEPARATOR + categoryParent.getCategoryName(); + if(edDataInfoParent != null){ + filePathOfFolder = filePathOfFolder + File.separator + edDataInfoParent.getDataName(); + } + } + + return filePathOfFolder; + } /** * 创建文件/文件夹数据信息 * @param edDataInfo * @return */ - public Boolean createDataInfo(EDDataInfo edDataInfo) + public Boolean createDataInfo(EDDataInfo edDataInfo) throws FileNotFoundException { - edDataRepository.createDataInfo(edDataInfo); + // 获取上级目录的名称 + Category categoryParent = new Category(); + categoryParent.setCategoryId(edDataInfo.getCategoryId()); + List categoryParentList = categoryRepository.selectCategories(categoryParent); + if(categoryParentList.size() < 1) { + throw new FileNotFoundException("上级文件夹不存在"); + } + else + { + // 获取新文件夹路径信息 + categoryParent = categoryParentList.get(0); + + String dataStoragePath = getDataStoragePath(); + String folderParent = categoryParent.getCategoryId() + FOLDER_NAME_SEPARATOR + categoryParent.getCategoryName() ; + String folderNew = dataStoragePath + File.separator + folderParent + File.separator + edDataInfo.getDataName(); + + // 判断文件夹名称是否存在 + EDDataParams folderParames = new EDDataParams(); + folderParames.setParentId(edDataInfo.getCategoryId()); + List childFileInfoList = edDataRepository.getDataInfoList(folderParames); + for(EDDataInfo fileInfo : childFileInfoList) + { + if(fileInfo.getDataName().equals(edDataInfo.getDataName())){ + throw new FileNotFoundException("文件夹已存在"); + } + } + + // 将文件夹数据写到数据库中 + if(edDataRepository.createDataInfo(edDataInfo)) { + if (!FileUtil.exist(folderNew)){ + FileUtil.mkdir(folderNew); + } + } + } + return Boolean.TRUE; } @@ -76,9 +216,44 @@ public class EDDataServiceImpl implements EDDataService { * @param parames * @return */ - public Boolean updateFileInfo(EDDataParams parames) + public Boolean updateFileInfo(EDDataParams parames) throws FileNotFoundException { + + String dataStoragePath = getDataStoragePath(); + if (!FileUtil.exist(dataStoragePath)){ + throw new FileNotFoundException("数据存储文件夹不存在"); + } + + EDDataParams paramesFind = new EDDataParams(); + paramesFind.setDataId(parames.getDataId()); + List edDataInfoList = edDataRepository.getDataInfoList(paramesFind); + if(edDataInfoList.size() < 1) { + throw new FileNotFoundException("文件信息不存在"); + } + + EDDataInfo edDataInfo = edDataInfoList.get(0); + String filePathOfFolder = getFilePathOfFolder(edDataInfo.getCategoryId()); + String fileStorageFullPath = dataStoragePath + filePathOfFolder + File.separator + edDataInfo.getDataName(); + + if (!FileUtil.exist(fileStorageFullPath)){ + throw new FileNotFoundException("文件不存在"); + } + + String fileNameNew = parames.getName(); + if(fileNameNew != null && fileNameNew != "" && !fileNameNew.equals(edDataInfo.getDataName())) { + FileUtil.rename(Paths.get(fileStorageFullPath) ,fileNameNew,true); + } + + // 修改文件夹 edDataRepository.updateFileInfo(parames); + // 修改文件夹中的文件 + if(edDataInfo.getDataType().equals(dataTypeFolder) && parames.getEffectFlag() != null) { + EDDataParams paramesChild = new EDDataParams(); + paramesChild.setParentId(edDataInfo.getDataId()); + paramesChild.setEffectFlag(parames.getEffectFlag()); + edDataRepository.updateFileInfo(paramesChild); + } + return Boolean.TRUE; } @@ -92,13 +267,14 @@ public class EDDataServiceImpl implements EDDataService { Integer childFileCount = 0; List edDataInfoList = edDataRepository.getDataInfoList(parames); + parames.setDataId(null); for (EDDataInfo edDataInfo : edDataInfoList) { - if(edDataInfo.getDataType().equals("folder")) + if(edDataInfo.getDataType().equals(dataTypeFolder)) { parames.setParentId(edDataInfo.getDataId()); childFileCount += getChildFileCount(parames); } - else if(edDataInfo.getDataType().equals("file")) + else if(edDataInfo.getDataType().equals(dataTypeFile)) { ++childFileCount; } @@ -108,39 +284,417 @@ public class EDDataServiceImpl implements EDDataService { } /** - * 下载 + * 文件上传 * @param parames * @return */ - public Boolean download(EDDataParams parames) + public Boolean uploadFile(EDDataParams parames) throws FileNotFoundException { - edDataRepository.download(parames); - return Boolean.TRUE; - } - /** - * 检查文件夹是否存在 - * @param path - * @return - */ - public Boolean checkFolderIsExist(String path) - { - return Files.exists(Paths.get(path)); - } + // 获取目录编码ID + String categoryId = parames.getParentId(); - /** - * 创建多级目录 - * @param path - * @return - */ - public Boolean createMultiLevelDirectory(String path) - { - try { - Files.createDirectories(Paths.get(path)); - return Boolean.TRUE; - } catch (IOException e) { - return Boolean.FALSE; + // 获取要上传的文件 + MultipartFile fileInput = parames.getFileData(); + + // 检查文件是否为空 + if (fileInput == null || fileInput.isEmpty()) { + throw new FileNotFoundException("上传的文件为空"); } + + // 获取文件名 + String fileFullName = fileInput.getOriginalFilename(); + // 获取文件类型 + String fileType = ""; + // 获取文件名称 + String fileName = ""; + if (fileFullName.lastIndexOf(".") != -1 && fileFullName.lastIndexOf(".") != 0) { + fileType = fileFullName.substring(fileFullName.lastIndexOf(".") + 1); + fileName = fileFullName.substring(fileFullName.lastIndexOf(".")); + } + + // 判断文件名称是否存在 + EDDataParams folderParames = new EDDataParams(); + folderParames.setParentId(categoryId); + List childFileInfoList = edDataRepository.getDataInfoList(folderParames); + for(EDDataInfo fileInfo : childFileInfoList) + { + if(fileInfo.getDataName().equals(fileFullName)){ + throw new FileNotFoundException("上传的文件已存在"); + } + } + + String dataStoragePath = getDataStoragePath(); + if (!FileUtil.exist(dataStoragePath)){ + FileUtil.mkdir(dataStoragePath); + } + + //获取文件存放在文件夹的路径 + String filePathOfFolder = getFilePathOfFolder(categoryId); + + // 将文件数据信息写到数据库 + EDDataInfo edDataInfo = new EDDataInfo(); + + + // 创建新文件数据 + edDataInfo.setCreator(parames.getUserId()); + edDataInfo.setCreatorName(parames.getUserName()); + edDataInfo.setModifier(parames.getUserId()); + edDataInfo.setModifierName(parames.getUserName()); + edDataInfo.setCategoryId(parames.getParentId()); + edDataInfo.setDataName(fileFullName); + edDataInfo.setNote(parames.getNote()); + edDataInfo.setFileType(fileType); + edDataInfo.setGmtBatchUpload(parames.getGmtBatchUpload()); + + edDataInfo.setDataId(IdWorker.getSnowFlakeIdString()); + edDataInfo.setDataNo(edDataInfo.getDataId()); + edDataInfo.setDataType(dataTypeFile); + edDataInfo.setVersion("1.0.0"); + edDataInfo.setDataStatus("publish"); + edDataInfo.setSaveStatus("saving"); + + boolean isSuccess = edDataRepository.createDataInfo(edDataInfo); + log.info("文件开始保存."); + + // 保存文件数据 到 文件存储目录 + + + // 文件保存目录路径 + String fileSavePath = dataStoragePath + File.separator + filePathOfFolder; + String newFileName = edDataInfo.getDataId() + FOLDER_NAME_SEPARATOR + fileFullName; + if (!FileUtil.exist(fileSavePath)){ + FileUtil.mkdir(fileSavePath); + } + + String dataCachePath = getDataCachePath(); + String uploadFileCachePath = dataCachePath + uploadCacheDir + FOLDER_NAME_SEPARATOR + getTimeStampString(); + if (!FileUtil.exist(uploadFileCachePath)){ + FileUtil.mkdir(uploadFileCachePath); + } + + String fileCacheFullPath = uploadFileCachePath + File.separator + newFileName; + String fileSaveFullPath = fileSavePath + File.separator + fileFullName; + log.info("文件缓存路径为: " + fileCacheFullPath); + + + // 这里可以添加将文件保存到本地磁盘或其他存储介质的逻辑 + File saveFile = new File(fileCacheFullPath); + + // 将文件保存到硬盘 + EDDataParams fileParames = new EDDataParams(); + try { + fileInput.transferTo(saveFile); + + + fileParames.setDataId(edDataInfo.getDataId()); + if(fileInput.getSize() == saveFile.length()) + { + Path source = Paths.get(fileCacheFullPath); + Path target = Paths.get(fileSaveFullPath); + Files.move(source, target); + fileParames.setSaveStatus("success"); + } + else + { + saveFile.delete(); + fileParames.setSaveStatus("failure"); + } + + isSuccess = edDataRepository.updateFileInfo(fileParames); + + FileUtil.del(uploadFileCachePath);//删除临时目录 + + log.info("文件保存成功: " + fileSaveFullPath); + + return Boolean.TRUE; + + } catch (IOException e) { + fileParames.setSaveStatus("failure"); + edDataRepository.updateFileInfo(fileParames); + log.info("文件保存失败: " + fileSaveFullPath); + throw new FileNotFoundException(e.getMessage()); + } + + } + + /** + * 文件下载 + * @param parames + * @return + */ + public List downloadFile(EDDataParams parames) + { + + // 获取文件存储的文件夹路径 + String dataStoragePath = getDataStoragePath(); + EDDataParams paramesFileInfo = new EDDataParams(); + List dataPathArr = new ArrayList(); + if (!FileUtil.exist(dataStoragePath)) { + dataPathArr.add("error : The directory where the file was stored was not found!"); + return dataPathArr; + } + + for(String dataId : parames.getDataIdArr()) + { + paramesFileInfo.setDataId(dataId); + EDDataInfo edDataInfo = edDataRepository.getDataInfo(paramesFileInfo); + if(edDataInfo != null) + { + String filePathOfFolder = getFilePathOfFolder(dataId); + String fileStoragePath = dataStoragePath + File.separator + filePathOfFolder; + String fileStorageFullPath = fileStoragePath + File.separator + edDataInfo.getDataName(); + if (FileUtil.exist(fileStoragePath)) { + if (!FileUtil.exist(fileStorageFullPath)) { + fileStorageFullPath = "error : No file found : " + fileStorageFullPath; + } + } + else { + //获取文件存放在文件夹的路径 + String filePathOfFolderByDB = getFilePathOfFolder(edDataInfo.getCategoryId()); + if (!FileUtil.exist(filePathOfFolderByDB)) { + fileStorageFullPath = "error : The directory path does not exist : " + edDataInfo.getCategoryId(); + } + } + dataPathArr.add(fileStorageFullPath); + } + } + + return dataPathArr; + } + + /** + * 导出数据 + * @param dataIdList + * @return + */ + public String exportData(List dataIdList) + { + String zipPathFileName = ""; + String exportDataCachePath = ""; + String enCodeZipPathFileName = ""; + + try { + // 获取文件夹编码ID数组 + List categoryIdInputList = dataIdList; + + String dataCachePath = getDataCachePath(); + + // 导出数据时的临时存放目录 + exportDataCachePath = dataCachePath + exportCacheDir + FOLDER_NAME_SEPARATOR + getTimeStampString(); + if (!FileUtil.exist(exportDataCachePath)) { + FileUtil.mkdir(exportDataCachePath); + } + + List categoryAllList = categoryRepository.getAllCategories(); + Map categoryAllMap = new HashMap(); //所有目录数组map + for (Category category : categoryAllList) { + categoryAllMap.put(category.getCategoryId(), category); + } + + EDDataParams folderParames = new EDDataParams(); + List fileAllList = edDataRepository.getDataInfoList(folderParames); //获取所有文件信息数据 + Map fileAllMap = new HashMap(); //所有文件数组map + for (EDDataInfo fileFinfo : fileAllList) { + fileAllMap.put(fileFinfo.getDataId(), fileFinfo); + } + + List categoryInputList = new ArrayList(); //客户端输入的目录数组 + Map categoryInputMap = new HashMap(); //客户端输入的目录数组map + for (String categoryId : categoryIdInputList) { + Category category = categoryAllMap.get(categoryId); + if (category != null) { + categoryInputList.add(category); + categoryInputMap.put(categoryId, category); + } + } + + + // 将List转换为JSON字符串 + String jsonStringCategory = JSONUtil.toJsonStr(categoryInputList); + String categoryListFileFullPath = exportDataCachePath + "/categoryList.json"; + FileUtil.writeString(jsonStringCategory, categoryListFileFullPath, "utf-8"); + log.info("目录树数据已成功导出为JSON文件。" + categoryListFileFullPath); + + + // 导出文件信息数据和文件数据 + + List fileExportList = new ArrayList(); //需要导出的文件信息数据数组 + Map fileExportMap = new HashMap(); //需要导出的文件信息数据数组map + for (EDDataInfo fileFinfo : fileAllList) { + if (categoryInputMap.get(fileFinfo.getCategoryId()) != null) { + fileExportList.add(fileFinfo); + fileExportMap.put(fileFinfo.getDataId(), fileFinfo); + } + } + // 找出子文件夹下的文件 + for (EDDataInfo fileFinfo : fileAllList) { + if (fileExportMap.get(fileFinfo.getCategoryId()) != null) { + fileExportList.add(fileFinfo); + } + } + + // 将文件信息数据导出为json文件 + String jsonStringFile = JSONUtil.toJsonStr(fileExportList); + String fileListFileFullPath = exportDataCachePath + "/fileInfoList.json"; + FileUtil.writeString(jsonStringFile, fileListFileFullPath, "utf-8"); + log.info("文件数据已成功导出为JSON文件。" + fileListFileFullPath); + + + // 将文件 复制到 数据导出的缓存目录中 + String dataStoragePath = getDataStoragePath(); + String needExportfolder = ""; + for (Category category : categoryInputList) { + needExportfolder = dataStoragePath + category.getCategoryId() + FOLDER_NAME_SEPARATOR + category.getCategoryName(); + if (FileUtil.exist(needExportfolder)) { + Path source = Paths.get(needExportfolder); + Path target = Paths.get(exportDataCachePath); + FileUtil.copy(source, target); // StandardCopyOption.REPLACE_EXISTING + } + } + + log.info("文件数据已成功复制到目标目录。"); + + // 将目录树数据 和 文件夹及文件夹内数据 进行压缩打包 + Date date = new Date(); + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss"); + String dateString = sdf.format(date); + + zipPathFileName = dataCachePath + "/exportData_" + dateString; + enCodeZipPathFileName = dataCachePath + "/exportData_" + dateString + ".comac"; + + ZipUtil.zip(exportDataCachePath, zipPathFileName); + + AES aes = SecureUtil.aes(encodePasswd.getBytes()); // aesKey是加密密钥 + try ( + InputStream inputStream = new FileInputStream(zipPathFileName); + OutputStream outputStream = new FileOutputStream(enCodeZipPathFileName); + ) { + aes.encrypt(inputStream, outputStream, true); + } catch (Exception e) { + log.error("文件加密错误..", e); + } + + log.info("目录树数据+文件数据已成功复制到目标目录。" + zipPathFileName); + } + catch (Exception e) { + log.error("导出数据异常..", e); + } + finally { + // 删除 导出数据的 缓存目录 + FileUtil.del(exportDataCachePath); + } + + return enCodeZipPathFileName; + } + + /** + * 将解压后的数据导入到数据库中 + * @param folderPath 解压后的数据目录 + * @return + */ + public Map> importData(String folderPath) + { + // 获取所有目录树节点数据 + List categoryAllList = categoryRepository.getAllCategories(); + Map categoryAllMap = new HashMap(); //所有目录数组map + for (Category category : categoryAllList) { + categoryAllMap.put(category.getCategoryId(), category); + } + + // 获取所有文件信息数据 + EDDataParams parames = new EDDataParams(); + List fileInfoAllList = edDataRepository.getDataInfoList(parames); + Map fileInfoAllMap = new HashMap(); //所有文件数组map + for (EDDataInfo fileInfo : fileInfoAllList) { + fileInfoAllMap.put(fileInfo.getDataId(), fileInfo); + } + + + // 读取并反序列化目录树的JSON文件数据为List;然后写入到数据库中。 + String jsonStringCategory = FileUtil.readString(folderPath + "/categoryList.json", StandardCharsets.UTF_8); + JSONArray jsonArrayCategory = JSONUtil.parseArray(jsonStringCategory); + List categoryImportList = JSONUtil.toList(jsonArrayCategory, Category.class); + if (categoryImportList == null) { + log.error("读取并反序列化JSON文件数据为List失败!"); + return null; + } + // 将目录树数据写入到数据库中 + for (Category category : categoryImportList) { + if (categoryAllMap.get(category.getCategoryId()) == null) { + categoryRepository.createCategory(category); + } + } + + // 读取并反序列化文件信息的JSON文件数据为List;然后写入到数据库中。 + String jsonStringFile = FileUtil.readString(folderPath + "/fileInfoList.json", StandardCharsets.UTF_8); + JSONArray jsonArrayFile = JSONUtil.parseArray(jsonStringFile); + List fileInfoImportList = JSONUtil.toList(jsonArrayFile, EDDataInfo.class); + if (fileInfoImportList == null) { + log.error("读取并反序列化JSON文件数据为List失败!"); + return null; + } + // 将文件信息数据写入到数据库中 + for (EDDataInfo fileInfo : fileInfoImportList) { + if (fileInfoAllMap.get(fileInfo.getDataId()) == null) { + edDataRepository.createDataInfo(fileInfo); + } + } + + // 将解压后的文件夹和文件 移动到 上传文件的存储目录中 + List importFileSuccess = new ArrayList(); + List importFileFail = new ArrayList(); + + String dataStoragePath = getDataStoragePath(); + if (!FileUtil.exist(dataStoragePath)){ + FileUtil.mkdir(dataStoragePath); + } + + String importDataCachePath = folderPath; //导入数据时 数据文件解压后的目录 + String importFileCachePath = ""; //需要导入的文件的缓存路径 + String importFileCacheFullPath = ""; //需要导入的文件的全路径 + String fileStorageFolder = ""; //文件存储的文件夹 + String fileStoragePath = ""; //文件存储的文件夹路径 + String fileStorageFullPath = ""; //文件存储的文件全路径 + + for (EDDataInfo fileInfo : fileInfoImportList) { + fileStorageFolder = getFilePathOfFolder(fileInfo.getCategoryId()); + importFileCachePath = importDataCachePath + File.separator + fileStorageFolder; + importFileCacheFullPath = importFileCachePath + File.separator + fileInfo.getDataName(); + fileStoragePath = dataStoragePath + File.separator + fileStorageFolder; + fileStorageFullPath = fileStoragePath + File.separator + fileInfo.getDataName(); + + if (fileInfoAllMap.get(fileInfo.getDataId()) == null + && !fileStorageFolder.isEmpty() + && FileUtil.exist(importFileCachePath) + && FileUtil.exist(importFileCacheFullPath) + && !FileUtil.exist(fileStorageFullPath) + ) + { + if(fileInfo.getDataType().equals(dataTypeFolder)) { + if (!FileUtil.exist(fileStorageFullPath)) { + FileUtil.mkdir(fileStorageFullPath); + } + } else if(fileInfo.getDataType().equals(dataTypeFile)) { + Path source = Paths.get(importFileCacheFullPath); + Path target = Paths.get(fileStorageFullPath); + FileUtil.move(source,target,true); + } + + importFileSuccess.add(fileInfo.getDataId() + FOLDER_NAME_SEPARATOR + fileInfo.getDataName()); + } + else + { + importFileFail.add(fileInfo.getDataId() + FOLDER_NAME_SEPARATOR + fileInfo.getDataName()); + } + } + + + Map> result = new HashMap<>(); + result.put("success", importFileSuccess); + result.put("fail", importFileFail); + + return result; } diff --git a/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/user/repository/CategoryRepository.java b/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/user/repository/CategoryRepository.java index 176fb1c..fd7713d 100644 --- a/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/user/repository/CategoryRepository.java +++ b/domain/src/main/java/com/electromagnetic/industry/software/data/manage/domain/boardservice/user/repository/CategoryRepository.java @@ -2,7 +2,9 @@ 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.ArrayList; import java.util.List; +import java.util.Map; public interface CategoryRepository { @@ -30,4 +32,37 @@ public interface CategoryRepository { */ List selectChildCategories(Category category); + /** + * 创建目录树节点数据 + * @return + */ + Boolean createCategory(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 + */ + Category getParentCategories(String categoryId, List categoryList); + + + } 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/EleZipUtil.java b/electromagnetic-framework/src/main/java/electromagnetic/data/framework/share/util/EleZipUtil.java new file mode 100644 index 0000000..d279112 --- /dev/null +++ b/electromagnetic-framework/src/main/java/electromagnetic/data/framework/share/util/EleZipUtil.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 EleZipUtil { + /** + * 压缩指定路径的文件 + * @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/facade/src/main/java/com/electromagnetic/industry/software/data/manage/facade/EDDataFacade.java b/facade/src/main/java/com/electromagnetic/industry/software/data/manage/facade/EDDataFacade.java index 7f7f61a..2463609 100644 --- a/facade/src/main/java/com/electromagnetic/industry/software/data/manage/facade/EDDataFacade.java +++ b/facade/src/main/java/com/electromagnetic/industry/software/data/manage/facade/EDDataFacade.java @@ -1,9 +1,15 @@ package com.electromagnetic.industry.software.data.manage.facade; import com.electromagnetic.industry.software.data.manage.request.indicator.EDDataRequest; +import com.electromagnetic.industry.software.data.manage.request.indicator.FileChunkDTO; +import com.electromagnetic.industry.software.data.manage.request.indicator.FileChunkResultDTO; import com.electromagnetic.industry.software.data.manage.response.indicator.EDDataPageResponse; import electromagnetic.data.framework.share.model.ElectromagneticResult; +import org.springframework.core.io.InputStreamResource; +import org.springframework.http.ResponseEntity; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; import java.util.List; import java.util.Map; @@ -43,27 +49,53 @@ public interface EDDataFacade { * @param request * @return */ - ElectromagneticResult upload(EDDataRequest request); + ElectromagneticResult uploadFile(EDDataRequest request); /** * 下载 - * @param request + * + * @param dataId * @return */ - ElectromagneticResult>> download(EDDataRequest request); + ResponseEntity download(String dataId, HttpServletResponse response) throws IOException; /** - * 导出 - * @param request + * 导出数据 + * @param dataIdArr * @return */ - ElectromagneticResult batchExport(EDDataRequest request); + ResponseEntity batchExport(String dataIdArr, HttpServletResponse response) throws IOException; /** - * 导入 - * @param request + * 导入数据 + * @param fileChunkDTO * @return */ - ElectromagneticResult batchImport(EDDataRequest request); + ElectromagneticResult batchImport(FileChunkDTO fileChunkDTO); + + /** + * 获取已经上传的分片 + * @param identifier + * @return + */ + ElectromagneticResult> getUploadedChunkNums(String identifier); + + + /** + * 合并分片 + * @param identifier + * @param fileName + * @param totalChunks + * @return + */ + ElectromagneticResult mergeChunks(String identifier, String fileName, Integer totalChunks); + + + /** + * 检查分片是否存在 + * @param fileChunkDTO + * @return + */ + ElectromagneticResult checkChunkExist(FileChunkDTO fileChunkDTO); } diff --git a/facade/src/main/java/com/electromagnetic/industry/software/data/manage/request/indicator/EDDataRequest.java b/facade/src/main/java/com/electromagnetic/industry/software/data/manage/request/indicator/EDDataRequest.java index f924802..366cdc1 100644 --- a/facade/src/main/java/com/electromagnetic/industry/software/data/manage/request/indicator/EDDataRequest.java +++ b/facade/src/main/java/com/electromagnetic/industry/software/data/manage/request/indicator/EDDataRequest.java @@ -4,10 +4,11 @@ import electromagnetic.data.framework.share.model.BaseRequest; import lombok.Data; import org.springframework.web.multipart.MultipartFile; +import java.io.Serializable; import java.util.Date; @Data -public class EDDataRequest extends BaseRequest { +public class EDDataRequest extends BaseRequest implements Serializable { /** * 当前页 @@ -29,6 +30,10 @@ public class EDDataRequest extends BaseRequest { * 文件夹名称 */ private String name; + /** + * 文件类型 + */ + private String dataType; /** * 创建日期排序 */ diff --git a/facade/src/main/java/com/electromagnetic/industry/software/data/manage/request/indicator/FileChunkDTO.java b/facade/src/main/java/com/electromagnetic/industry/software/data/manage/request/indicator/FileChunkDTO.java new file mode 100644 index 0000000..4a3b66a --- /dev/null +++ b/facade/src/main/java/com/electromagnetic/industry/software/data/manage/request/indicator/FileChunkDTO.java @@ -0,0 +1,18 @@ +package com.electromagnetic.industry.software.data.manage.request.indicator; + +import lombok.Data; +import org.springframework.web.multipart.MultipartFile; + +@Data +public class FileChunkDTO { + + private String identifier; + private long totalSize; + private MultipartFile file; + private String fileName; + private Integer chunkNumber; + private Long chunkSize; + private Long currentChunkSize; + private Integer totalChunks; + +} diff --git a/facade/src/main/java/com/electromagnetic/industry/software/data/manage/request/indicator/FileChunkResultDTO.java b/facade/src/main/java/com/electromagnetic/industry/software/data/manage/request/indicator/FileChunkResultDTO.java new file mode 100644 index 0000000..6dc4498 --- /dev/null +++ b/facade/src/main/java/com/electromagnetic/industry/software/data/manage/request/indicator/FileChunkResultDTO.java @@ -0,0 +1,15 @@ +package com.electromagnetic.industry.software.data.manage.request.indicator; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Set; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class FileChunkResultDTO { + private Boolean skipUpload; + private Set uploaded; +} diff --git a/facade/src/main/java/com/electromagnetic/industry/software/data/manage/request/indicator/FileDownloadDTO.java b/facade/src/main/java/com/electromagnetic/industry/software/data/manage/request/indicator/FileDownloadDTO.java new file mode 100644 index 0000000..244fe2f --- /dev/null +++ b/facade/src/main/java/com/electromagnetic/industry/software/data/manage/request/indicator/FileDownloadDTO.java @@ -0,0 +1,8 @@ +package com.electromagnetic.industry.software.data.manage.request.indicator; + +import lombok.Data; + +@Data +public class FileDownloadDTO { + private String dataId; +} diff --git a/facade/src/main/java/com/electromagnetic/industry/software/data/manage/response/indicator/EDDataResponse.java b/facade/src/main/java/com/electromagnetic/industry/software/data/manage/response/indicator/EDDataResponse.java index 1e8d19a..28c6089 100644 --- a/facade/src/main/java/com/electromagnetic/industry/software/data/manage/response/indicator/EDDataResponse.java +++ b/facade/src/main/java/com/electromagnetic/industry/software/data/manage/response/indicator/EDDataResponse.java @@ -61,6 +61,22 @@ public class EDDataResponse implements Serializable { * 状态:publish:发布,occupy:占用 */ private String dataStatus; + /** + * 备注 + */ + private String note; + /** + * 编辑人 + */ + private String editor; + /** + * 批量上传时间 + */ + private Date gmtBatchUpload; + /** + * 保存状态 + */ + private String saveStatus; /** * 创建人 */ diff --git a/infrastructure/repository/src/main/java/com/electromagnetic/industry/software/data/manage/repository/dao/CategoryMapper.java b/infrastructure/repository/src/main/java/com/electromagnetic/industry/software/data/manage/repository/dao/CategoryMapper.java index 9f51c2c..cd557db 100644 --- a/infrastructure/repository/src/main/java/com/electromagnetic/industry/software/data/manage/repository/dao/CategoryMapper.java +++ b/infrastructure/repository/src/main/java/com/electromagnetic/industry/software/data/manage/repository/dao/CategoryMapper.java @@ -31,4 +31,11 @@ public interface CategoryMapper { * @return */ List selectChildCategories(Category category); + + /** + * 创建目录树节点数据 + * @return + */ + Boolean createCategory(Category category); + } diff --git a/infrastructure/repository/src/main/java/com/electromagnetic/industry/software/data/manage/repository/impl/CategoryRepositoryImpl.java b/infrastructure/repository/src/main/java/com/electromagnetic/industry/software/data/manage/repository/impl/CategoryRepositoryImpl.java index 2af6889..c69c2f8 100644 --- a/infrastructure/repository/src/main/java/com/electromagnetic/industry/software/data/manage/repository/impl/CategoryRepositoryImpl.java +++ b/infrastructure/repository/src/main/java/com/electromagnetic/industry/software/data/manage/repository/impl/CategoryRepositoryImpl.java @@ -6,7 +6,9 @@ import com.electromagnetic.industry.software.data.manage.repository.dao.Category import org.springframework.stereotype.Repository; import javax.annotation.Resource; +import java.util.ArrayList; import java.util.List; +import java.util.Map; @Repository public class CategoryRepositoryImpl implements CategoryRepository { @@ -44,4 +46,76 @@ public class CategoryRepositoryImpl implements CategoryRepository { @Override public List selectChildCategories(Category category) { return categoryMapper.selectChildCategories(category); } + /** + * 创建目录树节点数据 + * @return + */ + @Override + public Boolean createCategory(Category category) { return categoryMapper.createCategory(category); } + + + /** + * 通过 节点 获取到顶级节点的树路径 从指定的节点数组中 + * @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(Category category, List categoryList) + { + Category categoryParent = null; + for(Category iter : categoryList) + { + if(categoryParent == null && iter.getCategoryId().equals(category.getParentId())) + { + categoryParent = iter; + 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/infrastructure/repository/src/main/java/com/electromagnetic/industry/software/data/manage/repository/impl/EDDataRepositoryImpl.java b/infrastructure/repository/src/main/java/com/electromagnetic/industry/software/data/manage/repository/impl/EDDataRepositoryImpl.java index 9c68ef8..9fdf44d 100644 --- a/infrastructure/repository/src/main/java/com/electromagnetic/industry/software/data/manage/repository/impl/EDDataRepositoryImpl.java +++ b/infrastructure/repository/src/main/java/com/electromagnetic/industry/software/data/manage/repository/impl/EDDataRepositoryImpl.java @@ -71,18 +71,5 @@ public class EDDataRepositoryImpl implements EDDataRepository { return edDataMapper.updateFileInfo(parames); } - /** - * 下载 - * @param parames - * @return - */ - @Override - public Boolean download(EDDataParams parames) - { - //return edDataMapper.download(parames); - return Boolean.TRUE; - } - - } \ No newline at end of file diff --git a/infrastructure/repository/src/main/resources/sqlmapper/CategoryMapper.xml b/infrastructure/repository/src/main/resources/sqlmapper/CategoryMapper.xml index 37a864d..33c9002 100644 --- a/infrastructure/repository/src/main/resources/sqlmapper/CategoryMapper.xml +++ b/infrastructure/repository/src/main/resources/sqlmapper/CategoryMapper.xml @@ -36,13 +36,32 @@ + + + SELECT LAST_INSERT_ID() + + insert into ed_data_info (id, + category_type_id, parent_id, category_id, + category_name, category_status, + creator, creator_name, gmt_create, + modifier, modifier_name, gmt_modified, + effect_flag + ) + values (#{id,jdbcType=VARCHAR}, #{categoryTypeId,jdbcType=VARCHAR}, + #{parentId,jdbcType=VARCHAR}, #{categoryId,jdbcType=VARCHAR}, + #{categoryName,jdbcType=VARCHAR}, #{categoryStatus,jdbcType=VARCHAR}, + #{creator,jdbcType=VARCHAR}, #{creatorName,jdbcType=VARCHAR}, now(), #{modifier,jdbcType=VARCHAR}, + #{modifierName,jdbcType=VARCHAR},now(),1 + ) + + \ No newline at end of file diff --git a/infrastructure/repository/src/main/resources/sqlmapper/EdDataInfoMapper.xml b/infrastructure/repository/src/main/resources/sqlmapper/EdDataInfoMapper.xml index 39c1094..a8ed76a 100644 --- a/infrastructure/repository/src/main/resources/sqlmapper/EdDataInfoMapper.xml +++ b/infrastructure/repository/src/main/resources/sqlmapper/EdDataInfoMapper.xml @@ -10,6 +10,7 @@ + @@ -37,7 +38,7 @@ SELECT LAST_INSERT_ID() - insert into ed_data_info (id, category_id, + insert into ed_data_info (category_id, data_id, data_no, data_name, data_type, file_type, version, content, implant_json, data_status, @@ -46,7 +47,7 @@ modifier, modifier_name, gmt_modified, effect_flag ) - values (#{id,jdbcType=VARCHAR}, #{categoryId,jdbcType=VARCHAR}, + values (#{categoryId,jdbcType=VARCHAR}, #{dataId,jdbcType=VARCHAR}, #{dataNo,jdbcType=VARCHAR}, #{dataName,jdbcType=VARCHAR}, #{dataType,jdbcType=VARCHAR}, #{fileType,jdbcType=VARCHAR},#{version,jdbcType=VARCHAR}, #{content,jdbcType=VARCHAR}, #{implantJson,jdbcType=VARCHAR}, #{dataStatus,jdbcType=VARCHAR}, @@ -73,6 +74,9 @@ and data_name LIKE '%${keyWord}%' + + and data_type = '${dataType}' + and save_status='${saveStatus}' @@ -102,10 +106,18 @@ gmt_modified = now() - where data_id = #{dataId,jdbcType=VARCHAR} and effect_flag = 1 + + + + data_id = #{dataId,jdbcType=VARCHAR} + + + + category_id = #{parentId,jdbcType=VARCHAR} + + + - - diff --git a/pom.xml b/pom.xml index 39ef8b7..2bce119 100644 --- a/pom.xml +++ b/pom.xml @@ -255,6 +255,7 @@ + electromagnetic org.apache.maven.plugins diff --git a/service/src/main/java/com/electromagnetic/industry/software/data/manage/service/aop/ServiceAspect.java b/service/src/main/java/com/electromagnetic/industry/software/data/manage/service/aop/ServiceAspect.java index a7538c7..2ca26d3 100644 --- a/service/src/main/java/com/electromagnetic/industry/software/data/manage/service/aop/ServiceAspect.java +++ b/service/src/main/java/com/electromagnetic/industry/software/data/manage/service/aop/ServiceAspect.java @@ -1,18 +1,21 @@ package com.electromagnetic.industry.software.data.manage.service.aop; import com.alibaba.fastjson.JSON; -import electromagnetic.data.framework.share.exception.LoggerConstant; -import electromagnetic.data.framework.share.log.LogUtils; -import electromagnetic.data.framework.share.log.ServiceResultHandleUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.catalina.connector.ResponseFacade; import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; +import org.springframework.util.StopWatch; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.multipart.MultipartFile; - +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import java.util.ArrayList; +import java.util.List; /** * service 通用日志切面 * @@ -21,33 +24,56 @@ import org.springframework.stereotype.Component; */ @Aspect @Component +@Slf4j public class ServiceAspect { - private static final Logger LOGGER = LoggerFactory.getLogger(LoggerConstant.DOMAIN_SERVICE); - /** * 日志切面 */ @Around("execution(* com.electromagnetic.industry.software.data.manage.facade..*.*(..)))") - public Object logAspect(ProceedingJoinPoint pjd) { - long startTime = System.currentTimeMillis(); - Object[] args = pjd.getArgs(); - Object arg = args.length < 1 ? "" : args[0]; - Signature signature = pjd.getSignature(); - String declaringTypeName = signature.getDeclaringTypeName(); - String logPattern = declaringTypeName.substring(declaringTypeName.lastIndexOf(".") + 1) + "@" + signature.getName() + " request={0}, response={1}, cost={2}ms"; - Object proceed = null; - try { - proceed = pjd.proceed(args); - } catch (Throwable t) { - LogUtils.error(t,LOGGER, "Executing " + logPattern+",Throwable:"+t, - arg == null ? "" : JSON.toJSONString(arg), JSON.toJSONString(proceed), System.currentTimeMillis() - startTime); - return ServiceResultHandleUtil.serviceError(t); - } + public Object process(ProceedingJoinPoint jp) throws Throwable { + String methodInfo = jp.getTarget().getClass().getSimpleName() + "." + + jp.getSignature().getName(); + Object[] args = jp.getArgs(); + String paramInfo = ""; + if (args != null && args.length > 0) { + if (args[0] != null && args[0].getClass() != ResponseFacade.class) { + try { + List list = new ArrayList<>(); + for (Object obj : jp.getArgs()) { - // 正常返回日志 - LogUtils.info(LOGGER, "End " + logPattern, - arg == null ? "" : JSON.toJSONString(arg), JSON.toJSONString(proceed), System.currentTimeMillis() - startTime); - return proceed; + if (obj instanceof ServletResponse) { + log.info("参数中有response"); + } else if (obj instanceof ServletRequest) { + log.info("参数中有request"); + } else if (obj instanceof MultipartFile) { + //文件不输出 + MultipartFile obj1 = (MultipartFile) obj; + log.info("参数中文件;文件名:{},文件大小:{}", obj1.getName(), obj1.getSize()); + break; + } else { + list.add(obj); + } + } + + paramInfo = JSON.toJSONString(list); + } catch (Exception e) { + log.warn("切面异常", e.getMessage()); + } + } + } + log.info("请求接口开始:{},参数:{}", methodInfo, paramInfo); + long startTime = System.currentTimeMillis(); + StopWatch stopwatch = new StopWatch(); + stopwatch.start("接口:" + methodInfo); + Object rvt = jp.proceed(); + if (rvt instanceof ResponseEntity) { + return rvt; + } + String returnInfo = JSON.toJSONString(rvt); + log.info("请求接口结束:{},返回参数:{},接口耗时:{}", methodInfo, returnInfo, (System.currentTimeMillis() - startTime) + "毫秒"); + stopwatch.stop(); + log.debug(stopwatch.prettyPrint()); + return rvt; } } 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 34dce55..6a8d8bf 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,40 +1,65 @@ package com.electromagnetic.industry.software.data.manage.service.facade; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONObject; -import com.electromagnetic.industry.software.data.manage.domain.boardservice.category.model.Category; +import cn.hutool.core.codec.Base64; +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.io.IoUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.ZipUtil; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.symmetric.AES; import com.electromagnetic.industry.software.data.manage.domain.boardservice.indicator.model.EDDataInfo; import com.electromagnetic.industry.software.data.manage.domain.boardservice.indicator.model.EDDataPage; import com.electromagnetic.industry.software.data.manage.domain.boardservice.indicator.parames.EDDataParams; import com.electromagnetic.industry.software.data.manage.domain.boardservice.indicator.service.EDDataService; -import com.electromagnetic.industry.software.data.manage.domain.boardservice.user.service.CategoryService; import com.electromagnetic.industry.software.data.manage.facade.EDDataFacade; import com.electromagnetic.industry.software.data.manage.request.indicator.EDDataRequest; +import com.electromagnetic.industry.software.data.manage.request.indicator.FileChunkDTO; +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 electromagnetic.data.framework.share.id.IdWorker; import electromagnetic.data.framework.share.model.ElectromagneticResult; import electromagnetic.data.framework.share.model.ElectromagneticResultUtil; -import org.springframework.http.HttpStatus; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; + +import org.springframework.core.io.FileSystemResource; +import org.springframework.core.io.InputStreamResource; +import org.springframework.http.*; import org.springframework.stereotype.Service; -import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; -import java.io.File; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; @Service +@Slf4j public class EDDataFacadeImpl implements EDDataFacade { @Resource private EDDataService edDataService; - private CategoryService categoryService; + + @Value("${data.windows.path}") + private String uploadFilePath; + + @Value("${data.file.storage.dir}") + private String fileStorageDir; + + + @Value("${data.import.cache.dir}") + private String importCacheDir; + + @Value("${file.encode.passwd}") + private String encodePasswd; + + @Value("${data.type.folder}") + private String dataTypeFolder; + + private static final String UPLOAD_FILE_CHUNK_SUFFIX = ".part"; + /** * 创建文件夹 @@ -48,14 +73,6 @@ public class EDDataFacadeImpl implements EDDataFacade { public ElectromagneticResult createFolder(EDDataRequest request) { EDDataInfo edDataInfo = EDDataMappers.INSTANCE.getEDDataInfo(request); - // 临时数据设置 - if(Boolean.TRUE) { - if (request.getUserId() == null || request.getUserId().isEmpty()) request.setUserId(IdWorker.getSnowFlakeIdString()); - if (request.getUserName() == null || request.getUserName().isEmpty()) request.setUserName("user"); - if (request.getName() == null || request.getName().isEmpty()) request.setName("testFolder"); - //if (request.getParentId() == null || request.getParentId().isEmpty()) request.setParentId(IdWorker.getSnowFlakeIdString()); - } - edDataInfo.setCreator(request.getUserId()); edDataInfo.setCreatorName(request.getUserName()); edDataInfo.setModifier(request.getUserId()); @@ -63,58 +80,21 @@ public class EDDataFacadeImpl implements EDDataFacade { edDataInfo.setCategoryId(request.getParentId()); edDataInfo.setDataName(request.getName()); edDataInfo.setNote(request.getNote()); + edDataInfo.setGmtBatchUpload(new Date()); edDataInfo.setDataId(IdWorker.getSnowFlakeIdString()); edDataInfo.setDataNo(edDataInfo.getDataId()); - edDataInfo.setDataType("folder"); + edDataInfo.setDataType(dataTypeFolder); edDataInfo.setVersion("1.0.0"); edDataInfo.setDataStatus("publish"); + edDataInfo.setSaveStatus("success"); - String parentFolderPath = ""; - // 获取上级目录的名称 - if(!request.getParentId().isEmpty()) { - EDDataParams parames = new EDDataParams(); - parames.setDataId(request.getParentId()); - EDDataInfo edDataInfoParent = edDataService.getDataInfo(parames); - if(edDataInfoParent == null) { - ElectromagneticResultUtil.fail(HttpStatus.BAD_REQUEST.toString(),"上级文件夹为空!"); - } - - String folderNameParent = edDataInfoParent.getDataName(); - String folderIdParent = edDataInfoParent.getDataId(); - - // 记录当前目录的文件夹路径和文件夹id路径 - JSONObject implantJsonObject = JSON.parseObject(edDataInfoParent.getImplantJson()); - if(implantJsonObject == null) { - implantJsonObject = new JSONObject(); - parentFolderPath = folderNameParent; - implantJsonObject.put("folderPath", parentFolderPath); - implantJsonObject.put("folderIdPath", folderIdParent); - } - else - { - String folderPath = implantJsonObject.getString("folderPath"); - String folderIdPath = implantJsonObject.getString("folderIdPath"); - parentFolderPath = folderPath + "/" + folderNameParent; - implantJsonObject.put("folderPath", parentFolderPath); - implantJsonObject.put("folderIdPath", folderIdPath + "/" + folderIdParent); - } - - String newImplantJson = implantJsonObject.toJSONString(); - edDataInfo.setImplantJson(newImplantJson); + try { + return ElectromagneticResultUtil.success(edDataService.createDataInfo(edDataInfo)); + } catch (FileNotFoundException e) { + log.error("创建文件夹失败。。。", e); + return ElectromagneticResultUtil.fail("500", e.getMessage()); } - - boolean isSuccess = edDataService.createDataInfo(edDataInfo); - if(isSuccess) - { - // 获取文件存储的文件夹路径 - String storageDirectory = "D:/fileTemp/" + parentFolderPath + "/" + edDataInfo.getDataName(); - if(!edDataService.checkFolderIsExist(storageDirectory)) { - edDataService.createMultiLevelDirectory(storageDirectory); - } - } - - return ElectromagneticResultUtil.success(Boolean.TRUE); } @@ -146,9 +126,13 @@ public class EDDataFacadeImpl implements EDDataFacade { */ public ElectromagneticResult updateFileInfo(EDDataRequest request) { - EDDataParams parames= EDDataMappers.INSTANCE.getEDDataParames(request); - edDataService.updateFileInfo(parames); - return ElectromagneticResultUtil.success(Boolean.TRUE); + try { + EDDataParams parames= EDDataMappers.INSTANCE.getEDDataParames(request); + return ElectromagneticResultUtil.success(edDataService.updateFileInfo(parames)); + } catch (FileNotFoundException e) { + log.error("文件信息更新失败。。。", e); + return ElectromagneticResultUtil.fail("500", e.getMessage()); + } } /** @@ -174,193 +158,62 @@ public class EDDataFacadeImpl implements EDDataFacade { * @param request * @return */ - public ElectromagneticResult upload(EDDataRequest request) + public ElectromagneticResult uploadFile(EDDataRequest request) { - EDDataParams parames= EDDataMappers.INSTANCE.getEDDataParames(request); - try { - // 获取目录编码ID - String categoryId = request.getParentId(); - - // 获取要上传的文件 - MultipartFile fileInput = request.getFileData(); - - // 检查文件是否为空 - if (fileInput == null || fileInput.isEmpty()) { - return ElectromagneticResultUtil.fail(HttpStatus.BAD_REQUEST.toString(),"上传的文件为空"); - } - - // 获取文件名 - String fileFullName = fileInput.getOriginalFilename(); - // 获取文件类型 - String fileType = ""; - // 获取文件名称 - String fileName = ""; - if (fileFullName.lastIndexOf(".") != -1 && fileFullName.lastIndexOf(".") != 0) { - fileType = fileFullName.substring(fileFullName.lastIndexOf(".") + 1); - fileName = fileFullName.substring(fileFullName.lastIndexOf(".")); - } - - // 获取文件存储的文件夹路径 - String storageDirectory = "D:/fileTemp"; - if(!edDataService.checkFolderIsExist(storageDirectory)) { - edDataService.createMultiLevelDirectory(storageDirectory); - } - - String parentFolderPath = ""; //上级文件夹路径 - String parentFolderIdPath = ""; //上级文件夹ID路径 - String parentFolderName = ""; //上级文件夹名称 - - // 获取上级文件夹路径 - { - 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(); - } - - // 文件保存目录路径 - String fileSavePath = storageDirectory + "/" + parentFolderPath; - String treeName = "目录树名称"; - //String newFileName = treeName + "," + parentFolderName + "," + fileFullName; - String newFileName = fileFullName; - - // 文件数据信息写到数据库 - { - // 临时数据设置 - if(Boolean.TRUE) { - if (request.getUserId() == null || request.getUserId().isEmpty()) request.setUserId(IdWorker.getSnowFlakeIdString()); - if (request.getUserName() == null || request.getUserName().isEmpty()) request.setUserName("user"); - //if (request.getName() == null || request.getName().isEmpty()) request.setName("testFolder"); - if (request.getParentId() == null || request.getParentId().isEmpty()) request.setParentId(IdWorker.getSnowFlakeIdString()); - } - - // 创建新文件数据 - EDDataInfo edDataInfo = new EDDataInfo(); - edDataInfo.setCreator(request.getUserId()); - edDataInfo.setCreatorName(request.getUserName()); - edDataInfo.setModifier(request.getUserId()); - edDataInfo.setModifierName(request.getUserName()); - edDataInfo.setCategoryId(request.getParentId()); - edDataInfo.setDataName(newFileName); - edDataInfo.setNote(request.getNote()); - edDataInfo.setFileType(fileType); - edDataInfo.setGmtBatchUpload(request.getGmtBatchUpload()); - - edDataInfo.setDataId(IdWorker.getSnowFlakeIdString()); - edDataInfo.setDataNo(edDataInfo.getDataId()); - edDataInfo.setDataType("file"); - edDataInfo.setVersion("1.0.0"); - edDataInfo.setDataStatus("publish"); - edDataInfo.setSaveStatus("saving"); - - JSONObject newImplantJsonObject = new JSONObject(); - newImplantJsonObject.put("folderPath", parentFolderPath); - newImplantJsonObject.put("folderIdPath", parentFolderIdPath); - edDataInfo.setImplantJson(newImplantJsonObject.toJSONString()); - - boolean isSuccess = edDataService.createDataInfo(edDataInfo); - - String userHome = System.getProperty("user.home"); - File cacheDirectory = new File(userHome + "\\AppData\\Local\\Temp\\EDData\\Upload"); - if (!cacheDirectory.exists()) { - cacheDirectory.mkdirs(); - } - - String cacheFolder = cacheDirectory.getAbsolutePath(); - - String cachePath = cacheFolder + "/" + newFileName; - System.out.println("文件缓存路径为: " + cacheDirectory.getAbsolutePath()); - fileSavePath += "/" + newFileName; - - - // 这里可以添加将文件保存到本地磁盘或其他存储介质的逻辑 - File saveFile = new File(cachePath);//fileSavePath - - // 将文件保存到硬盘 - fileInput.transferTo(saveFile); - - EDDataParams fileParames = new EDDataParams(); - fileParames.setDataId(edDataInfo.getDataId()); - if(fileInput.getSize() == saveFile.length()) - { - Path source = Paths.get(cachePath); - Path target = Paths.get(fileSavePath); - Files.move(source, target); - fileParames.setSaveStatus("success"); - } - else - { - saveFile.delete(); - fileParames.setSaveStatus("failure"); - } - - isSuccess = edDataService.updateFileInfo(fileParames); - - } - - // 如果文件上传成功,返回成功消息 - return ElectromagneticResultUtil.success(Boolean.TRUE); - } catch (Exception e) { - // 如果出现异常,返回异常消息 - return ElectromagneticResultUtil.fail(HttpStatus.INTERNAL_SERVER_ERROR.toString(),"文件上传失败" + e.getMessage()); + EDDataParams parames= EDDataMappers.INSTANCE.getEDDataParames(request); + return ElectromagneticResultUtil.success(edDataService.uploadFile(parames)); + } catch (FileNotFoundException e) { + log.error("上传文件失败。。。", e); + return ElectromagneticResultUtil.fail("500", e.getMessage()); } - } /** * 下载 * WISDOM_DOWNLOAD * /data/ed/file/download - * @param request + * + * @param dataId * @return */ - public ElectromagneticResult>> download(EDDataRequest request) + public ResponseEntity download(String dataId, HttpServletResponse response) throws IOException { - //EDDataParams parames= EDDataMappers.INSTANCE.getEDDataParames(request); // 获取文件存储的文件夹路径 - String storageDirectory = "D:/fileTemp"; + String osName = System.getProperty("os.name").toLowerCase(); + String storageFilePath = osName.startsWith("win") ? uploadFilePath + fileStorageDir : fileStorageDir; EDDataParams parames = new EDDataParams(); - List dataPathArr = new ArrayList(); - for(String dataId : request.getDataIdArr()) - { - parames.setDataId(dataId); - EDDataInfo edDataInfo = edDataService.getDataInfo(parames); - if(edDataInfo != null) - { - JSONObject implantJsonObject = JSON.parseObject(edDataInfo.getImplantJson()); - String filePath = implantJsonObject.getString("folderPath"); - filePath = storageDirectory + "/" + filePath + "/" + edDataInfo.getDataName(); - dataPathArr.add(filePath); - } - } + parames.setDataId(dataId); + EDDataInfo edDataInfo = edDataService.getDataInfo(parames); + Assert.isTrue(edDataInfo != null, "没有找到该下载文件"); + String filePathOfFolder = edDataService.getFilePathOfFolder(edDataInfo.getCategoryId()); + String filePath = storageFilePath + "/" + filePathOfFolder + "/" + edDataInfo.getDataName(); - Map> result = new HashMap<>(); - result.put("urlArr", dataPathArr); - - return ElectromagneticResultUtil.success(result); + Assert.isTrue(FileUtil.exist(filePath), "下载文件不存在。"); + FileSystemResource fileSystemResource = new FileSystemResource(filePath); + HttpHeaders headers = new HttpHeaders(); + headers.add("Cache-Control", "no-cache, no-store, must-revalidate"); + headers.add("Pragma", "no-cache"); + headers.add("Expires", "0"); + String fileName = Base64.encode(fileSystemResource.getFilename()); + response.setHeader("content-disposition","attachment;filename=" + fileName); + // 构建响应实体(可以返回 batchExport(EDDataRequest request) { + public ResponseEntity batchExport(String dataIdArr, HttpServletResponse response) throws IOException { //1、根据用户选择层级树编码查出所有文件和文件夹list //2、循环list将每个文件复制到新建目录并进行重命名,命名规则:目录树编码+,+文件夹编码(有则填写无则为空)+,+文件编码 //3、打包新建为zip,并根据生产下载地址(域名+文件路径+文件) @@ -368,86 +221,190 @@ public class EDDataFacadeImpl implements EDDataFacade { // **********在导出的过程中可能会出现有用户上传文件的情况 - // 获取目录编码ID - String categoryId = request.getParentId(); + Map result = new HashMap<>(); + List dataIdList = Arrays.asList(dataIdArr.split(",")); + if(dataIdList.size() > 0) { + String filePath = edDataService.exportData(dataIdList); + + Assert.isTrue(FileUtil.exist(filePath), "下载文件不存在。"); + File file = new File(filePath); + 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); + + // 构建响应实体(可以返回 categoryList = categoryService.selectAllCategories(); - - { - // 遍历客户端上传的 - 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 parentFolderPath = ""; //上级文件夹路径 - String parentFolderIdPath = ""; //上级文件夹ID路径 - String parentFolderName = ""; //上级文件夹名称 - - // 获取上级文件夹路径 - { - 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(); - } - - return null; } /** * 导入 - * @param request + * @param fileChunkDTO * @return */ @Override - public ElectromagneticResult batchImport(EDDataRequest request) { - //1、上传文件到指定目录,并重命名 - //2、接下压缩包 - //3、扫码解压文件夹的所有文件 - //4、循环处理文件:读取文件名称,根据名称规则,进行数据库查询,匹配层级树、文件夹和文件是否跳过 - //5、如果不存在则新建文件记录 - //6、并移动文件到上传目录 - //7、处理完成返回成功 - return null; + public ElectromagneticResult batchImport(FileChunkDTO fileChunkDTO) { + + String identifier = fileChunkDTO.getIdentifier(); + String fileName = fileChunkDTO.getFileName(); + + String dataCachePath = edDataService.getDataCachePath(); + String importDataCachePath = dataCachePath + importCacheDir; + + // 首先检查文件是否存在,如果存在则不允许重复上传。 + String destZipPath = importDataCachePath + identifier + File.separator + fileName; + boolean existFile = FileUtil.exist(new File(destZipPath)); + if (existFile) { + return ElectromagneticResultUtil.fail("-1", "文件已经存在,请勿重复上传。"); + } + + // 检查该分片有没被上传过 + String destChunkPath = importDataCachePath + identifier + File.separator + fileChunkDTO.getChunkNumber() + UPLOAD_FILE_CHUNK_SUFFIX; + boolean existChunk = FileUtil.exist(new File(destChunkPath)); + if (existChunk) { + return ElectromagneticResultUtil.success(true); + } + + File dir = new File(importDataCachePath + identifier + File.separator); + if (!dir.exists()) { + dir.mkdir(); + } + + try ( + InputStream inputStream = fileChunkDTO.getFile().getInputStream(); + FileOutputStream fileOutputStream = new FileOutputStream(destChunkPath); + ) { + IoUtil.copy(inputStream, fileOutputStream); + } catch (IOException ioException) { + log.error("上传文件错误...", ioException); + } + return ElectromagneticResultUtil.success(fileChunkDTO.getIdentifier()); + } + + @Override + public ElectromagneticResult> getUploadedChunkNums(String identifier) { + return ElectromagneticResultUtil.success(getUploadedChunks(identifier)); + } + + private List getUploadedChunks(String identifier) { + String dataCachePath = edDataService.getDataCachePath(); + String importDataCachePath = dataCachePath + importCacheDir; + String destPath = importDataCachePath + identifier; + if (!FileUtil.exist(new File(destPath))) { + return new ArrayList<>(); + } + + List uploadedFileChunkNums = FileUtil.listFileNames(destPath) + .stream() + .filter(e -> !e.endsWith(".comac")) + .map(e -> e.replace(UPLOAD_FILE_CHUNK_SUFFIX, "")) + .map(Integer::parseInt) + .collect(Collectors.toList()); + return uploadedFileChunkNums; + } + + // TODO 需要验证如果一个分片上传一半网络断开,则该分片的存储情况。 + @Override + public ElectromagneticResult mergeChunks(String identifier, String fileName, Integer totalChunks) { + String dataCachePath = edDataService.getDataCachePath(); + String importDataCachePath = dataCachePath + importCacheDir; + + // 检查所有分片是否已经上传完成,分片编号从1开始 + for (int i = 1; i <= totalChunks; i++) { + String tmpPath = importDataCachePath + identifier + File.separator + i + UPLOAD_FILE_CHUNK_SUFFIX; + if (!FileUtil.exist(new File(tmpPath))) { + log.error("第{}个分片没有上传完成,请上传完成后再合并。", i); + ElectromagneticResultUtil.fail("-1", "文件尚未上传完成。"); + } + } + + // 合并分片 + String destZipPath = importDataCachePath + identifier + File.separator + fileName; + File mergedFile = new File(destZipPath); + try { + RandomAccessFile targetFile = new RandomAccessFile(mergedFile, "rw"); + byte[] buffer = new byte[1024]; + for (int i = 1; i <= totalChunks; i++) { + String tmpPath = importDataCachePath + identifier + File.separator + i + UPLOAD_FILE_CHUNK_SUFFIX; + RandomAccessFile tmp = new RandomAccessFile(new File(tmpPath), "r"); + int len; + while ((len = tmp.read(buffer)) != -1) { + targetFile.write(buffer, 0, len); + } + tmp.close(); + } + targetFile.close(); + } catch (IOException ioException) { + ElectromagneticResultUtil.fail("-1", "文件合并失败"); + } + + // 删除分片 + for (int i = 1; i <= totalChunks; i++) { + String tmpPath = importDataCachePath + identifier + File.separator + i + UPLOAD_FILE_CHUNK_SUFFIX; + FileUtil.del(tmpPath); + } + + // 检验文件的MD5值 + + // 解密文件 + String decryptFilePath = destZipPath + "_decrypted"; + AES aes = SecureUtil.aes(encodePasswd.getBytes()); // aesKey是加密密钥 + try( + InputStream inputStream = new FileInputStream(destZipPath); + OutputStream outputStream = new FileOutputStream(decryptFilePath); + ) { + aes.decrypt(inputStream, outputStream, true); + } catch (Exception e) { + log.error("文件加密错误..", e); + } + + // 解压文件 + String unzipFileOutputPath = importDataCachePath + identifier + File.separator; + ZipUtil.unzip(decryptFilePath, unzipFileOutputPath); + + // 文件信息存入数据库 + Map> result = edDataService.importData(importDataCachePath + identifier); + + // 删除 解压数据的 缓存目录 + FileUtil.del(unzipFileOutputPath); + + return ElectromagneticResultUtil.success(result); + } + + @Override + public ElectromagneticResult checkChunkExist(FileChunkDTO fileChunkDTO) { + String dataCachePath = edDataService.getDataCachePath(); + String importDataCachePath = dataCachePath + importCacheDir; + + FileChunkResultDTO res = new FileChunkResultDTO(); + // 首先判断zip文件是否存在,如果不存在则表示还没有上传完成。 + String identifier = fileChunkDTO.getIdentifier(); + String fileName = fileChunkDTO.getFileName(); + String destZipPath = importDataCachePath + identifier + File.separator + fileName; + boolean existFile = FileUtil.exist(new File(destZipPath)); + + if (existFile) { + return ElectromagneticResultUtil.success(new FileChunkResultDTO(true, new HashSet<>())); + } + + List uploadedChunks = getUploadedChunks(identifier); + return ElectromagneticResultUtil.success(new FileChunkResultDTO(false, new HashSet<>(uploadedChunks))); } + }