yangys
2025-08-24 c9433fab340a766a99b2c01ca018609cac407cee
偏离单文件名+P1
已修改4个文件
247 ■■■■ 文件已修改
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/DispatchTaskController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/DNCSendBackService.java 135 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcNodeService.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcProgramExportDNCService.java 92 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/DispatchTaskController.java
@@ -87,7 +87,7 @@
            TaskAssignVO startVO = new TaskAssignVO();
            BeanUtils.copyProperties(dispatch, startVO);
            startVO.setTitle(startVO.getTitle()+"-"+startVO.getProcessNo()+"-"+startVO.getProcessEdition()+"数控程序编制");
            startVO.setTitle(startVO.getDrawingNo()+"-"+startVO.getProcessNo()+"-"+startVO.getProcessEdition()+"数控程序编制");
            try {
                String instId = dispatcher.start(startVO);
                dispatch.setStatus(TaskDispatch.STATUS_STARTED);
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/DNCSendBackService.java
@@ -4,6 +4,7 @@
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
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;
@@ -35,6 +36,7 @@
import java.nio.file.StandardOpenOption;
import java.time.Duration;
import java.util.*;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -55,6 +57,12 @@
    private final FlowCommonService flowCommonService;
    private final DncBackFileService dncBackFileService;
    private final ProgramFlowStatusQueryService programFlowStatusQueryService;
    /**
     * 偏离单文件末尾的模式:P+数字
     */
    private static final String P_NUMBER_PATTERN = "(?i)P\\d+";
    private String getFileKey(){
        return "dncimpfile-"+ AuthUtil.getUserId();
    }
@@ -243,7 +251,7 @@
            //根据内部文件,读取和分析程序包和程序文件数据
            List<String> dirList = entryNameList.stream().filter(s -> s.endsWith("/")).toList();
            for(String dir : dirList){
                String programPackageName1 = StringUtils.removeEnd(dir,"/");
                //String programPackageName1 = StringUtils.removeEnd(dir,"/");
                String folderName = StringUtils.removeEnd(dir,"/");
                PackageAndProcessEdition pkgAndEdition = parseProgramPackageFromFolderName(folderName);
@@ -254,17 +262,14 @@
                if(optPackageNode.isEmpty()){
                    throw new ServiceException("找不到程序"+programPackageName);
                }
                NcNode packageNode = optPackageNode.get();
                if(packageNode.hasCured()) {
                    throw new ServiceException(programPackageName + "已经固化,请勿重复入库。");
                }
                //偏离程序判断是否重复回传
                if(packageNode.isDeviationProgram() && packageNode.hasLocked()) {
                    throw new ServiceException(programPackageName + "已锁定的程序不可以再次回传。");
                }
                //检查是否在审批过程中
                boolean active = flowCommonService.isProcessInstanceActive(packageNode.getProcessInstanceId());
                if(active){
@@ -285,7 +290,7 @@
                    if(!entryName.endsWith("/")){
                        //实际的文件
                        String fileName = StringUtils.removeStart(entryName,dir);//去除文件名路径部分
                        fileName = removeDeviationPart(fileName);
                        try {
                            FlowProgramFile newFlowFile = new FlowProgramFile();
                            newFlowFile.setProgramName(packageNode.getName());
@@ -306,121 +311,29 @@
                pkgIdFileMap.put(packageNode.getId(),flowFiles);
            }
        }
        return pkgIdFileMap;
    }
    /**
     * 更新节点,主要是创建 程序包名 的新版本。
     * @param pkgFileName zip文件名
     * @param programPackageIdList 程序包名 节点的id列表
     * @param programPackageSubMap 新的 程序包节点id -> =文件列表 map,用于回传数据
     * @throws IOException 访问文件异常
     */
    /*
    List<NcNode> updateNodeDataByDNCBackData(String pkgFileName, List<Long> programPackageIdList,Map<Long,List<NcNode>> programPackageSubMap) throws IOException {
        InputStream inputStream = this.ossTemplate.statFileStream(pkgFileName);
        Path tempZipFile = createTempFile(inputStream);
        List<NcNode> newProgramPackageNodeList = new ArrayList<>();
        List<String> entryNameList = new ArrayList<>();
        ZipEntry entry;
        try (java.util.zip.ZipFile zipFile = new java.util.zip.ZipFile(tempZipFile.toFile())) {
            Enumeration<? extends ZipEntry> entries = zipFile.entries();
            while(entries.hasMoreElements()) {
                entry = entries.nextElement();
                entryNameList.add(entry.getName());
    String removeDeviationPart(String filename){
        String finalFilename  = filename;
        //去掉文件名中可能带有的偏离单部分:-P[序号]
        String ext = FilenameUtils.getExtension(filename);
        String dotExt = StringUtils.isNotBlank(ext)?"."+ext:ext;//带点的扩展名
        String notExtName = StringUtils.removeEnd(filename,dotExt);
        int idx = notExtName.lastIndexOf("-");
        if(idx != -1){
            String endPart = notExtName.substring(idx+1);
            //Pattern.CASE_INSENSITIVE
            boolean containsPld = endPart.matches(P_NUMBER_PATTERN);
            if(containsPld){
                finalFilename = notExtName.substring(0, idx)+dotExt;
            }
            log.info("allentrynames:{}",entryNameList);
            List<NcNode> allAcceptPackages =  this.ncNodeService.lambdaQuery().in(NcNode::getId,programPackageIdList).list();
            //根据内部文件,读取和分析程序包和程序文件数据
            List<String> dirList = entryNameList.stream().filter(s -> s.endsWith("/")).toList();
            for(String dir : dirList){
                String programPackageName = StringUtils.removeEnd(dir,"/");
                Optional<NcNode> optPackageNode = allAcceptPackages.stream().filter(node -> StringUtils.equals(node.getName(),programPackageName)).findFirst();
                if(optPackageNode.isEmpty()){
                    throw new ServiceException("找不到程序"+programPackageName);
                }
                NcNode packageNode = optPackageNode.get();
                if(packageNode.hasCured()) {
                    throw new ServiceException(programPackageName + "已经固化,请勿重复入库。");
                }
                //检查是否在审批过程中
                //根据节点信息查询流程
                boolean active = flowCommonService.isProcessInstanceActive(packageNode.getProcessInstanceId());
                if(active){
                    throw new ServiceException(programPackageName+"正在审批中,请勿重复入库。");
                }
                NcNode newProgramPkg = new NcNode();
                BeanUtils.copyProperties(packageNode, newProgramPkg);
                EntityUtil.clearBaseProperties(newProgramPkg);
                newProgramPkg.setIsLastEdition(1);
                ncNodeService.save(newProgramPkg);
                newProgramPackageNodeList.add(newProgramPkg);
                //旧数据更新为老版本
                packageNode.setIsLocked(1);//旧版自动锁定
                packageNode.setIsLastEdition(0);;
                ncNodeService.updateById(packageNode);
                //List<FlowProgramFile> newFlowFiles = new ArrayList<>();
                List<NcNode> newProgramNodes = new ArrayList<>();
                //查找包下的文件数据,
                entryNameList.stream().filter(s -> s.startsWith(dir)).forEach(entryName -> {
                    log.info("{}下的文件:{}",dir,entryName);
                    if(!entryName.endsWith("/")){
                        //实际的文件
                        String fileName = StringUtils.removeStart(entryName,dir);//去除文件名路径部分
                        NcNode oldProgramNode = this.ncNodeService.getLastEditionProgramFile(fileName,packageNode.getId());
                        if(oldProgramNode == null){
                            log.info("{}找不到程序文件",entryName);
                            throw new ServiceException(programPackageName+"下找不到程序文件"+fileName);
                        }
                        //创建新版本的程序节点
                        NcNode newProgramNode = new NcNode();
                        BeanUtils.copyProperties(oldProgramNode, newProgramNode);
                        EntityUtil.clearBaseProperties(newProgramNode);
                        newProgramNode.setIsLastEdition(1);
                        newProgramNode.setParentId(newProgramPkg.getId());
                        newProgramNode.setParentIds(newProgramPkg.getParentIds()+","+newProgramPkg.getId());
                        FlowProgramFile oldFlowFile = flowProgramFileService.getById(newProgramNode.getFlowProgramFileId());
                        FlowProgramFile newFlowFile = new FlowProgramFile();
                        BeanUtils.copyProperties(oldFlowFile, newFlowFile);
                        newFlowFile.setProcessInstanceId(null);//先置为空,启动流程后设置该值
                        EntityUtil.clearBaseProperties(newFlowFile);
                        try {
                            InputStream ins = zipFile.getInputStream(zipFile.getEntry(entryName));
                            BladeFile newOssFile = ossTemplate.putFile("mdm",fileName,ins);
                            newFlowFile.setOssName(newOssFile.getName());
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                        newProgramNode.setFlowProgramFile(newFlowFile);
                        newProgramNode.setVersionNumber(oldProgramNode.genNewVersionNumber());
                        newProgramNodes.add(newProgramNode);
                        //旧节点处理,咋办?如果导出工控网 重复导出呢?,isLastEdition不用设置了,因为 程序包节点 是新的
                    }
                });
                programPackageSubMap.put(newProgramPkg.getId(),newProgramNodes);
            }
        }
        return newProgramPackageNodeList;
        return finalFilename;
    }
    */
    /**
     * 创建一个临时zip文件
     * @param inputStream 文件的输入流
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcNodeService.java
@@ -366,4 +366,22 @@
        node.unlock();
        this.updateById(node);
    }
    /**
     * 查询偏离单的序号
     * @param programPkgNode 偏离单的程序包名节点
     * @return 序号
     */
    public long getDeviationSerialForNode(NcNode programPkgNode) {
        return lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE)
            .eq(NcNode::getName,programPkgNode.getName())
            .eq(NcNode::getDrawingNo,programPkgNode.getDrawingNo())
            .eq(NcNode::getProcessNo,programPkgNode.getProcessNo())
            .eq(NcNode::getProcessEdition,programPkgNode.getProcessEdition())
            .isNotNull(NcNode::getDeviation)
            .le(NcNode::getCreateTime,programPkgNode.getCreateTime())  //时间小于等于当前节点
            .count();
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcProgramExportDNCService.java
@@ -5,6 +5,7 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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;
@@ -50,7 +51,6 @@
    private final FlowProgramFileService flowProgramFileService;
    private final ProgramAnnotationService programAnnotationService;
    public static final String ANNOTATION_DICT = "machine_annotation";
    /**
     * 分页查询
@@ -108,10 +108,14 @@
        }else if(programPackageNode.hasCured()){
            status = "GH";
        }
        long deviationSerial = -1;//偏离单序号 ,-1为非偏离单,不需要加入
        if(packageNode.isDeviationProgram()) {
            deviationSerial = ncNodeService.getDeviationSerialForNode(packageNode);
        }
        List<DictBiz> annotationDictList= programAnnotationService.getAnnotionList();
        for (NcNode node : programNodes) {
            String filePathInZip = packageFolder + node.getName();
            String filePathInZip = genFilePathInZip(packageFolder,node,deviationSerial);
            programFile = this.flowProgramFileService.getById(node.getFlowProgramFileId());
            if(programFile.isProgram()) {//程序文件,才会加入压缩包
                InputStream inputStream = ossTemplate.statFileStream(programFile.getOssName());
@@ -130,75 +134,33 @@
    }
    /**
     * 加入机床下发路径和程序状态的注释
     * @param inputStream
     * @return
     * 生成在zip中的文件路径
     * @param packageFolder zip中的文件夹
     * @param programNode 程序节点
     * @param deviationSerial 偏离单序号
     * @return zip中的文件路径
     */
    /*
    InputStream addSendDirAnnotation(InputStream inputStream,Machine machine,List<Dict> annotationList) throws IOException {
        //检测第二行是否是路径
        String annotationText = programAnnotationService.generateAnnotation(machine.getProgSendDir()==null? StringUtil.EMPTY:machine.getProgSendDir(),machine.getMachineGroupCode(),annotationList);
    String genFilePathInZip(String packageFolder,NcNode programNode,long deviationSerial){
        //为文件名增加偏离单号
        String filePathInZip;
        //TODO 改判断行内容
        return FileContentUtil.insertLine(inputStream,1,annotationText);
    }*/
        if(deviationSerial != -1){
            //加入偏离单序号
            String ext = FilenameUtils.getExtension(programNode.getName());
            String dotExt = StringUtils.isNotBlank(ext)?"."+ext:ext;//带点的扩展名
    /**
     * 添加程序专改的注释
     * @param inputStream
     * @param status 程序状态
     * @param machine
     * @param annotationList 配置的注释字典列表
     * @return
     * @throws IOException
     */
    /*
    InputStream addProgramStatusAnnotation(InputStream inputStream,String status,Machine machine,List<Dict> annotationList) throws IOException {
        String annoText= programAnnotationService.generateAnnotation(status,machine.getMachineGroupCode(),annotationList);
        return FileContentUtil.insertLine(inputStream,2,annoText);
    }*/
    /**
     * 判断一行文本是否是注释
     * @param line
     * @param annotationList
     * @return
     */
    /*
    boolean isAnnotation(String line,List<Dict> annotationList){
        boolean isAnno = false;
        return isAnno;
    }*/
    /*
    String generateAnnotation(String oriTest,String machineGroupCode,List<Dict> annotationList) {
        R<List<Dict>> dictsResult = dictClient.getList(ANNOTATION_DICT);
        String annotation = oriTest;
        String begin = "(";
        String end = ")";
        Optional<Dict> dictOpt = dictsResult.getData().stream().filter(dict -> {return dict.getDictKey().equals(machineGroupCode);}).findFirst();
        String annotationSetting = "(,)";
        if(dictOpt.isPresent()) {
            annotationSetting = dictOpt.get().getDictValue();
            String temp = programNode.getName();
            if(StringUtils.isNotBlank(ext)) {
                temp = StringUtils.removeEnd(temp,dotExt);
            }
            filePathInZip = packageFolder + temp+"-P"+deviationSerial+dotExt;
        }else{
            //非偏离单,直接使用原文件名
            filePathInZip = packageFolder + programNode.getName();
        }
        String[] arr = annotationSetting.split(",");
        if(arr.length == 2){
            begin = arr[0];
            end = arr[1];
        }
        annotation = begin + oriTest + end;
        return annotation;
        return filePathInZip;
    }
    */
    /**
     * 将 输入流 中的内容写入zip
     * @param zipOut zip输出流