yangys
2025-09-29 4c7296d45efe849dc70a3b2e2240c905481a91c9
工控网涉密网联调
已添加4个文件
已修改41个文件
885 ■■■■■ 文件已修改
blade-service/blade-mdm/src/main/java/org/springblade/mdm/basesetting/machine/service/MachineService.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/commons/contants/RegExpConstants.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/commons/service/DirTransProperties.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/commons/service/MachineDirTranslator.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/config/InitBean.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/config/ShutdownHook.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/MyFlowController.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/append/AppendFinishListener.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/cure/DeviationCureFinishDataHandler.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/cure/NormalCureFinishDataHandler.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/CureFlowService.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/gkw/programnode/vo/ProgramNameVO.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/gkw/task/entity/MachineBackTask.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/gkw/task/mapper/MachineBackTaskMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/gkw/task/vo/MachineBackTaskVO.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/controller/MachineFileController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/entity/FileSendRecord.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/filewatch/FileLockChecker.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/filewatch/FileWatcherService.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/filewatch/MachineFileChangeListener.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/listeners/ExportToInnerListener.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/mapper/MachineAcceptedFileMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/mapper/MachineFileMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/mapper/MachineFileMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/service/MachineAcceptedFileService.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/service/MachineFileScanService.java 68 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/service/MachineFileService.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/service/NcProgramExportInnerService.java 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/service/ReceiveFileCheckService.java 67 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/controller/MdmProgramImportController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/controller/ProgramOnMachineImportController.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/entity/DncBackFile.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/DNCSendBackService.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/DncBackFileService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/MdmProgramImportService.java 93 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcNodeService.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcProgramExportDNCService.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/programannotation/AbstractProcessor.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/programannotation/AnnotationProcessor.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/programannotation/AnnotationUtil.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/programannotation/DefaultProcessor.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/test/MyTestController.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/test/java/org/springblade/mdm/gkw/programnode/vo/ProgramNameVOTest.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/test/java/org/springblade/mdm/program/service/programannotation/DefaultProcessorTest.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/test/java/org/springblade/mdm/utils/ProgramFileNameParserTest.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/basesetting/machine/service/MachineService.java
@@ -16,6 +16,7 @@
import org.springblade.mdm.basesetting.machine.vo.MachineSaveVO;
import org.springblade.mdm.basesetting.machine.vo.MachineVO;
import org.springblade.mdm.basesetting.producedivision.service.MdmDeptService;
import org.springblade.mdm.commons.service.MachineDirTranslator;
import org.springblade.mdm.commons.service.ParamService;
import org.springblade.mdm.machinefile.entity.MachineFile;
import org.springblade.mdm.machinefile.filewatch.DynamicDirectoryWatcher;
@@ -35,6 +36,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Optional;
@Service
public class MachineService extends BizServiceImpl<MachineMapper, Machine> {
@@ -44,6 +46,9 @@
    private DynamicDirectoryWatcher dynamicDirectoryWatcher;
    @Autowired
    private ParamService paramService;
    @Autowired
    private MachineDirTranslator machineDirTranslator;
    @Transactional(rollbackFor = Exception.class)
    public void saveMachine(MachineSaveVO vo) throws IOException {
        checkMachine(vo);
@@ -66,15 +71,15 @@
    void makeMachineDirs(Machine machine) throws IOException {
        Path dir;
        if(StringUtils.isNotBlank(machine.getProgSendDir())){
            createDirIsNotExists(machine.getProgSendDir());
            createDirIsNotExists(machineDirTranslator.trans(machine.getProgSendDir()));
        }
        if(StringUtils.isNotBlank(machine.getProgReceiveDir())){
            createDirIsNotExists(machine.getProgReceiveDir());
        if(StringUtils.isNotBlank(machineDirTranslator.trans(machine.getProgReceiveDir()))){
            createDirIsNotExists(machineDirTranslator.trans(machine.getProgReceiveDir()));
        }
        if(StringUtils.isNotBlank(machine.getProgTempDir())){
            createDirIsNotExists(machine.getProgTempDir());
        if(StringUtils.isNotBlank(machineDirTranslator.trans(machine.getProgTempDir()))){
            createDirIsNotExists(machineDirTranslator.trans(machine.getProgTempDir()));
        }
    }
@@ -95,13 +100,17 @@
            ProgramAnnotationService annoService = SpringUtil.getBean(ProgramAnnotationService.class);
            if(StringUtils.isNotBlank(machine.getProgSendDir())) {
                String sendDir = machineDirTranslator.trans(machine.getProgSendDir());
                WatchInfo watchInfoSend = new WatchInfo();
                watchInfoSend.setMachine(machine);
                watchInfoSend.setDirType(MachineFile.DIR_TYPE_SEND);
                watchInfoSend.setPath(machine.getProgSendDir());
                watchInfoSend.setPath(sendDir);
                if(!dynamicDirectoryWatcher.containsPath(Paths.get(machine.getProgSendDir()))) {
                    dynamicDirectoryWatcher.addDirectory(Paths.get(machine.getProgSendDir()),
                Path path = Paths.get(sendDir);
                if(!dynamicDirectoryWatcher.containsPath(path)) {
                    dynamicDirectoryWatcher.addDirectory(path,
                        new MachineFileChangeListener(machineFileService,
                            annoService,
                            watchInfoSend));
@@ -109,12 +118,16 @@
            }
            if(StringUtils.isNotBlank(machine.getProgReceiveDir())) {
                String recDir = machineDirTranslator.trans(machine.getProgReceiveDir());
                WatchInfo watchInfoRec = new WatchInfo();
                watchInfoRec.setMachine(machine);
                watchInfoRec.setDirType(MachineFile.DIR_TYPE_REC);
                watchInfoRec.setPath(machine.getProgReceiveDir());
                if(!dynamicDirectoryWatcher.containsPath(Paths.get(machine.getProgReceiveDir()))) {
                    dynamicDirectoryWatcher.addDirectory(Paths.get(machine.getProgReceiveDir()),
                watchInfoRec.setPath(recDir);
                Path path = Paths.get(recDir);
                if(!dynamicDirectoryWatcher.containsPath(path)) {
                    dynamicDirectoryWatcher.addDirectory(path,
                        new MachineFileChangeListener(machineFileService,
                            annoService,
                            watchInfoRec));
@@ -122,12 +135,14 @@
            }
            if(StringUtils.isNotBlank(machine.getProgTempDir())) {
                String tempDir = machineDirTranslator.trans(machine.getProgTempDir());
                WatchInfo watchInfoTemp = new WatchInfo();
                watchInfoTemp.setMachine(machine);
                watchInfoTemp.setDirType(MachineFile.DIR_TYPE_TEMP);
                watchInfoTemp.setPath(machine.getProgTempDir());
                if(!dynamicDirectoryWatcher.containsPath(Paths.get(machine.getProgTempDir()))) {
                    dynamicDirectoryWatcher.addDirectory(Paths.get(machine.getProgTempDir()),
                watchInfoTemp.setPath(tempDir);
                Path path = Paths.get(machine.getProgTempDir());
                if(!dynamicDirectoryWatcher.containsPath(path)) {
                    dynamicDirectoryWatcher.addDirectory(path,
                        new MachineFileChangeListener(machineFileService,
                            annoService,
                            watchInfoTemp));
@@ -356,16 +371,20 @@
            return null;
        }
        //去掉末尾括号(发那科) ,末尾路径分隔符
        String tempPath = StringUtils.removeEnd(StringUtils.removeEnd(StringUtils.removeEnd(sendPathLine,")"),"/"),"\\");
        //去掉前2位可能的注释(*-)。
        String sendPath = escapeSqlWildcard(StringUtils.trim(StringUtils.substring(tempPath,2)));
        String oriPath = StringUtils.removeEnd(StringUtils.removeEnd(StringUtils.removeEnd(sendPathLine,")"),"/"),"\\");
        List<Machine> machines = lambdaQuery().eq(Machine::getStatus,Machine.STATUS_ENABLE).like(Machine::getProgSendDir,sendPath).list();
        if(machines.isEmpty()){
            return null;
        }else{
            return machines.get(0);
        }
        String tempPathRepl1 = StringUtils.replace(oriPath,"/","\\");//反斜杠版本的路径
        String tempPathRepl2 = StringUtils.replace(oriPath,"\\","/");//正斜杠版本的路径
        //去掉前2位可能的注释(*-)。
        String sendPath1 = escapeSqlWildcard(StringUtils.trim(StringUtils.substring(tempPathRepl1,2)));
        String sendPath2 = escapeSqlWildcard(StringUtils.trim(StringUtils.substring(tempPathRepl2,2)));
        Optional<Machine> machineOpt = lambdaQuery().eq(Machine::getStatus,Machine.STATUS_ENABLE).and(w -> {
            w.like(Machine::getProgSendDir,sendPath1).or().like(Machine::getProgSendDir,sendPath2);
        }).last("limit 1").oneOpt();
        return machineOpt.orElse(null);
    }
    /**
blade-service/blade-mdm/src/main/java/org/springblade/mdm/commons/contants/RegExpConstants.java
@@ -9,6 +9,6 @@
     */
    public static final Pattern PROGRAM_FILE_PATTERN = Pattern.compile("^([\\u4e00-\\u9fa5\\w\\-]+)-([0-9a-zA-Z]+)-([\\u4e00-\\u9fa5a-zA-Z0-9]+)-(\\d+)-(\\d+)-?([Pp]\\d+)?(\\.[a-zA-Z]+)?$");
    //public static final Pattern PROGRAM_PACKAGE_PATTERN = Pattern.compile("[\\w\\-]+\\-\\w+\\-\\w+");
    public static final Pattern PROGRAM_PACKAGE_PATTERN = Pattern.compile("([\\u4e00-\\u9fa5\\w\\-]+)-[0-9a-zA-Z]+-[\\u4e00-\\u9fa5a-zA-Z0-9]+");
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/commons/service/DirTransProperties.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,14 @@
package org.springblade.mdm.commons.service;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "dirtrans")
@Data
public class DirTransProperties {
    private String oriDirPrefix;
    private String targetDirPrefix;
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/commons/service/MachineDirTranslator.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package org.springblade.mdm.commons.service;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
 * æœºåºŠè·¯å¾„转换器,从Z盘这种目录转换为网络目录格式入:\\192.168.233.2\Workshop
 */
@Component
public class MachineDirTranslator {
    @Autowired
    private DirTransProperties transProperties;
    public String trans(String path){
        if(StringUtils.isBlank(transProperties.getTargetDirPrefix()) || !StringUtils.startsWithIgnoreCase(path,transProperties.getOriDirPrefix())){
            return path;
        }
        String finalDir = transProperties.getTargetDirPrefix()+StringUtils.removeStartIgnoreCase(path,transProperties.getOriDirPrefix());
        return finalDir;
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/config/InitBean.java
@@ -6,6 +6,7 @@
import org.apache.commons.lang3.StringUtils;
import org.springblade.mdm.basesetting.machine.service.MachineService;
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.commons.service.MachineDirTranslator;
import org.springblade.mdm.commons.service.ParamService;
import org.springblade.mdm.flow.service.TaskDispatchService;
import org.springblade.mdm.machinefile.entity.MachineFile;
@@ -34,10 +35,7 @@
    private final ProgramAnnotationService annotationService;
    private final MachineFileScanService machineFileScanService;
    private final TaskDispatchService taskDispatchService;
    //@Value("${task.file_scan_on_start:true}")
    //@Value("${task.fileScanOnStart:true}")
    //public boolean fileScanOnStart;
    private final MachineDirTranslator dirTranslator;
    private final TaskPropertieBean taskPropertieBean;
    @PostConstruct
    public void init() {
@@ -52,7 +50,6 @@
            log.info("工控网启动文件监控");
            initMachineDirMonitor();
        }else{
            //涉密网
            taskDispatchService.resetDrawingNos();
        }
@@ -76,6 +73,7 @@
        machineList.forEach(m -> {
            addToWatchDirList(monitorInfoList,m);
        });
        for (WatchInfo info : monitorInfoList) {
            try {
                Path dirPath = Paths.get(info.getPath());
@@ -94,7 +92,8 @@
        String dir;
        //加入send文件夹
        if (StringUtils.isNotEmpty(machine.getProgSendDir())) {
            dir = StringUtils.removeEnd(StringUtils.removeEnd(machine.getProgSendDir(), "/"), "\\");
            //dir = dirTranslator.trans(StringUtils.removeEnd(StringUtils.removeEnd(machine.getProgSendDir(), "/"), "\\"));
            dir = fixMachineDir(machine.getProgSendDir());
            WatchInfo watchInfo = new WatchInfo();
            watchInfo.setMachine(machine);
            watchInfo.setDirType(MachineFile.DIR_TYPE_SEND);
@@ -106,7 +105,8 @@
        //加入rec文件夹
        if (StringUtils.isNotEmpty(machine.getProgReceiveDir())) {
            dir = StringUtils.removeEnd(StringUtils.removeEnd(machine.getProgReceiveDir(), "/"), "\\");
            //dir = StringUtils.removeEnd(StringUtils.removeEnd(machine.getProgReceiveDir(), "/"), "\\");
            dir = fixMachineDir(machine.getProgReceiveDir());
            WatchInfo watchInfo = new WatchInfo();
            watchInfo.setMachine(machine);
            watchInfo.setDirType(MachineFile.DIR_TYPE_REC);
@@ -118,7 +118,8 @@
        //加入temp文件夹
        if (StringUtils.isNotEmpty(machine.getProgTempDir())) {
            dir = StringUtils.removeEnd(StringUtils.removeEnd(machine.getProgTempDir(), "/"), "\\");
            //dir = StringUtils.removeEnd(StringUtils.removeEnd(machine.getProgTempDir(), "/"), "\\");
            dir = fixMachineDir(machine.getProgTempDir());
            WatchInfo watchInfo = new WatchInfo();
            watchInfo.setMachine(machine);
            watchInfo.setDirType(MachineFile.DIR_TYPE_TEMP);
@@ -129,6 +130,15 @@
        }
    }
    /**
     * ç¿»è¯‘共享文件夹路径到 æ ‡å‡†ç½‘络路径,去掉末尾路径分割不
     * @param dirpath åŽŸå§‹è·¯å¾„
     * @return è½¬æ¢åŽçš„路径
     */
    String fixMachineDir(String dirpath){
        return dirTranslator.trans(StringUtils.removeEnd(StringUtils.removeEnd(dirpath, "/"), "\\"));
    }
    FileWatcherService.FileChangeListener getListener(WatchInfo info) {
        return new MachineFileChangeListener(machineFileService,annotationService,info);
    }
blade-service/blade-mdm/src/main/java/org/springblade/mdm/config/ShutdownHook.java
@@ -3,19 +3,18 @@
import jakarta.annotation.PreDestroy;
import lombok.AllArgsConstructor;
import org.springblade.mdm.machinefile.filewatch.DirectorLockService;
import org.springblade.mdm.machinefile.filewatch.FileWatcherService;
import org.springframework.stereotype.Component;
@AllArgsConstructor
@Component
public class ShutdownHook {
    private final DirectorLockService directorLockService;
    private final FileWatcherService fileWatcherService;
    @PreDestroy
    public void onExit() {
        System.out.println("执行退出前清理操作...");
        // 1. å…³é—­æ–‡ä»¶ç›‘控
        // 2. é‡Šæ”¾èµ„源
        // 3. ä¿å­˜çŠ¶æ€
        // 4. é€šçŸ¥å…¶ä»–服务
        directorLockService.releaseLock();
        fileWatcherService.shutdown();
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/controller/MyFlowController.java
@@ -6,9 +6,7 @@
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.HistoryService;
import org.flowable.engine.TaskService;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
@@ -16,14 +14,11 @@
import org.springblade.mdm.basesetting.producedivision.service.MdmUserService;
import org.springblade.mdm.flow.service.DoneQueryService;
import org.springblade.mdm.flow.service.FlowBusinessService;
import org.springblade.mdm.flow.service.FlowCommonService;
import org.springblade.mdm.flow.service.FlowTransferService;
import org.springblade.mdm.flow.vo.DoneQueryVO;
import org.springblade.mdm.flow.vo.FlowVO;
import org.springblade.mdm.flow.vo.TodoQueryVO;
import org.springblade.mdm.gkw.programnode.vo.ProgramNodeVO;
import org.springblade.system.feign.IUserSearchClient;
import org.springblade.system.pojo.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
@@ -44,13 +39,7 @@
    @Autowired
    private FlowBusinessService businessService;
    @Autowired
    private IUserSearchClient userSearchClient;
    @Autowired
    private FlowTransferService flowTransferService;
    @Autowired
    private FlowCommonService flowCommonService;
    @Autowired
    private DoneQueryService doneQueryService;
    /**
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/append/AppendFinishListener.java
@@ -1,7 +1,6 @@
package org.springblade.mdm.flow.excution.append;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.DelegateExecution;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.mdm.flow.entity.FlowProgramFile;
@@ -78,7 +77,7 @@
            tempProgramNode.setName(newFlowFile.getName());
            tempProgramNode.setParentId(tempPkgNode.getId());
            tempProgramNode.setParentIds(tempPkgNode.getParentIds()+","+tempPkgNode.getId());
            tempProgramNode.setParentIds(tempPkgNode.subNodeParentIds());
            tempProgramNode.setProcessInstanceId(props.getProcessInstanceId());
            tempProgramNode.setFlowProgramFileId(newFlowFile.getId());
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/cure/DeviationCureFinishDataHandler.java
@@ -46,11 +46,9 @@
        EntityUtil.clearBaseProperties(newPkgNode);
        newPkgNode.setIsLastEdition(1);
        newPkgNode.upgradeVersionNumber();
        nodeService.save(newPkgNode);
        copyNonProgramNodes(pkgNode,newPkgNode);
        //copyNonProgramNodes(pkgNode,newPkgNode);
        addNewProgramNode(newPkgNode,props.getProcessInstanceId());
        log.info("临时更改单回传Listener完成");
@@ -61,6 +59,7 @@
     * @param oriPkgNode å¾…固化节点
     * @param cureNode å›ºåŒ–节点
     */
    /*
    void copyNonProgramNodes(NcNode oriPkgNode,NcNode cureNode){
        //处理程序包下层的程序节点1
        List<NcNode> oriProgramNodes = nodeService.lambdaQuery().eq(NcNode::getParentId,oriPkgNode.getId()).list();
@@ -80,7 +79,7 @@
            }
        }
    }
    }*/
    /**
     * åŠ å…¥æ–°çš„ç¨‹åºæ–‡ä»¶èŠ‚ç‚¹
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/excution/cure/NormalCureFinishDataHandler.java
@@ -171,6 +171,7 @@
            oldProgramNode.setIsLastEdition(0);
            //当前固化程序包名下的“其他文件”非程序文件。不设置为老版本,直接挪到固化树下,两个网络之间只交换程序文件,其他文件只能保留
            //其他文件,需要复制到新建的固化节点下(程序文件不复制)
            /*
            pfile = flowProgramFileService.getById(oldProgramNode.getFlowProgramFileId());
            if(!pfile.isProgram()) {
                NcNode newFileNode = new NcNode();
@@ -181,11 +182,17 @@
                newFileNode.setIsLastEdition(1);
                nodeService.save(newFileNode);
            }
            */
        }
        nodeService.updateBatchById(oriProgramNodes);
    }
    /**
     * åŠ å…¥æ–°çš„ç¨‹åºèŠ‚ç‚¹
     * @param cureNode å›ºåŒ–节点
     * @param processInstanceId æµç¨‹å®žä¾‹id
     * @throws IOException
     */
    void addNewProgramNode(NcNode cureNode,String processInstanceId) throws IOException {
        Machine machine = machineService.getByCode(cureNode.getMachineCode());
        List<DictBiz> annoDicts = programAnnotationService.getAnnotionDictList();
blade-service/blade-mdm/src/main/java/org/springblade/mdm/flow/service/CureFlowService.java
@@ -6,14 +6,13 @@
import org.flowable.engine.RuntimeService;
import org.flowable.engine.runtime.ProcessInstance;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.mdm.basesetting.machine.service.MachineService;
import org.springblade.mdm.basesetting.producedivision.service.ProduceDivisionService;
import org.springblade.mdm.flow.constants.FlowConstant;
import org.springblade.mdm.flow.constants.FlowVariableConstant;
import org.springblade.mdm.flow.entity.FlowProgramFile;
import org.springblade.mdm.program.entity.NcNode;
import org.springblade.mdm.program.service.NcNodeService;
import org.springblade.mdm.program.service.NodeDeptQueryService;
import org.springblade.mdm.utils.EntityUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -32,12 +31,9 @@
    private final RuntimeService runtimeService;
    private final IdentityService identityService;
    private final NodeDeptQueryService nodeDeptQueryService;
    private final NcNodeService ncNodeService;
    private final FlowProgramFileService flowProgramFileService;
    private final ProduceDivisionService produceDivisionService;
    private final MachineService machineService;
    private final FlowCommonService flowCommonService;
    /**
@@ -59,37 +55,11 @@
        vars.put(FlowConstant.NODE_ID,programPackage.getId());
        flowCommonService.putFlowVariablesByNode(vars,programPackage);
        /*
        vars.put(FlowVariableContants.MACHINE_CODE,programPackage.getMachineCode());
        //机床型号
        Machine machine = machineService.getByCode(programPackage.getMachineCode());
        if(machine != null) {
            vars.put(FlowVariableContants.MACHINE_MODE,machine.getName());
        }
        String workshop = nodeDeptQueryService.getWorkshopNameByMachineCode(programPackage.getMachineCode());
        vars.put(FlowVariableContants.WORKSHOP,workshop);
        vars.put(FlowContants.NODE_ID, Func.toStr(nodeId));
        vars.put(FlowVariableContants.PROCESS_NO,programPackage.getProcessNo());
        vars.put(FlowVariableContants.PROCESS_NAME,programPackage.getProcessName());
        vars.put(FlowVariableContants.PROCESS_EDITION,programPackage.getProcessEdition());
        vars.put(FlowVariableContants.CRAFT_EDITION, programPackage.getCraftEdition());
        vars.put(FlowVariableContants.DRAWING_NO,programPackage.getDrawingNo());
        vars.put(FlowVariableContants.DRAWING_NO_EDITION,programPackage.getDrawingNoEdition());
        vars.put(FlowVariableContants.PRODUCT_MODEL,programPackage.getProductModel());
        vars.put(FlowVariableContants.PROGRAM_PACKAGE_NAME,programPackage.getName());
        */
        flowCommonService.putDefaultAssignees(vars,programPackage.getDrawingNo(),null);
        vars.put(FlowVariableConstant.ASSIGNEE,vars.get(FlowVariableConstant.PROGRAMMER));
        identityService.setAuthenticatedUserId(String.valueOf(AuthUtil.getUserId()));//设置流程发起人
        vars.put(FlowVariableConstant.LAST_STEP_USER_NICKNAME, AuthUtil.getNickName());
        if(programPackage.getDeviation() != null) {
            vars.put(FlowVariableConstant.MY_PROCESS_NAME, "临时更改单回传");
@@ -109,16 +79,29 @@
        }
        this.flowProgramFileService.saveBatch(fileList);
        addPreviousOtherFiles(programPackage.getId(),inst.getProcessInstanceId());
        log.info("启动固化流程完成,实例id={}", inst.getId());
    }
    /**
     * å°†ç¨‹åºæŒ‰ç…§æœºå™¨ä»£ç åˆ†ç»„
     * @param ncProgramIdList
     * @return
     * å¤åˆ¶è¯•切阶段的其他文件给固化流程
     * @param previousNodeId è¯•切阶段的节点id
     * @param newProcessInstanceId æ–°çš„固化流程实例id
     */
    /*
    Map<String,List<NcProgram>> groupProgramsByMachineCode(List<Long> ncProgramIdList){
        List<NcProgram> programs = ncProgramService.listByIds(ncProgramIdList);
        return programs.stream().collect(Collectors.groupingBy(NcProgram::getMachineCode));
    }*/
    void addPreviousOtherFiles(Long previousNodeId,String newProcessInstanceId) {
        List<NcNode> previousFileNodes = ncNodeService.getProgramFilesByPackageId(previousNodeId);
        for(NcNode fileNode : previousFileNodes){
            FlowProgramFile progFile = flowProgramFileService.getById(fileNode.getFlowProgramFileId());
            if(!progFile.isProgram()){
                FlowProgramFile newProgFile = new FlowProgramFile();
                BeanUtils.copyProperties(progFile,newProgFile);
                EntityUtil.clearBaseProperties(newProgFile);
                newProgFile.setProcessInstanceId(newProcessInstanceId);
                flowProgramFileService.save(newProgFile);
            }
        }
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/gkw/programnode/vo/ProgramNameVO.java
@@ -1,7 +1,6 @@
package org.springblade.mdm.gkw.programnode.vo;
import com.alibaba.excel.util.StringUtils;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
/**
 * è£…载程序名结构
@@ -40,6 +39,17 @@
    }
    /**
     * èŽ·å–ä¸´æ—¶æ›´æ”¹å•åºå·
     * @return æ›´æ”¹å•序号
     */
    public String lgSerial(){
        if(StringUtils.startsWithIgnoreCase(lgPart,"P")){
            return lgPart.substring(1);
        }else{
            return null;
        }
    }
    /**
     * æ–‡ä»¶åæ˜¯å¦æœ‰æ•ˆ
     * @return
     */
blade-service/blade-mdm/src/main/java/org/springblade/mdm/gkw/task/entity/MachineBackTask.java
@@ -46,6 +46,10 @@
     */
    private String deviation;
    /**
     * ä¸´æ—¶æ›´æ”¹å•序号
     */
    private String deviationSerial;
    /**
     * ç¨‹åºæ€»æ®µæ•°/现场编制的=0
     */
    private int segCount;
@@ -56,4 +60,8 @@
    private int taskType;
    private Date finishTime;
    public boolean isProgramOnMachineTask(){
        return taskType == TASK_TYPE_ON_MACHINE;
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/gkw/task/mapper/MachineBackTaskMapper.xml
@@ -6,7 +6,7 @@
    <!--文件记录查询-->
    <select id="pageQuery" resultType="org.springblade.mdm.gkw.task.vo.MachineBackTaskVO">
        select t.id,t.program_name,t.machine_code,t.task_type,t.deviation,t.seg_count,t.finish_time,t.create_time,t.status,t.update_time,u.name create_user_name
        select t.id,t.program_name,t.machine_code,t.task_type,t.deviation,t.deviation_serial,t.seg_count,t.finish_time,t.create_time,t.status,t.update_time,u.name create_user_name
        from mdm_machine_back_task t left join blade_user u on t.create_user=u.id
        <where>
            t.is_deleted=0
blade-service/blade-mdm/src/main/java/org/springblade/mdm/gkw/task/vo/MachineBackTaskVO.java
@@ -14,7 +14,13 @@
    @Schema(description = "机床编号")
    private String machineCode;
    @Schema(description = "更改单号")
    private String deviation;
    @Schema(description = "更改单序号")
    private String deviationSerial;
    @Schema(description = "任务类型")
    private int taskType;
    @Schema(description = "程序段数")
    private int segCount;
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/controller/MachineFileController.java
@@ -93,12 +93,12 @@
    }
    @PostMapping("/change-file-name")
    @Operation(summary = "保存机床文件", description = "保存机床文件到磁盘")
    @Operation(summary = "SEND文件重命名", description = "SEND文件重命名")
    public R<Void> changeFileName(Long id,String name) {
        try {
            machineFileService.changeName(id,name);
        } catch (Exception e) {
            log.error(e.getMessage());
            log.error("文件重命名异常",e);
            return R.fail(e.getMessage());
        }
        return R.success();
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/entity/FileSendRecord.java
@@ -42,9 +42,14 @@
    private String programStatus;
    /**
     * ä¸´æ—¶æ›´æ”¹å•号
     * ä¸´æ—¶æ›´æ”¹å•号,非持久化属性
     */
    //private String deviation;
    transient private String deviation;
    /**
     * ä¸´æ—¶æ›´æ”¹å•序号,非持久化属性
     */
    transient private String deviationSerial;
    /**
     * ç”Ÿæˆæ–‡ä»¶å¤§å°çš„æ˜¾ç¤ºæ–‡æœ¬
     * @return æ˜¾ç¤ºæ–‡æœ¬
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/filewatch/FileLockChecker.java
@@ -36,7 +36,7 @@
     */
    public static boolean isFileComplete(Path file) throws IOException, InterruptedException {
        long initialSize = Files.size(file);
        Thread.sleep(3000); // ç­‰å¾…1秒
        Thread.sleep(1000); // ç­‰å¾…1秒
        long currentSize = Files.size(file);
        return initialSize == currentSize;
    }
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/filewatch/FileWatcherService.java
@@ -20,7 +20,7 @@
    private final ExecutorService executor = Executors.newCachedThreadPool();
    private final Map<Path, WatchService> watchServices = new HashMap<>();
    private final Map<Path, FileChangeListener> listeners = new HashMap<>();
    private final Map<Path, FileState> fileStatesOld = new HashMap<>();
    Cache<Path, FileState> fileStates = CacheBuilder.newBuilder()
        .maximumSize(10) // æœ€å¤§å®¹é‡3
        .build();
@@ -64,8 +64,6 @@
                        FileState currentState = fileStates.getIfPresent(fullPath);
                        currentState = (currentState == null) ? FileState.STABLE : currentState;
                        //FileState currentState = fileStates.getOrDefault(fullPath, FileState.STABLE);
                        FileChangeListener currentListener = listeners.get(directory);
                        if (currentListener == null) break;
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/filewatch/MachineFileChangeListener.java
@@ -1,6 +1,5 @@
package org.springblade.mdm.machinefile.filewatch;
import com.alibaba.excel.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.tool.utils.SpringUtil;
import org.springblade.mdm.basesetting.machine.entity.Machine;
@@ -11,23 +10,16 @@
import org.springblade.mdm.machinefile.service.MachineFileService;
import org.springblade.mdm.program.service.ProgramAnnotationService;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class MachineFileChangeListener implements FileWatcherService.FileChangeListener{
    private final MachineFileService machineFileService;
    ProgramAnnotationService programAnnotationService;
    private final Machine machine;
    private final String dirType;
    public MachineFileChangeListener(MachineFileService aMachineFileService, ProgramAnnotationService annotationService, WatchInfo info) {
@@ -41,10 +33,15 @@
        try {
            log.info("文件创建{},mcode={},dieType={}",filePath,machine.getCode(),dirType);
            if(FileLockChecker.isFileComplete(filePath)){
            if(this.waitingForFileComplete(filePath)){
                log.info("{}传输完成Create,开始处理",filePath);
                MachineFileScanService fileScanService = SpringUtil.getBean(MachineFileScanService.class);
                MachineFile mf = fileScanService.readFileToMachineFile(filePath,this.machine,this.dirType,programAnnotationService.getAnnotionDictList());
                MachineFile mf = fileScanService.readFileToMachineFile(filePath,this.machine,this.dirType);
                machineFileService.refreshFileData(mf);
            }else{
                //0928新增:文件传输没完成
                log.info("{}传输未完成Created,不处理",filePath);
            }
            saveMonitor(filePath,FileMonitorRecord.EVENT_CREATE);
        } catch (InterruptedException e) {
@@ -56,16 +53,34 @@
        }
    }
    /**
     * ç­‰å¾…文件传输完成(检测20次)
     * @param filePath æ–‡ä»¶Path对象
     * @return æœ€ç»ˆæ˜¯å¦ä¼ è¾“完成
     * @throws IOException æ–‡ä»¶æ£€æµ‹é—®é¢˜
     * @throws InterruptedException çº¿ç¨‹ç­‰å¾…可能引发的异常
     */
    boolean waitingForFileComplete(Path filePath) throws IOException, InterruptedException {
        final int maxWaitTimes = 20; //文件传输完成检测次数
        boolean isCompleted = false;
        for(int i=0;i<maxWaitTimes;i++){
            isCompleted = FileLockChecker.isFileComplete(filePath);
            if(isCompleted){
                break;
            }
        }
        return isCompleted;
    }
    @Override
    public void onFileModified(Path filePath) {
        //文件修改
        log.info("文件修改:{}",filePath);
        try {
            if(FileLockChecker.isFileComplete(filePath)){
                log.info("文件传输完成{}",filePath);
            if(waitingForFileComplete(filePath)){
                log.info("文件传输完成Modify{}",filePath);
                MachineFileScanService fileScanService = SpringUtil.getBean(MachineFileScanService.class);
                MachineFile mf = fileScanService.readFileToMachineFile(filePath,this.machine,this.dirType,programAnnotationService.getAnnotionDictList());
                MachineFile mf = fileScanService.readFileToMachineFile(filePath,this.machine,this.dirType);
                machineFileService.refreshFileData(mf);
            }else{
                log.warn("文件传输中,后续再操作{}",filePath);
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/listeners/ExportToInnerListener.java
@@ -24,7 +24,7 @@
import java.util.Optional;
/**
 * å›ºåŒ–流程执行完成后,需要处理的事件:入库mes同步表
 * è§†æƒ…况将已经导出的现场编程文件,保存到PROGRAM文件夹
 */
@Slf4j
@Component
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/mapper/MachineAcceptedFileMapper.xml
@@ -22,7 +22,7 @@
-->
    <!--机床回传程序处理分页-->
    <select id="handlePageQuery" resultType="org.springblade.mdm.machinefile.vo.MachineAcceptedFileVO">
        select f.id,f.name,f.oss_name,f.create_time,m.code machine_code, m.name machine_name,f.status,f.create_time,mf.program_status,mf.file_create_time,f.export_time,f.create_time
        select f.id,f.name,f.oss_name,m.code machine_code, m.name machine_name,f.status,f.create_time,mf.program_status,mf.file_create_time,f.export_time,f.create_time
        from mdm_machine_accepted_file f
            left join mdm_machine_file mf on f.machine_file_id=mf.id
        left join mdm_machine m on mf.machine_code=m.code
@@ -42,6 +42,7 @@
            and m.confirm_time$lt;#{query.confirmTimeEnd}
        </if>
        </where>
        order by f.export_time desc,f.create_time desc
    </select>
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/mapper/MachineFileMapper.java
@@ -34,4 +34,8 @@
     */
    IPage<MachineFile> exceptionFilePageQuery(IPage<Object> page,@Param("query") MachineFileExceptionQueryVO query);
    /**
     * åˆ é™¤æ— ç”¨æ–‡ä»¶å‡ é‡Œè·¯
     */
    void deleteNotUseRecords();
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/mapper/MachineFileMapper.xml
@@ -11,6 +11,12 @@
        <result column="is_deleted" property="isDeleted"/>
    </resultMap>
    <!--删除没有引用的,且标记为删除的文件记录-->
    <delete id="deleteNotUseRecords">
        delete from mdm_machine_file_change_his where machine_file_id in (select id mdm_machine_file where id not in (select machine_file_id from mdm_machine_accepted_file) and status=4);
        delete from mdm_machine_file where id not in (select machine_file_id from mdm_machine_accepted_file) and status=4;
    </delete>
    <!--待接收机床文件分页查询-->
    <select id="filePageForAccept" resultType="org.springblade.mdm.machinefile.entity.MachineFile">
        select f.id,f.name,f.machine_code,f.file_create_time,f.md5,f.file_size,f.dir_type,f.program_status
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/service/MachineAcceptedFileService.java
@@ -31,6 +31,7 @@
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -148,9 +149,12 @@
        //现场编程的任务集合
        //List<MachineBackTask> onMachineTasks1 = machineBackTaskService.lambdaQuery().in(MachineBackTask::getId, backTaskIds).list();
        if(backTaskIds.isEmpty()){
            return Collections.emptyList();
        }
        List<MachineBackTask> onMachineTasks = machineBackTaskService.lambdaQuery()
            .eq(MachineBackTask::getTaskType,MachineBackTask.TASK_TYPE_ON_MACHINE)
            .in(MachineBackTask::getId, backTaskIds).list();
            .list();
        List<Long> onMachineFileIds = new ArrayList<>();
        for(MachineAcceptedFile accFile : acceptedFiles){
@@ -160,7 +164,14 @@
                }
            }
        }
        if(onMachineFileIds.isEmpty()){
            return Collections.emptyList();
        }
        return machineFileService.lambdaQuery().in(MachineFile::getId,onMachineFileIds).list();
    }
    public List<MachineAcceptedFile> listByBackTaskId(Long backTaskId) {
        return lambdaQuery().eq(MachineAcceptedFile::getBackTaskId,backTaskId).list();
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/service/MachineFileScanService.java
@@ -6,9 +6,11 @@
import org.springblade.core.log.exception.ServiceException;
import org.springblade.mdm.basesetting.machine.service.MachineService;
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.commons.service.MachineDirTranslator;
import org.springblade.mdm.commons.service.ParamService;
import org.springblade.mdm.gkw.programnode.vo.ProgramNameVO;
import org.springblade.mdm.machinefile.entity.MachineFile;
import org.springblade.mdm.machinefile.mapper.MachineFileMapper;
import org.springblade.mdm.program.service.ProgramAnnotationService;
import org.springblade.mdm.program.service.programannotation.*;
import org.springblade.mdm.utils.FileContentUtil;
@@ -37,14 +39,11 @@
    @Autowired
    private MachineService machineService;
    @Autowired
    private ProgramAnnotationService programAnnotationService;
    @Autowired
    private MachineAnnotationConfig annoConfig;
    @Autowired
    private AnnotationProcessorHelper annotationProcessorHelper;
    /**
     * æ‰«ææ‰€æœ‰æœºåºŠçš„配置目录
     */
    @Autowired
    private MachineDirTranslator machineDirTranslator;
    @Autowired
    private MachineFileMapper machineFileMapper;
    @Async
    public void scanMachineFile() {
        List<Machine> machines = machineService.getEnableMachines();
@@ -85,17 +84,17 @@
            }
        }
        machineFileMapper.deleteNotUseRecords();
    }
    /**
     * æ‰«æç›®å½•
     * @param machine æœºåºŠä¿¡æ¯
     * @param dirType ç›®å½•类型
     * @throws IOException
     * @throws IOException æ–‡ä»¶æ“ä½œå¯èƒ½å¯¼è‡´çš„异常
     */
    public void scanDir(Machine machine,String dirType) throws IOException {
        String basePath = MachineFileService.getBasePath(machine,dirType);
        String basePath = machineDirTranslator.trans(MachineFileService.getBasePath(machine,dirType));
        if(basePath == null) {
            log.warn("目录类型不匹配:{}",dirType);
            return;
@@ -110,11 +109,11 @@
            .filter(Files::isRegularFile).toList();
        //byte[] buffer = new byte[2048];
        List<DictBiz> annotatiionList = programAnnotationService.getAnnotionDictList();
        //List<DictBiz> annotatiionList = programAnnotationService.getAnnotionDictList();
        //boolean exists;//文件是否存在于数据库中
        for (Path filePath : files) {
            try {
                MachineFile mf = readFileToMachineFile(filePath,machine,dirType,annotatiionList);
                MachineFile mf = readFileToMachineFile(filePath,machine,dirType);
                machineFileService.refreshFileData(mf);
@@ -130,18 +129,16 @@
     * @param filePath æ–‡ä»¶è·¯å¾„
     * @param machine æœºå™¨
     * @param dirType ç›®å½•类型
     * @param annotatiionList æ³¨è§£é…ç½®å­—å…¸ ç”¨äºŽè¯»å–程序状态
     * @return MachineFile å®žä¾‹
     * @throws IOException
     */
    public MachineFile readFileToMachineFile(Path filePath,Machine machine,String dirType,List<DictBiz> annotatiionList) throws IOException {
    public MachineFile readFileToMachineFile(Path filePath,Machine machine,String dirType) throws IOException {
        MachineFile mf = new MachineFile();
        mf.setTenantId("000000");
        mf.setName(filePath.toFile().getName());
        mf.setDirType(dirType);
        mf.setMachineCode(machine.getCode());
        BasicFileAttributes attrs = Files.readAttributes(
            filePath,
@@ -177,53 +174,18 @@
        }
        return mf;
    }
    /**
     * è¯»å–文件中的程序状态
     * @param filePath æ–‡ä»¶è·¯å¾„
     * @param controlSystem
     * @param annotatiionList æ³¨é‡Šé…ç½®å­—å…¸
     * @return çŠ¶æ€çš„æ•´æ•°ä¹‹å’Œ
     * @throws IOException
     */
    public int readProgramStatus(Path filePath,String controlSystem,List<DictBiz> annotatiionList) throws IOException {
        int programStatus = MachineFile.PROGRAM_STATUS_UNKNOWN;
        try(InputStream ins = Files.newInputStream(filePath);
            BufferedInputStream byteInsStream = new BufferedInputStream(ins)){
            boolean isText= FileContentUtil.isTextFile(byteInsStream);
            if(!isText){
                return MachineFile.PROGRAM_STATUS_UNKNOWN;
            }
            byteInsStream.reset();
            AnnotationProcessor annoProcessor = ProcessorHelper.getProcessor(controlSystem,annoConfig);
            String statusLine = FileContentUtil.readLineAt(byteInsStream, annoProcessor.getAnnotationProperties().getStatusLineIndex());
            if(AnnotationUtil.isAnnotation(statusLine,controlSystem,annotatiionList)){
                String progStatusTxt = AnnotationUtil.removeAnnotation(controlSystem,statusLine,annotatiionList);
                if(AnnotationUtil.SQ.equals(progStatusTxt)){
                    programStatus = MachineFile.PROGRAM_STATUS_TRY;
                }else if(AnnotationUtil.GH.equals(progStatusTxt)){
                    programStatus = MachineFile.PROGRAM_STATUS_CURED;
                }else if(AnnotationUtil.LG.equals(progStatusTxt)){
                    programStatus = MachineFile.PROGRAM_STATUS_DIVIASTION;
                }
            }
        }
        return programStatus;
    }
    /**
     * æ¸…理已经删除了文件的记录
     * @param machine
     * @param dirType
     * @param machine æœºåºŠ
     * @param dirType ç›®å½•类型
     * @throws IOException
     */
    void clearDeletedRecords(Machine machine,String dirType) throws IOException {
        List<MachineFile> machineFiles =  this.machineFileService.lambdaQuery().eq(MachineFile::getDirType,dirType)
            .eq(MachineFile::getMachineCode,machine.getCode()).list();
        String basePath = MachineFileService.getBasePath(machine,dirType);
        String basePath = machineDirTranslator.trans(MachineFileService.getBasePath(machine,dirType));
        if(basePath == null) {
            log.warn("目录类型不匹配:{}",dirType);
            return;
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/service/MachineFileService.java
@@ -13,6 +13,7 @@
import org.springblade.core.oss.model.BladeFile;
import org.springblade.mdm.basesetting.machine.service.MachineService;
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.commons.service.MachineDirTranslator;
import org.springblade.mdm.machinefile.entity.MachineFile;
import org.springblade.mdm.machinefile.entity.MachineFileChangeHis;
import org.springblade.mdm.machinefile.mapper.MachineFileMapper;
@@ -21,6 +22,7 @@
import org.springblade.mdm.program.vo.CompareDataVO;
import org.springblade.mdm.statreport.vo.MachineFileExceptionQueryVO;
import org.springblade.mdm.utils.FileContentUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -44,7 +46,7 @@
    private final MachineService machineService;
    private final MachineFileChangeHisService machineFileChangeHisService;
    private final OssTemplate ossTemplate;
    private MachineDirTranslator machineDirTranslator;
    /**
     * èŽ·å–æ–‡ä»¶å…¨è·¯å¾„
     * @param id æ•°æ®id
@@ -87,9 +89,9 @@
    /**
     * èŽ·å–åŸºæœ¬è·¯å¾„
     * @param machine
     * @param dirType
     * @return
     * @param machine æœºåºŠ
     * @param dirType ç›®å½•类型
     * @return ç›®å½•基本路径
     */
    public static String getBasePath(Machine machine,String dirType){
        String dirPath;
@@ -221,6 +223,7 @@
            existFileInDb.setProgramStatus(mf.getProgramStatus());
            existFileInDb.setFileCreateTime(mf.getFileCreateTime());
            existFileInDb.setFileModifyTime(mf.getFileModifyTime());
            existFileInDb.setStatus(MachineFile.STATUS_NORMAL);
            if(!com.alibaba.excel.util.StringUtils.equals(existFileInDb.getMd5(),mf.getMd5())){
                //文件内容发生变化了,设置状态为初始状态
                existFileInDb.setStatus(MachineFile.STATUS_NORMAL);
@@ -249,12 +252,25 @@
    }
    /**
     * ä¿®æ”¹æ–‡ä»¶åæˆ
     * ä¿®æ”¹æ–‡ä»¶åç§°
     * @param id æ–‡ä»¶id
     * @param name æ–°åç§°
     */
    public void changeName(Long id, String name) {
    public void changeName(Long id, String name) throws IOException {
        MachineFile machineFile = getById(id);
        if(machineFile.getName().equals(name)) {
            return;
        }
        Machine machine = machineService.getByCode(machineFile.getMachineCode());
        String baseDir = machineDirTranslator.trans(getBasePath(machine,machineFile.getDirType()));
        String targetFilePath = baseDir + File.separator + name;
        Path filePath = Paths.get(targetFilePath);
        if(filePath.toFile().exists()) {
            throw new ServiceException("同名文件已存在:"+name);
        }
        Files.move(Paths.get(baseDir+File.separator+machineFile.getName()),filePath);
        baseMapper.deleteById(id);
    }
    public MachineFile getByNameAndMachineInDir(String name, String machineCode, String dirType) {
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/service/NcProgramExportInnerService.java
@@ -5,14 +5,12 @@
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springblade.core.mp.base.BizServiceImpl;
import org.springblade.core.oss.OssTemplate;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.SpringUtil;
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.basesetting.machine.service.MachineService;
import org.springblade.mdm.flow.excution.events.CureFinishedEvent;
import org.springblade.mdm.gkw.task.entity.MachineBackTask;
import org.springblade.mdm.gkw.task.service.MachineBackTaskService;
import org.springblade.mdm.machinefile.entity.MachineAcceptedFile;
@@ -54,9 +52,9 @@
    private final MachineBackTaskService machineBackTaskService;
    /**
     * å¯¼å‡ºåˆ°æ¶‰å¯†ç½‘
     * @param acceptedFileIds
     * @param os
     * @throws IOException
     * @param acceptedFileIds æŽ¥å—的文件id离了吧
     * @param os è¾“出流
     * @throws IOException æ“ä½œzip可能导致的IO异常
     */
    @Transactional
    public void exportToInner(List<Long> acceptedFileIds, ServletOutputStream os) throws IOException {
@@ -65,6 +63,8 @@
        try (ZipOutputStream zipOut = new ZipOutputStream(os);) {//os
            Map<String,List<MachineAcceptedFile>> map =  acceptedFiles.stream()
                .collect(Collectors.groupingBy(s -> ProgramFileNameParser.parseProgramName(s.getName()).logicProgramName()));
            this.createFoldersInZip(zipOut,map.keySet());
            for (Map.Entry<String, List<MachineAcceptedFile>> entry : map.entrySet()) {
                String programName = entry.getKey();
@@ -77,7 +77,6 @@
                    acceptedFile.setExportTime(DateUtil.now());
                    acceptedFile.setStatus(MachineAcceptedFile.STATUS_EXPORTED);
                }
            }
            machineAcceptedService.updateBatchById(acceptedFiles);
@@ -94,18 +93,39 @@
    }
    /**
     * åˆ›å»ºå·¦å³çš„程序包名文件夹
     * @param zipOut zip输出流
     * @param folderSet ç¨‹åºæŠ¥åæ–‡ä»¶å¤¹é›†åˆ
     * @throws IOException zipIO操作异常
     */
    void createFoldersInZip(ZipOutputStream zipOut,Set<String> folderSet) throws IOException {
        for(String folderName : folderSet){
            ZipEntry zipEntry = new ZipEntry(folderName+"/");// "/"结尾表示文件夹
            zipOut.putNextEntry(zipEntry);
            zipOut.closeEntry();
        }
    }
    void finishTask(List<Long> backTaskIdList){
        if(backTaskIdList.isEmpty()){
            return;
        }
        List<MachineBackTask> tasks = machineBackTaskService.lambdaQuery().in(MachineBackTask::getId,backTaskIdList).list();
        for(MachineBackTask backTask : tasks){
            backTask.setStatus(MachineBackTask.STATUS_FINISHED);
            backTask.setFinishTime(new Date());
        for(Long backTaskId : backTaskIdList){
            MachineBackTask backTask = machineBackTaskService.getById(backTaskId);
            List<MachineAcceptedFile> acceptedFiles = machineAcceptedService.listByBackTaskId(backTaskId);
            machineBackTaskService.updateById(backTask);
            if(acceptedFiles.size() == backTask.getSegCount()) {
                backTask.setStatus(MachineBackTask.STATUS_FINISHED);
                backTask.setFinishTime(new Date());
                machineBackTaskService.updateById(backTask);
            }
        }
    }
    /**
blade-service/blade-mdm/src/main/java/org/springblade/mdm/machinefile/service/ReceiveFileCheckService.java
@@ -9,8 +9,11 @@
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.basesetting.machine.service.MachineService;
import org.springblade.mdm.commons.contants.RegExpConstants;
import org.springblade.mdm.commons.service.MachineDirTranslator;
import org.springblade.mdm.commons.service.ParamService;
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.entity.MachineFile;
import org.springblade.mdm.program.entity.ProgramOnMachine;
@@ -50,8 +53,9 @@
    @Autowired
    private AnnotationProcessorHelper annoProcessHelper;
    @Autowired
    private ProgramAnnotationService programAnnotationService;
    private MachineDirTranslator machineDirTranslator;
    @Autowired
    private MachineBackTaskService machineBackTaskService;
    /**
     * æ–‡ä»¶åˆæ³•性检查
     * @param machineFile
@@ -59,7 +63,7 @@
    @Transactional(rollbackFor = Exception.class)
    public void check(MachineFile machineFile,List<MachineFile> allFilesInDir,Machine machine) throws IOException {
        String srcFilepath = MachineFileService.getBasePath(machine,machineFile.getDirType())+ File.separator+machineFile.getName();
        String srcFilepath = machineDirTranslator.trans(MachineFileService.getBasePath(machine,machineFile.getDirType())+ File.separator+machineFile.getName());
        log.info("开始检查文件{}",srcFilepath);
        Path checkFilePath = Paths.get(srcFilepath);
        if(!checkFilePath.toFile().exists()){
@@ -84,9 +88,13 @@
                    if(matchCount != progNameVO.getSegmentCount()){//文件段数缺失
                        excepType = MachineFile.EXCEPTION_LOST_FILES;
                    }else{
                        //检查是否匹配机床回传任务?
                        //检查是否匹配机床回传任务
                        byteStream.reset();
                        AnnotationProcessor annoProcessor = this.annoProcessHelper.getProcessor(machine.getControlSystem());
                        AnnotationData annoData = annoProcessor.readAnnotationData(byteStream);
                        Optional<MachineBackTask> taskOpt = backTaskForFile(machineFile,annoData);
                        //检查是否匹配下发记录的段数
                        /*
                        String nameLikeStr;
                        if(StringUtils.isNotBlank(progNameVO.getLgPart())){
                            nameLikeStr = prefix +"%P%";
@@ -97,26 +105,31 @@
                            .eq(FileSendRecord::getMachineCode,machineFile.getMachineCode())
                            .likeRight(FileSendRecord::getName,nameLikeStr).last("limit 1")
                            .orderByDesc(FileSendRecord::getCreateTime).oneOpt();
                        boolean matchSendRecord;//文件是否有下发记录
                        if(optFile.isPresent()){
                            matchSendRecord = true;
                            //确实下发过,比对总段数是否相同
                            FileSendRecord sendFile = optFile.get();
                            ProgramNameVO sendProgNameVO =  ProgramFileNameParser.parseProgramName(sendFile.getName());
                            if(progNameVO.getSegmentCount() != sendProgNameVO.getSegmentCount()){
                                //段数不匹配下发记录
                                excepType = MachineFile.EXCEPTION_NOT_MATCH_SEND_SEG_COUNT;
                            }else if(!StringUtils.equals(sendProgNameVO.getLgPart(),progNameVO.getLgPart())){
                                excepType = MachineFile.EXCEPTION_NOT_MATCH_SEND_LG;
                        */
                        //boolean matchSendRecord;//文件是否有下发记录
                        if(taskOpt.isPresent()){
                            //有任务,比对总段数是否相同
                            MachineBackTask backTask = taskOpt.get();
                            //FileSendRecord sendFile = optFile.get();
                            //ProgramNameVO sendProgNameVO =  ProgramFileNameParser.parseProgramName(sendFile.getName());
                            if(!backTask.isProgramOnMachineTask() ){//工艺编制
                                if(progNameVO.getSegmentCount() != backTask.getSegCount()) {
                                    //段数不匹配下发记录
                                    excepType = MachineFile.EXCEPTION_NOT_MATCH_SEND_SEG_COUNT;
                                }
                            }else{
                                //现场编程,检查更改单序号
                                if(StringUtils.isNotBlank(backTask.getDeviationSerial()) && !StringUtils.equals(backTask.getDeviationSerial(),progNameVO.lgSerial())){
                                    excepType = MachineFile.EXCEPTION_NOT_MATCH_SEND_LG;
                                }
                            }
                        }else{
                            matchSendRecord = false;
                            excepType = MachineFile.EXCEPTION_NOT_MATCH_RECORD;
                        }
                        /*
                        if(!matchSendRecord){//如果文件未下发过,查看是否有现场编程记录
                            byteStream.reset();
                            String devSerial = null;
                            if(StringUtils.isNotBlank(progNameVO.getLgPart())){
                                devSerial = progNameVO.getLgPart().substring(1);
@@ -133,6 +146,8 @@
                            }
                        }
                         */
                    }
                }
            }
@@ -141,4 +156,16 @@
            machineFileService.updateById(machineFile);
        }
    }
    Optional<MachineBackTask> backTaskForFile(MachineFile machineFile,AnnotationData annoData){
        ProgramNameVO progNameVO = ProgramFileNameParser.parseProgramName(machineFile.getName());
        return machineBackTaskService.lambdaQuery()
            .eq(MachineBackTask::getStatus,MachineBackTask.STATUS_PENDING)
            .eq(MachineBackTask::getMachineCode,machineFile.getMachineCode())
            .eq(MachineBackTask::getProgramName,progNameVO.logicProgramName())
            .eq(progNameVO.lgSerial()!=null,MachineBackTask::getDeviation,annoData.getDeviation())
            .eq(progNameVO.lgSerial()!=null,MachineBackTask::getDeviationSerial,progNameVO.lgSerial())
            .last("limit 1").oneOpt();
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/controller/MdmProgramImportController.java
@@ -31,7 +31,6 @@
@Slf4j
public class MdmProgramImportController {
    //private final DncSendBackService dncSendBackService;
    private final MdmProgramImportService mdmProgramImportService;
    /**
     * ä¸Šä¼ DNC回传文件
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/controller/ProgramOnMachineImportController.java
@@ -8,18 +8,12 @@
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springblade.core.excel.util.ExcelUtil;
import org.springblade.core.tenant.annotation.NonDS;
import org.springblade.core.tool.api.R;
import org.springblade.mdm.flow.vo.ProgramOnMachineExcel;
import org.springblade.mdm.flow.vo.ProgramOnMachineQueryVO;
import org.springblade.mdm.program.service.MdmProgramImportService;
import org.springblade.mdm.program.service.ProgramOnMachineService;
import org.springblade.mdm.program.vo.*;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
/**
 * mdm导入接口,工控网功能
@@ -35,14 +29,10 @@
public class ProgramOnMachineImportController {
    private final ProgramOnMachineService programOnMachineService;
    /**
     * ä¸Šä¼ DNC回传文件
     *
     * @param file    dnc程序打包文件
     */
    @PostMapping("import-prog-on-machine")
    @ApiOperationSupport(order = 1)
    @Operation(summary = "MDM程序导入", description = "工控网mdm程序导入")
    @Operation(summary = "工控网导入现场编制数据", description = "工控网导入现场编制数据")
    public R<Integer> upload(@RequestParam MultipartFile file) {
        if(file == null || file.isEmpty() || file.getOriginalFilename() ==null){
            return R.fail("文件不能为空");
@@ -62,7 +52,6 @@
    @Operation(summary = "工控网下场编程记录分页查询", description = "工控网下场编程记录分页查询")
    @GetMapping("/program-on-machine-page")
    public R<IPage<ProgramOnMachineVO>> page(ProgramOnMachineRecordQueryVO queryVO) {
        return R.data(programOnMachineService.pageQuery(queryVO));
    }
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/entity/DncBackFile.java
@@ -8,14 +8,12 @@
import java.util.Date;
/**
 * DNC回传文件,数据通过监控目录获取文件并入库
 * å·¥æŽ§ç½‘)回传文件记录
 */
@Setter
@Getter
@TableName("mdm_dnc_back_file")
public class DncBackFile extends BizEntity {
    public static int STATUS_ACCEPTED = 2;
    public static int STATUS_REJECTED = 3;
    /**
     * ç¨‹åºåŒ…名 èŠ‚ç‚¹ çš„id
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/DNCSendBackService.java
@@ -72,7 +72,6 @@
     * åç¦»å•文件末尾的模式:P+数字
     */
    private static final String P_NUMBER_PATTERN = "(?i)P\\d+";
    //static String[] encodings = {"UTF-8","GBK", "GB2312", "ISO-8859-1"};
    private String getFileKey(){
        return "dncimpfile-"+ AuthUtil.getUserId();
    }
@@ -120,9 +119,12 @@
                result = parseProgramListByCharset(byteInsStream,Charset.forName(encoding));
                log.error("使用编码 {} è§£æžæˆåŠŸ ",encoding);
                break;
            }catch (ServiceException se) {
                log.error("数据不正确异常:",se);
                break;
            } catch (Exception e) {
                byteInsStream.reset();
                log.error("使用编码 {} è§£æžå¤±è´¥: ",encoding,e);
                log.error("使用编码 {} è§£æžå¤±è´¥:",encoding,e);
            }
        }
        if(result != null) {
@@ -242,8 +244,7 @@
    @Transactional
    public void dncFileAccept(String ids) throws IOException {
        List<Long> acceptIdList = Func.toLongList(ids);
        //
        NcProgramExchange exchange;
        String filekey = getFileKey();
        String zipFileName = bladeRedis.get(filekey);
        log.info("filekey={},文件名={}",filekey,zipFileName);
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/DncBackFileService.java
@@ -6,14 +6,11 @@
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.HistoryService;
import org.flowable.engine.ProcessEngine;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BizServiceImpl;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.oss.OssTemplate;
import org.springblade.core.oss.model.BladeFile;
import org.springblade.core.tool.utils.FileUtil;
import org.springblade.mdm.flow.entity.FlowProgramFile;
import org.springblade.mdm.flow.service.FlowBusinessService;
import org.springblade.mdm.program.entity.DncBackFile;
import org.springblade.mdm.program.entity.NcNode;
@@ -22,13 +19,10 @@
import org.springblade.mdm.program.vo.DncBackFileQueryVO;
import org.springblade.mdm.program.vo.DncBackFileVO;
import org.springblade.mdm.program.vo.DncSendBackFile;
import org.springblade.mdm.utils.FileContentUtil;
import org.springblade.mdm.utils.ZipTextFileContentUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
@@ -37,7 +31,6 @@
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Optional;
import java.util.zip.ZipEntry;
/**
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/MdmProgramImportService.java
@@ -1,11 +1,9 @@
package org.springblade.mdm.program.service;
import jodd.util.annotation.AnnotationParser;
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;
@@ -16,7 +14,6 @@
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;
@@ -43,7 +40,6 @@
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;
@@ -260,8 +256,8 @@
        MdmProgramImportVO vo = new MdmProgramImportVO();
        vo.setFilename(path.getFileName().toString());
        ProgramNameVO pnmameVO = tryParseProgramName(vo.getFilename());
        vo.setDrawingNo(pnmameVO.getDrawingNo());
        ProgramNameVO progNmameVO = tryParseProgramName(vo.getFilename());
        vo.setDrawingNo(progNmameVO.getDrawingNo());
        try (InputStream inputStream = Files.newInputStream(path)) {
            // ä½¿ç”¨è¾“入流读取文件内容
@@ -286,7 +282,7 @@
            Machine matchedMachine = machineService.getMachineBySendPathAnnotation(sendPathLine);
            if (matchedMachine != null) {
                vo.setName(pnmameVO.logicProgramName());
                vo.setName(progNmameVO.logicProgramName());
                vo.setMachineCode(matchedMachine.getCode());
                vo.setFullPath(path.toString());//文件地址
@@ -300,68 +296,7 @@
        }
        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列表逗号分隔
@@ -378,7 +313,7 @@
        Path extractDir = Paths.get(dictStr);
        List<MdmProgramImportVO> list = readTempDir(extractDir);
        List<DictBiz> annoDictList = programAnnotationService.getAnnotionDictList();
        //List<DictBiz> annoDictList = programAnnotationService.getAnnotionDictList();
        String destFileFull;
        for(String str : idList){
            Optional<MdmProgramImportVO> optVO = list.stream().filter(vo -> vo.getId().equals(str)).findFirst();
@@ -391,6 +326,7 @@
            destFileFull = vo.getSendPath()+File.separator+vo.getFilename();
            File destFile = new File(destFileFull);
            FileUtils.forceMkdirParent(destFile);
            FileUtils.copyFile(new File(str),destFile);
@@ -410,11 +346,11 @@
                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());
                if(StringUtils.isNotBlank(nameVO.getLgPart())) {
                    record.setDeviation(annotationData.getDeviation());
                }*/
                record.setDeviationSerial(nameVO.lgSerial());
                record.setProgramStatus(annotationData.getProgramStatus());
            }
            fileSendRecordService.save(record);
@@ -427,17 +363,17 @@
    /**
     * åˆ›å»ºæœºåºŠå›žä¼ ä»»åŠ¡
     * @param importedRecords
     * @param importedRecords å¯¼å…¥è®°å½•列表
     */
    List<MachineBackTask> parseMachineBackTask(List<FileSendRecord>  importedRecords){
        List<FileSendRecord> recList = importedRecords.stream().filter(r ->{
            return AnnotationUtil.SQ.equals(r.getProgramStatus())
                || AnnotationUtil.LG.equals(r.getProgramStatus());}).toList();
        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);
        }
@@ -450,6 +386,9 @@
            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);
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcNodeService.java
@@ -188,7 +188,6 @@
     * @return æœ€æ–°ç‰ˆæœ¬ç¨‹åºæŠ¥åèŠ‚ç‚¹
     */
    public NcNode getLastEditionTryingProgramPackage(String name){
        //.or(NcNode::getIsCured,0)
        List<NcNode> pkgList = lambdaQuery().eq(NcNode::getNodeType,NcNode.TYPE_PROGRAM_PACKAGE)
            .eq(NcNode::getName, name).and(i->{
                i.eq(NcNode::getIsCured, 0).or().isNull(NcNode::getIsCured);
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/NcProgramExportDNCService.java
@@ -50,8 +50,6 @@
    private final FlowProgramFileService flowProgramFileService;
    private final HistoryService historyService;
    private final TaskDispatchService taskDispatchService;
    private final MachineAnnotationConfig annotationConfig;
    private final AnnotationProcessorHelper annotationProcessorHelper;
    /**
     * å¯¼å‡ºdnc压缩包
@@ -90,8 +88,8 @@
    /**
     * å°†ç¨‹åºåŒ…和下属文件加入压缩包
     * @param zipOut
     * @param approved
     * @param zipOut zip文件输出流
     * @param approved å®¡æ‰¹å®Œæˆè®°å½•
     */
    private void addProgramPackageToZip(ZipOutputStream zipOut, NcProgramApproved approved) throws IOException{
        NcNodeHis packageNodeHis = ncNodeHisService.getById(approved.getNcNodeId());
@@ -126,7 +124,6 @@
                InputStream inputStream = ossTemplate.statFileStream(programFile.getOssName());
                String sendDir = machine.getProgSendDir()==null? StringUtil.EMPTY:machine.getProgSendDir();
                //AnnotationProcessor annoProcessor = ProcessorHelper.getProcessor(machine.getControlSystem(),annotationConfig);
                AnnotationProcessor annoProcessor = this.annotationProcessorHelper.getProcessor(machine.getControlSystem());
                AnnotationData annoData = new AnnotationData();
                annoData.setSendPath(sendDir);
@@ -134,9 +131,12 @@
                annoData.setDeviation(programPackageNode.getDeviation());
                annoData.setFilename(programFile.getName());
                InputStream addedInsFinal = annoProcessor.putAnnotation(annoData,inputStream);
                if(StringUtils.startsWith(programPackageNode.getParentIds(),"0,4")) {
                    //试切补充,特殊标记状态
                    annoData.setProgramStatus(AnnotationUtil.TMP);
                }
                InputStream addedInsFinal = annoProcessor.putAnnotation(annoData, inputStream);
                addedInsFinal.reset();
                this.addInputStreamToZip(zipOut, addedInsFinal, filePathInZip);
            }
        }
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/programannotation/AbstractProcessor.java
@@ -19,28 +19,34 @@
    private ProgramAnnotationService programAnnotationService;
    protected AnnotationProperties annotationProperties;
    protected List<DictBiz> getAnnotationDictList(){
        return programAnnotationService.getAnnotionDictList();
    }
    @Override
    public InputStream putSendPathAnnotation(String sendPath, InputStream inputStream,List<DictBiz> annoDicts) throws IOException{
        String sendPathRepl = StringUtils.replace(sendPath,"\\","/");
        InputStream finishedStream;
        try(inputStream){
            ByteArrayInputStream byteInputStream =  new ByteArrayInputStream(IOUtils.toByteArray(inputStream));
            //1加入发送路径的注释
            String sendPathAnnotation = AnnotationUtil.generateAnnotation(sendPath,getControlSystem(),annoDicts);//加了注释之后的文本
            String sendPathAnnotation = AnnotationUtil.generateAnnotation(sendPathRepl,getControlSystem(),annoDicts);//加了注释之后的文本
            String sendDirLine = FileContentUtil.readLineAt(byteInputStream,annotationProperties.getSendPathLineIndex());//第2行是发送路径
            String sendPathLine = FileContentUtil.readLineAt(byteInputStream,annotationProperties.getSendPathLineIndex());//第2行是发送路径
            byteInputStream.reset();
            if(AnnotationUtil.isAnnotation(sendDirLine,getControlSystem(),annoDicts)){
                String planText = AnnotationUtil.removeAnnotation(getControlSystem(),sendDirLine,annoDicts);
                if(!planText.equals(sendPath)) {
            if(AnnotationUtil.isAnnotation(sendPathLine,getControlSystem(),annoDicts)){
                String planText = AnnotationUtil.removeAnnotation(getControlSystem(),sendPathLine,annoDicts);
                //String planTextRepl = StringUtils.replace(planText,"\\","/");
                if(!planText.equals(sendPath) && !planText.equals(sendPathRepl)) {
                    //非路径的注释,插入
                    finishedStream = FileContentUtil.insertLine(byteInputStream,annotationProperties.getSendPathLineIndex(),sendPathAnnotation);
                }else{
                    //是路径,不处理直接返回原输入流
                    finishedStream = inputStream;
                }
                //finishedStream = FileContentUtil.replaceAtLine(byteInputStream,annotationProperties.getSendPathLineIndex(),sendPathAnnotation);
            }else{
                finishedStream = FileContentUtil.insertLine(byteInputStream,annotationProperties.getSendPathLineIndex(),sendPathAnnotation);
            }
@@ -76,12 +82,7 @@
            //非注释,插入状态
            insAfterProgramName = FileContentUtil.insertLine(byteStream,annotationProperties.getProgramNameLineIndex(),proNameAnnotation);
        }
        /*
        if(isAnnotation){
            insAfter = FileContentUtil.replaceAtLine(bais, annotationProperties.getProgramNameLineIndex(),proNameLine);
        }else{
            insAfter = FileContentUtil.insertLine(bais, annotationProperties.getProgramNameLineIndex(),proNameLine);
        }*/
        return insAfterProgramName;
    }
@@ -95,18 +96,7 @@
            //1加入发送路径的注释
            InputStream insAfterSetSendDir = putSendPathAnnotation(annoData.getSendPath(),byteInputStream,annoDicts);
            /*
            String statusLine = FileContentUtil.readLineAt(insAfterSetSendDir,annotationProperties.getStatusLineIndex());//状态注释
            insAfterSetSendDir.reset();
            //加入状态注释行
            InputStream insAfterStatus;
            String statusAnnotation = AnnotationUtil.generateAnnotation(annoData.getProgramStatus(),getControlSystem(),annoDicts);//注释后的状态文本
            if(AnnotationUtil.isAnnotation(statusLine,getControlSystem(),annoDicts)){
                insAfterStatus = FileContentUtil.replaceAtLine(insAfterSetSendDir,annotationProperties.getStatusLineIndex(),statusAnnotation);
            }else{
                insAfterStatus = FileContentUtil.insertLine(insAfterSetSendDir,annotationProperties.getStatusLineIndex(),statusAnnotation);
            }*/
            InputStream insAfterStatus = putStatusAnnotation(annoData.getProgramStatus(),insAfterSetSendDir,annoDicts);
            if(StringUtils.isNotBlank(annoData.getDeviation())){
@@ -208,9 +198,11 @@
            String statusText = AnnotationUtil.removeAnnotation(this.getControlSystem(),statusLine,annoDictList);
            if(AnnotationUtil.isStatusContent(statusText)){
                data.setProgramStatus(statusText);
            }
            data.setDeviation(AnnotationUtil.removeAnnotation(this.getControlSystem(),devLine,annoDictList));
                if(AnnotationUtil.LG.equals(statusText)) {
                    data.setDeviation(AnnotationUtil.removeAnnotation(this.getControlSystem(), devLine, annoDictList));
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/programannotation/AnnotationProcessor.java
@@ -27,5 +27,4 @@
     * @return è¯»å–的数据
     */
    AnnotationData readAnnotationData(InputStream inputStream);
    //InputStream puttSendPathAnnotation(String programName, InputStream inputStream) throws IOException;
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/programannotation/AnnotationUtil.java
@@ -18,7 +18,7 @@
    public static final String SQ = "SQ";
    public static final String GH = "GH";
    public static final String LG = "LG";
    public static final String TMP = "TMP";
    /**
     * åˆ¤æ–­æ˜¯å¦æ˜¯æ³¨é‡Šè¡Œ
     * @param text æ–‡å­—
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/programannotation/DefaultProcessor.java
@@ -1,29 +1,94 @@
package org.springblade.mdm.program.service.programannotation;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springblade.mdm.program.service.ProgramAnnotationService;
import org.springblade.mdm.utils.FileContentUtil;
import org.springblade.system.pojo.entity.DictBiz;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Component("defaultProcessor")
public class DefaultProcessor extends AbstractProcessor{
    @Autowired
    private ProgramAnnotationService programAnnotationService;
    //@Autowired
    //private ProgramAnnotationService programAnnotationService;
    private String controlSystem;
    @Override
    public InputStream putAnnotation(AnnotationData annoData, InputStream inputStream) throws IOException {
        InputStream insAfter = super.putFilenameAnnotation(annoData.getFilename(),inputStream);
        InputStream insAfter = putFilenameAnnotation(annoData.getFilename(),inputStream);
        return super.putAnnotation(annoData, insAfter);
    }
    @Override
    public InputStream putFilenameAnnotation(String fileName, InputStream inputStream) throws IOException {
        List<DictBiz> annoDicts = getAnnotationDictList();
        ByteArrayInputStream byteStream = new ByteArrayInputStream(IOUtils.toByteArray(inputStream));
        String programNameLine = FileContentUtil.readLineAt(byteStream, annotationProperties.getProgramNameLineIndex());
        byteStream.reset();
        boolean isAnnotation = AnnotationUtil.isAnnotation(programNameLine,this.getControlSystem(),annoDicts);
        InputStream insAfterProgramName;
        //加入程序名注释行
        String programNameStr = genProgramNameText(FilenameUtils.removeExtension(fileName));
        String proNameAnnotation =  AnnotationUtil.generateAnnotation(programNameStr,getControlSystem(),annoDicts);
        if(isAnnotation){//是注释
            //提取注释内文字
            String programName = FilenameUtils.removeExtension(fileName);
            String progNameLineWithoutAnno = AnnotationUtil.removeAnnotation(this.getControlSystem(),programNameLine,annoDicts);
            if(!isCurrentProgramNameAnnotation(progNameLineWithoutAnno,programName)) {
                //注释不是程序名(工艺员自己写的注释),插入
                insAfterProgramName = FileContentUtil.insertLine(byteStream,annotationProperties.getProgramNameLineIndex(),proNameAnnotation);
            }else{
                //是程序名注释,不处理,返回原stream
                insAfterProgramName =  byteStream;
            }
        }else{
            //非注释,插入状态
            insAfterProgramName = FileContentUtil.insertLine(byteStream,annotationProperties.getProgramNameLineIndex(),proNameAnnotation);
        }
        return insAfterProgramName;
    }
    /**
     * æ˜¯å¦ä¸ºå½“前程序的注释
     * @param lineTextWithoutAnno æ³¨é‡Šè¡Œçš„æ–‡å­—
     * @param programName ç¨‹åºåç§°
     * @return æ˜¯å¦æ—¶ç¨‹åºæ³¨é‡Šè¡Œï¼Œå¦‚果与当前程序名匹配则true
     */
    boolean isCurrentProgramNameAnnotation(String lineTextWithoutAnno,String programName){
        Pattern pattern = Pattern.compile("^\\((.+)\\)");
        Matcher matcher = pattern.matcher(lineTextWithoutAnno);
        if(matcher.find()){
            String findText = matcher.group(1);
            return findText.equals(programName);
        }else{
            return false;
        }
    }
    /**
     * ç”Ÿæˆç¨‹åºåæˆçš„行 åŠ å…¥ (pname=[程序名称])
     * @param proggramName
     * @return æŠ¥è£…后的程序名称
     */
    private String genProgramNameText(String proggramName) {
        return String.format("(%s)",proggramName);
    }
    @Override
    public void setControlSystem(String controlSystemDictVal) {
blade-service/blade-mdm/src/main/java/org/springblade/mdm/test/MyTestController.java
@@ -8,11 +8,13 @@
import jakarta.xml.soap.SOAPException;
import jakarta.xml.ws.WebServiceContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.SpringUtil;
import org.springblade.mdm.basesetting.machine.entity.Machine;
import org.springblade.mdm.commons.service.InternalEmailService;
import org.springblade.mdm.commons.service.MachineDirTranslator;
import org.springblade.mdm.flow.entity.MesSync;
import org.springblade.mdm.flow.excution.events.CureFinishedEvent;
import org.springblade.mdm.flow.service.MesSyncService;
@@ -73,6 +75,9 @@
    private NcNodeHisService nodeHisService;
    @Autowired
    private FileSendRecordService fileSendRecordService;
    @Autowired
    private MachineDirTranslator transDir;
    /**
     * æ–°å¢ž
     */
@@ -195,4 +200,15 @@
        return optFile.get();
    }
    @GetMapping("/transdir")
    public Object transdir(String path){
        return transDir.trans(path);
    }
    @GetMapping("/sendfile")
    public Object sendfile() throws IOException {
        FileUtils.copyFile(new java.io.File("d:/a.txt"),(new java.io.File("\\\\192.168.233.2\\Workshop\\testMachine\\at.txt")));
        return "OK";
    }
}
blade-service/blade-mdm/src/test/java/org/springblade/mdm/gkw/programnode/vo/ProgramNameVOTest.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,27 @@
package org.springblade.mdm.gkw.programnode.vo;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class ProgramNameVOTest {
    @Test
    public void testLgSerial(){
        ProgramNameVO vo = new ProgramNameVO();
        vo.setLgPart(null);
        Assertions.assertNull(vo.lgSerial());
        vo.setLgPart("");
        Assertions.assertNull(vo.lgSerial());
        vo.setLgPart("X1");//非Px结尾
        Assertions.assertNull(vo.lgSerial());
        vo.setLgPart("P1");
        Assertions.assertEquals("1",vo.lgSerial());
        vo.setLgPart("p2");//小写p,也应该可以
        Assertions.assertEquals("2",vo.lgSerial());
    }
}
blade-service/blade-mdm/src/test/java/org/springblade/mdm/program/service/programannotation/DefaultProcessorTest.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
package org.springblade.mdm.program.service.programannotation;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class DefaultProcessorTest {
    @Test
    public void testIsCurrentProgramNameAnnotation(){
        DefaultProcessor processor = new DefaultProcessor();
        String programName = "CP3-1-1-1";
        boolean result = processor.isCurrentProgramNameAnnotation("{NOTeprogram}",programName);
        Assertions.assertFalse(result);
        result = processor.isCurrentProgramNameAnnotation("(CP3-1-1-1)",programName);
        Assertions.assertTrue(result);
    }
}
blade-service/blade-mdm/src/test/java/org/springblade/mdm/utils/ProgramFileNameParserTest.java
@@ -47,7 +47,6 @@
        Assertions.assertEquals("CS",vo.getDrawingNo());
        Assertions.assertEquals("无",vo.getProcessEdition());
        ProgramNameVO pnmame1 = ProgramFileNameParser.parseProgramName("CP3-2-1-无-1-1.txt");
        Assertions.assertEquals("无",pnmame1.getProcessEdition());
    }