yangys
2025-09-29 4c7296d45efe849dc70a3b2e2240c905481a91c9
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/MdmProgramImportService.java
@@ -4,7 +4,6 @@
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;
@@ -15,28 +14,32 @@
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.commons.contants.ZipConstants;
import org.springblade.mdm.gkw.programnode.vo.ProgramNameVO;
import org.springblade.mdm.gkw.task.entity.MachineBackTask;
import org.springblade.mdm.gkw.task.service.MachineBackTaskService;
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.mapper.NcProgramExchangeMapper;
import org.springblade.mdm.program.service.programannotation.AnnotationProperties;
import org.springblade.mdm.program.service.programannotation.*;
import org.springblade.mdm.program.vo.MdmProgramImportVO;
import org.springblade.mdm.utils.FileContentUtil;
import org.springblade.mdm.utils.ProgramFileNameParser;
import org.springblade.system.pojo.entity.DictBiz;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
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;
@@ -58,6 +61,11 @@
   private FileSendRecordService fileSendRecordService;
   @Autowired
   private OssTemplate ossTemplate;
   @Autowired
   private AnnotationProcessorHelper annotationProcessorHelper;
   @Autowired
   private MachineBackTaskService machineBackTaskService;
   private String getFileKey(){
      return "mdmgkwimpfile-"+ AuthUtil.getUserId();
   }
@@ -85,14 +93,8 @@
            Path tempZipFile = Files.createTempFile("mdmimpfile-"+System.currentTimeMillis(), ".zip");
            file.transferTo(tempZipFile);
            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()));
         }
