| | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.apache.commons.codec.digest.DigestUtils; |
| | | import org.apache.commons.io.FileUtils; |
| | | import org.apache.commons.io.FilenameUtils; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.springblade.core.log.exception.ServiceException; |
| | | import org.springblade.core.mp.base.BizServiceImpl; |
| | |
| | | import org.springblade.core.tool.utils.Func; |
| | | import org.springblade.mdm.basesetting.machine.service.MachineService; |
| | | import org.springblade.mdm.basesetting.machine.entity.Machine; |
| | | import org.springblade.mdm.commons.contants.RegExpConstants; |
| | | import org.springblade.mdm.gkw.programnode.vo.ProgramNameVO; |
| | | import org.springblade.mdm.machinefile.entity.FileSendRecord; |
| | | import org.springblade.mdm.machinefile.service.FileSendRecordService; |
| | | import org.springblade.mdm.program.entity.NcProgramExchange; |
| | |
| | | import org.springblade.mdm.program.service.programannotation.AnnotationProperties; |
| | | import org.springblade.mdm.program.vo.MdmProgramImportVO; |
| | | import org.springblade.mdm.utils.FileContentUtil; |
| | | import org.springblade.mdm.utils.ProgramFileNameParser; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | |
| | | import java.time.Duration; |
| | | import java.util.*; |
| | | import java.nio.file.*; |
| | | import java.util.regex.Matcher; |
| | | import java.util.stream.Stream; |
| | | import java.util.zip.ZipEntry; |
| | | import java.util.zip.ZipInputStream; |
| | | /** |
| | |
| | | * @return |
| | | */ |
| | | public List<MdmProgramImportVO> mdmImportUpload(MultipartFile file) { |
| | | List<MdmProgramImportVO> list = new ArrayList<>(); |
| | | List<MdmProgramImportVO> list; |
| | | try { |
| | | if(file == null || file.isEmpty()){ |
| | | throw new ServiceException("文件为空"); |
| | | } |
| | | |
| | | /* |
| | | if(!StringUtils.endsWith(file.getOriginalFilename(),".zip")){ |
| | | throw new ServiceException("文件必须为zip包"); |
| | | } |
| | | }*/ |
| | | String tempDir = System.getProperty("java.io.tmpdir"); |
| | | Path tempPath = Paths.get(tempDir); |
| | | |
| | | // 创建解压目标目录(在临时目录下创建一个唯一子目录) |
| | | Path tempZipFile = Files.createTempFile("mdmimpfile-"+System.currentTimeMillis(), ".zip"); |
| | | |
| | | file.transferTo(tempZipFile); |
| | | |
| | | // 创建解压目标目录(在临时目录下创建一个唯一子目录) |
| | | Path extractDir = Files.createTempDirectory(tempPath, "unzip_"); |
| | | |
| | | Path extractDir = Files.createTempDirectory(tempPath, "unzip_"+System.currentTimeMillis()); |
| | | bladeRedis.setEx(getFileKey(),extractDir.toString(), Duration.ofHours(2)); |
| | | if(StringUtils.endsWithIgnoreCase(file.getOriginalFilename(),".zip")){ |
| | | // 创建解压目标目录(在临时目录下创建一个唯一子目录) |
| | | Path tempZipFile = Files.createTempFile("mdmimpfile-"+System.currentTimeMillis(), ".zip"); |
| | | file.transferTo(tempZipFile); |
| | | extractZipToTempDir(tempZipFile,extractDir); |
| | | |
| | | extractZipToTempDir(tempZipFile,extractDir); |
| | | |
| | | }else{ |
| | | //普通文件,直接放入extract文件夹 |
| | | String basename = FilenameUtils.getBaseName(file.getOriginalFilename()); |
| | | String ext = FilenameUtils.getExtension(file.getOriginalFilename()); |
| | | //Path filepath = Files.createTempFile(extractDir,basename,StringUtils.isEmpty(ext) ? "": "."+ext); |
| | | //Path filepath = Files.createFile(); |
| | | file.transferTo(Paths.get(extractDir.toString()+File.separator+file.getOriginalFilename())); |
| | | } |
| | | |
| | | //读取文件目录 |
| | | list = readTempDir(extractDir); |
| | |
| | | return list; |
| | | } |
| | | |
| | | /** |
| | | * 解压zip包到临时路径 |
| | | * @param zipFilePath zip包文件服务器上的路径 |
| | | * @param extractDir 目标目录 |
| | | * @throws IOException 文件操作异常 |
| | | */ |
| | | public void extractZipToTempDir(Path zipFilePath,Path extractDir) throws IOException { |
| | | // 获取系统临时目录 |
| | | String tempDir = System.getProperty("java.io.tmpdir"); |
| | | Path tempPath = Paths.get(tempDir); |
| | | |
| | | // 创建解压目标目录(在临时目录下创建一个唯一子目录) |
| | | try (InputStream fis = Files.newInputStream(zipFilePath); |
| | |
| | | |
| | | /** |
| | | * 防止ZIP Slip攻击 |
| | | * @param zipEntry |
| | | * @param targetDir |
| | | * @return |
| | | * @throws IOException |
| | | * @param zipEntry zip内部文件路径 |
| | | * @param targetDir 目标文件夹 |
| | | * @return 文件路径 |
| | | * @throws IOException 操作文件IO异常 |
| | | */ |
| | | Path zipSlipProtect(ZipEntry zipEntry, Path targetDir) throws IOException { |
| | | Path targetDirResolved = targetDir.resolve(zipEntry.getName()); |
| | |
| | | return normalizePath; |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 读取解压文件夹下所有文件 解析成vo列表 |
| | | * @param extractDir 解压文件夹 |
| | | * @return vo列表 |
| | | * @throws IOException 解析文件的异常 |
| | | */ |
| | | public List<MdmProgramImportVO> readTempDir(Path extractDir) throws IOException { |
| | | List<MdmProgramImportVO> list = new ArrayList<>(); |
| | | |
| | | //List<Machine> machines = machineService.getEnableMachines(); |
| | | try (Stream<Path> paths = Files.walk(extractDir)) { |
| | | List<Path> filePathList = paths |
| | | .filter(Files::isRegularFile).toList(); // 只保留普通文件,排除目录 |
| | | //.collect(Collectors.toList()); |
| | | //System.out.println("所有文件"+filePathList); |
| | | for(Path path : filePathList){ |
| | | list.add(readFileToVO(path)); |
| | | } |
| | | } |
| | | /* |
| | | //读取所有文件夹 |
| | | try (DirectoryStream<Path> stream = Files.newDirectoryStream(extractDir)) { |
| | | for (Path path : stream) { |
| | | if (Files.isDirectory(path)) { |
| | | |
| | | // 如果是子目录,读取其中的文件 |
| | | try (DirectoryStream<Path> subStream = Files.newDirectoryStream(path)) { |
| | | for (Path subPath : subStream) { |
| | |
| | | } else if (Files.isRegularFile(path)) { |
| | | System.out.println("找到文件2: " + path); |
| | | //这里 找到的文件不是 |
| | | MdmProgramImportVO vo = new MdmProgramImportVO(); |
| | | vo.setFilename(path.getFileName().toString()); |
| | | vo.setDrawingNo(parseDrawingNo(vo.getFilename())); |
| | | |
| | | try (InputStream inputStream = Files.newInputStream(path)) { |
| | | // 使用输入流读取文件内容 |
| | | byte[] buffer = new byte[2000]; |
| | | inputStream.read(buffer); |
| | | vo.setMd5(DigestUtils.md5Hex(buffer)); |
| | | } catch (IOException e) { |
| | | log.error("读取文件md5失败",e); |
| | | } |
| | | |
| | | |
| | | try (InputStream inputStream = Files.newInputStream(path, StandardOpenOption.READ)) { |
| | | // 使用输入流读取文件内容 |
| | | ByteArrayInputStream bas = new ByteArrayInputStream(inputStream.readAllBytes()); |
| | | |
| | | AnnotationProperties defAnnoProperties = AnnotationProperties.getDefault(); |
| | | String sendPathLine = FileContentUtil.readLineAt(bas,defAnnoProperties.getSendPathLineIndex()); |
| | | //bas.mark(0); |
| | | bas.reset(); |
| | | String statusLine = FileContentUtil.readLineAt(bas,defAnnoProperties.getStatusLineIndex()); |
| | | log.info("sendPathLine={}", sendPathLine); |
| | | |
| | | Machine matchedMachine = machineService.getMachineBySendPathAnnotation(sendPathLine); |
| | | /* |
| | | for (Machine machine : machines) { |
| | | if(Func.isNotBlank(machine.getProgSendDir()) && sendPathLine.contains(machine.getProgSendDir())){ |
| | | matchedMachine = machine; |
| | | break; |
| | | } |
| | | |
| | | } |
| | | |
| | | */ |
| | | if (matchedMachine != null) { |
| | | vo.setName(parseProgramName(vo.getFilename())); |
| | | vo.setMachineCode(matchedMachine.getCode()); |
| | | |
| | | vo.setFullPath(path.toString());//文件地址 |
| | | vo.setSendPath(matchedMachine.getProgSendDir()); |
| | | vo.setId(vo.getFullPath()); |
| | | vo.setProgramStatus(programAnnotationService.removeAnnotation(matchedMachine.getControlSystem(),statusLine)); |
| | | |
| | | list.add(vo); |
| | | } |
| | | |
| | | } catch (IOException e) { |
| | | log.error("读取文件md5失败",e); |
| | | } |
| | | list.add(readFileToVO(path)); |
| | | } |
| | | } |
| | | } |
| | | }*/ |
| | | return list; |
| | | } |
| | | |
| | | /** |
| | | * 将文件组织成VO |
| | | * @param path 文件path |
| | | * @return vo |
| | | */ |
| | | MdmProgramImportVO readFileToVO(Path path){ |
| | | MdmProgramImportVO vo = new MdmProgramImportVO(); |
| | | vo.setFilename(path.getFileName().toString()); |
| | | |
| | | ProgramNameVO pnmameVO = ProgramFileNameParser.parseProgramName(vo.getFilename()); |
| | | vo.setDrawingNo(pnmameVO.getDrawingNo()); |
| | | //vo.setDrawingNo(parseDrawingNo(vo.getFilename())); |
| | | |
| | | try (InputStream inputStream = Files.newInputStream(path)) { |
| | | // 使用输入流读取文件内容 |
| | | byte[] buffer = new byte[2000]; |
| | | inputStream.read(buffer); |
| | | vo.setMd5(DigestUtils.md5Hex(buffer)); |
| | | } catch (IOException e) { |
| | | log.error("读取文件md5失败",e); |
| | | } |
| | | |
| | | try (InputStream inputStream = Files.newInputStream(path, StandardOpenOption.READ)) { |
| | | // 使用输入流读取文件内容 |
| | | ByteArrayInputStream bas = new ByteArrayInputStream(inputStream.readAllBytes()); |
| | | |
| | | AnnotationProperties defAnnoProperties = AnnotationProperties.getDefault(); |
| | | String sendPathLine = FileContentUtil.readLineAt(bas,defAnnoProperties.getSendPathLineIndex()); |
| | | //bas.mark(0); |
| | | bas.reset(); |
| | | String statusLine = FileContentUtil.readLineAt(bas,defAnnoProperties.getStatusLineIndex()); |
| | | log.info("sendPathLine={}", sendPathLine); |
| | | |
| | | Machine matchedMachine = machineService.getMachineBySendPathAnnotation(sendPathLine); |
| | | |
| | | if (matchedMachine != null) { |
| | | //vo.setName(parseProgramName(vo.getFilename())); |
| | | vo.setName(pnmameVO.logicProgramName()); |
| | | vo.setMachineCode(matchedMachine.getCode()); |
| | | |
| | | vo.setFullPath(path.toString());//文件地址 |
| | | vo.setSendPath(matchedMachine.getProgSendDir()); |
| | | vo.setId(vo.getFullPath()); |
| | | vo.setProgramStatus(programAnnotationService.removeAnnotation(matchedMachine.getControlSystem(),statusLine)); |
| | | } |
| | | } catch (IOException e) { |
| | | log.error("读取文件失败",e); |
| | | throw new ServiceException("导入程序失败"+path.getFileName().toString()+","+e.getMessage()); |
| | | } |
| | | return vo; |
| | | } |
| | | /** |
| | | * 解析出零组件好 |
| | | * @param filename |
| | | * @return |
| | | */ |
| | | /* |
| | | String parseDrawingNo(String filename){ |
| | | |
| | | /* |
| | | String drawingNo = ""; |
| | | int idx = filename.lastIndexOf("-"); |
| | | String temp; |
| | |
| | | |
| | | } |
| | | return drawingNo; |
| | | |
| | | |
| | | } |
| | | |
| | | String parseProgramName(String filename){ |
| | |
| | | } |
| | | } |
| | | //以上去掉了最后2段段数和段号 |
| | | |
| | | |
| | | } |
| | | return programName; |
| | | } |
| | | |
| | | */ |
| | | /** |
| | | * 入库mdm涉密网文件 |
| | | * @param ids id列表逗号分隔 |
| | |
| | | |
| | | String dictStr = bladeRedis.get(getFileKey()); |
| | | if(dictStr == null){ |
| | | throw new ServiceException(""); |
| | | throw new ServiceException("文件缓存已过期,请重新上传文件。"); |
| | | } |
| | | Path extractDir = Paths.get(dictStr); |
| | | |
| | | List<MdmProgramImportVO> list = readTempDir(extractDir); |
| | | |
| | | String destFileFull; |
| | | for(String str : idList){ |
| | | for(MdmProgramImportVO vo : list){ |
| | | if(StringUtils.equals(vo.getFullPath(),str)){ |
| | | destFileFull = vo.getSendPath()+File.separator+vo.getFilename(); |
| | | File destFile = new File(destFileFull); |
| | | FileUtils.forceMkdirParent(destFile); |
| | | FileUtils.copyFile(new File(str),destFile); |
| | | Optional<MdmProgramImportVO> optVO = list.stream().filter(vo -> vo.getId().equals(str)).findFirst(); |
| | | |
| | | FileSendRecord record = new FileSendRecord(); |
| | | record.setName(destFile.getName()); |
| | | Path destPath = Paths.get(destFileFull); |
| | | record.setMachineCode(vo.getMachineCode()); |
| | | record.setFileSize(Files.size(destPath)); |
| | | |
| | | try(InputStream inputStream = new FileInputStream(destFile)){ |
| | | BladeFile bFile = ossTemplate.putFile(record.getName(), inputStream); |
| | | record.setOssName(bFile.getName()); |
| | | } |
| | | fileSendRecordService.save(record); |
| | | break; |
| | | } |
| | | if(optVO.isEmpty()){ |
| | | continue; |
| | | } |
| | | |
| | | MdmProgramImportVO vo = optVO.get(); |
| | | |
| | | destFileFull = vo.getSendPath()+File.separator+vo.getFilename(); |
| | | File destFile = new File(destFileFull); |
| | | FileUtils.forceMkdirParent(destFile); |
| | | FileUtils.copyFile(new File(str),destFile); |
| | | |
| | | FileSendRecord record = new FileSendRecord(); |
| | | record.setName(destFile.getName()); |
| | | Path destPath = Paths.get(destFileFull); |
| | | record.setMachineCode(vo.getMachineCode()); |
| | | record.setFileSize(Files.size(destPath)); |
| | | |
| | | try(InputStream inputStream = new FileInputStream(destFile)){ |
| | | BladeFile bFile = ossTemplate.putFile(record.getName(), inputStream); |
| | | record.setOssName(bFile.getName()); |
| | | } |
| | | fileSendRecordService.save(record); |
| | | } |
| | | |
| | | } |