@@ -111,13 +113,24 @@
    * @param extractDir 目标目录
    * @throws IOException 文件操作异常
    */
   public void extractZipToTempDir(Path zipFilePath,Path extractDir) throws IOException {
   public void extractZipToTempDir(Path zipFilePath,Path extractDir) throws IOException{
      for (String encoding : ZipConstants.TRY_ENCODINGS) {
         try {
            extractZipToTempDirWithCharset(zipFilePath,extractDir,Charset.forName(encoding));
            log.error("使用编码 {} 解析成功 ",encoding);
            break;
         } catch (Exception e) {
            log.error("使用编码 {} 解析失败: ",encoding,e);
         }
      }
   }
   public void extractZipToTempDirWithCharset(Path zipFilePath, Path extractDir, Charset charset) throws IOException {
      // 获取系统临时目录
      String tempDir = System.getProperty("java.io.tmpdir");
      // 创建解压目标目录(在临时目录下创建一个唯一子目录)
      try (InputStream fis = Files.newInputStream(zipFilePath);
          ZipInputStream zis = new ZipInputStream(fis)) {
          ZipInputStream zis = new ZipInputStream(fis,charset)) {
         ZipEntry zipEntry = zis.getNextEntry();
         while (zipEntry != null) {
@@ -177,8 +190,7 @@
      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));
         }
@@ -205,19 +217,47 @@
      }*/
      return list;
   }
   public static byte[] getUTF8BytesFromGBKString(String gbkStr) {
      int n = gbkStr.length();
      byte[] utfBytes = new byte[3 * n];
      int k = 0;
      for (int i = 0; i < n; i++) {
         int m = gbkStr.charAt(i);
         if (m < 128 && m >= 0) {
            utfBytes[k++] = (byte) m;
            continue;
         }
         utfBytes[k++] = (byte) (0xe0 | (m >> 12));
         utfBytes[k++] = (byte) (0x80 | ((m >> 6) & 0x3f));
         utfBytes[k++] = (byte) (0x80 | (m & 0x3f));
      }
      if (k < utfBytes.length) {
         byte[] tmp = new byte[k];
         System.arraycopy(utfBytes, 0, tmp, 0, k);
         return tmp;
      }
      return utfBytes;
   }
   ProgramNameVO tryParseProgramName(String fiilename){
      ProgramNameVO pnmameVO = ProgramFileNameParser.parseProgramName(fiilename);//标准utf8编码
      if(pnmameVO.getDrawingNo() == null) {
         //使用GBK编码解析
         pnmameVO = ProgramFileNameParser.parseProgramName(new String(getUTF8BytesFromGBKString(fiilename), StandardCharsets.UTF_8));
      }
      return pnmameVO;
   }
   /**
    * 将文件组织成VO
    * @param path 文件path
    * @return vo
    */
   MdmProgramImportVO readFileToVO(Path path){
   MdmProgramImportVO readFileToVO(Path path) throws UnsupportedEncodingException {
      MdmProgramImportVO vo = new MdmProgramImportVO();
      vo.setFilename(path.getFileName().toString());
      ProgramNameVO pnmameVO = ProgramFileNameParser.parseProgramName(vo.getFilename());
      vo.setDrawingNo(pnmameVO.getDrawingNo());
      //vo.setDrawingNo(parseDrawingNo(vo.getFilename()));
      ProgramNameVO progNmameVO = tryParseProgramName(vo.getFilename());
      vo.setDrawingNo(progNmameVO.getDrawingNo());
      try (InputStream inputStream = Files.newInputStream(path)) {
         // 使用输入流读取文件内容
@@ -234,7 +274,7 @@
         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);
@@ -242,8 +282,7 @@
         Machine matchedMachine = machineService.getMachineBySendPathAnnotation(sendPathLine);
         if (matchedMachine != null) {
            //vo.setName(parseProgramName(vo.getFilename()));
            vo.setName(pnmameVO.logicProgramName());
            vo.setName(progNmameVO.logicProgramName());
            vo.setMachineCode(matchedMachine.getCode());
            vo.setFullPath(path.toString());//文件地址
@@ -257,74 +296,14 @@
      }
      return vo;
   }
   /**
    * 解析出零组件好
    * @param filename
    * @return
    */
   /*
   String parseDrawingNo(String filename){
      /*
      String drawingNo = "";
      int idx = filename.lastIndexOf("-");
      String temp;
      if(idx != -1){
         temp = filename.substring(0,idx);
         idx = temp.lastIndexOf("-");
         if(idx != -1){
            temp = temp.substring(0,idx);
            //去掉工序版次
            idx = temp.lastIndexOf("-");
            if(idx != -1){
               temp = temp.substring(0,idx);
               //去掉工序号
               idx = temp.lastIndexOf("-");
               if(idx != -1){
                  drawingNo = temp.substring(0,idx);
               }
            }
         }
         //以上去掉了最后2段段数和段号
      }
      return drawingNo;
   }
   String parseProgramName(String filename){
      String programName = "";
      int idx = filename.lastIndexOf("-");
      String temp;
      if(idx != -1){
         temp = filename.substring(0,idx);
         idx = temp.lastIndexOf("-");
         if(idx != -1){
            temp = temp.substring(0,idx);
            //去掉工序版次
            idx = temp.lastIndexOf("-");
            if(idx != -1){
               programName = temp.substring(0,idx);
            }
         }
         //以上去掉了最后2段段数和段号
      }
      return programName;
   }
*/
   /**
    * 入库mdm涉密网文件
    * @param ids id列表逗号分隔
    */
   public void mdmFileAccept(String ids) throws IOException {
      List<FileSendRecord>  importedRecords = new ArrayList<>();
      List<String> idList = Func.toStrList(ids);
      String dictStr = bladeRedis.get(getFileKey());
@@ -334,6 +313,7 @@
      Path extractDir = Paths.get(dictStr);
      List<MdmProgramImportVO> list = readTempDir(extractDir);
      //List<DictBiz> annoDictList = programAnnotationService.getAnnotionDictList();
      String destFileFull;
      for(String str : idList){
         Optional<MdmProgramImportVO> optVO = list.stream().filter(vo -> vo.getId().equals(str)).findFirst();
@@ -346,6 +326,7 @@
         destFileFull = vo.getSendPath()+File.separator+vo.getFilename();
         File destFile = new File(destFileFull);
         FileUtils.forceMkdirParent(destFile);
         FileUtils.copyFile(new File(str),destFile);
@@ -359,8 +340,60 @@
            BladeFile bFile = ossTemplate.putFile(record.getName(), inputStream);
            record.setOssName(bFile.getName());
         }
         try(InputStream inputStream = ossTemplate.statFileStream(record.getOssName())){
            //读取程序状态
            Machine machine = this.machineService.getByCode(record.getMachineCode());
            AnnotationProcessor processor = annotationProcessorHelper.getProcessor(machine.getControlSystem());
            AnnotationData annotationData = processor.readAnnotationData(inputStream);
            record.setDeviation(annotationData.getDeviation());
            ProgramNameVO nameVO = ProgramFileNameParser.parseProgramName(record.getName());
            record.setDeviationSerial(nameVO.lgSerial());
            record.setProgramStatus(annotationData.getProgramStatus());
         }
         fileSendRecordService.save(record);
         importedRecords.add(record);
      }
      machineBackTaskService.saveBatch(parseMachineBackTask(importedRecords));
   }
   /**
    * 创建机床回传任务
    * @param importedRecords 导入记录列表
    */
   List<MachineBackTask> parseMachineBackTask(List<FileSendRecord>  importedRecords){
      List<FileSendRecord> recList = importedRecords.stream().filter(r -> AnnotationUtil.SQ.equals(r.getProgramStatus())
         || AnnotationUtil.LG.equals(r.getProgramStatus())).toList();
      Map<String,FileSendRecord> map = new HashMap<>();
      for(FileSendRecord record : recList){
         ProgramNameVO nameVO = ProgramFileNameParser.parseProgramName(record.getName());
         String key = record.getMachineCode()+","+nameVO.logicProgramName();
         map.put(key,record);
      }
      List<MachineBackTask> backTasks = new ArrayList<>();
      for(String key : map.keySet()){
         MachineBackTask task = new MachineBackTask();
         task.setTaskType(MachineBackTask.TASK_TYPE_PROGRAM);
         FileSendRecord record = map.get(key);
         task.setMachineCode(record.getMachineCode());
         ProgramNameVO nameVO = ProgramFileNameParser.parseProgramName(record.getName());
         task.setDeviation(record.getDeviation());
         task.setDeviationSerial(record.getDeviationSerial());
         task.setProgramName(nameVO.logicProgramName());
         task.setSegCount(nameVO.getSegmentCount());
         backTasks.add(task);
      }
      //提取程序包名,机床编码集合
      return backTasks;
   }
}