yangys
2025-09-22 4d014f9795032d7ef02bcc8050384f7cca1738a8
优化文件名检查;zip文件解析加入多编码检验
已修改7个文件
137 ■■■■■ 文件已修改
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/gkw/programnode/vo/ProgramNameVO.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/DNCSendBackService.java 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/utils/FileContentUtil.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/test/java/org/springblade/mdm/commons/contants/RegExpConstantsTest.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/test/java/org/springblade/mdm/program/service/DNCSendBackServiceTest.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/test/java/org/springblade/mdm/utils/ProgramFileNameParserTest.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
blade-service/blade-mdm/src/main/java/org/springblade/mdm/commons/contants/RegExpConstants.java
@@ -7,7 +7,7 @@
    /**
     * 程序文件名 正则
     */
    public static final Pattern PROGRAM_FILE_PATTERN = Pattern.compile("^([\\w\\-]+)-([0-9]+)-([0-9a-zA-Z]+)-(\\d+)-(\\d+)-?([Pp]\\d*)?(\\.*[a-zA-Z]*)$");
    public static final Pattern PROGRAM_FILE_PATTERN = Pattern.compile("^([\\w\\-]+)-([0-9a-zA-Z]+)-([0-9a-zA-Z]+)-(\\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("([\\w\\-]+)-[0-9a-zA-Z]+-[0-9a-zA-Z]+");
blade-service/blade-mdm/src/main/java/org/springblade/mdm/gkw/programnode/vo/ProgramNameVO.java
@@ -47,6 +47,6 @@
        return StringUtils.isNotBlank(this.drawingNo)
            && StringUtils.isNotBlank(this.processNo)
            && StringUtils.isNotBlank(this.processEdition)
            && this.segmentCount > 0 && this.segmentNo > 0;
            && this.segmentCount > 0 && this.segmentNo > 0 && this.segmentCount>=this.segmentNo;
    }
}
blade-service/blade-mdm/src/main/java/org/springblade/mdm/program/service/DNCSendBackService.java
@@ -37,11 +37,13 @@
import org.springblade.mdm.utils.ProgramFileNameParser;
import org.springblade.mdm.utils.ZipTextFileContentUtil;
import org.springblade.system.pojo.entity.DictBiz;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
@@ -51,6 +53,7 @@
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
/**
 * DNC回传文件处理服务
@@ -59,23 +62,27 @@
 */
@Slf4j
@Service
@AllArgsConstructor
public class DNCSendBackService extends BizServiceImpl<NcProgramExchangeMapper, NcProgramExchange> {
    private final CureFlowService cureFlowService;
    private final QinzheFgbService qinzheFbgService;
    private final NcNodeService ncNodeService;
    private final OssTemplate ossTemplate;
    private final BladeRedis bladeRedis;
    private final FlowCommonService flowCommonService;
    private final DncBackFileService dncBackFileService;
    private final MachineService machineService;
    private final ParamService paramService;
    @Autowired
    private CureFlowService cureFlowService;
    @Autowired
    private NcNodeService ncNodeService;
    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private BladeRedis bladeRedis;
    @Autowired
    private FlowCommonService flowCommonService;
    @Autowired
    private DncBackFileService dncBackFileService;
    @Autowired
    private MachineService machineService;
    /**
     * 偏离单文件末尾的模式: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();
    }
@@ -112,19 +119,47 @@
    /**
     * 从压缩包 解析回传程序列表,这里解析目录即可,目录就是程序包名
     * @param inputStream 压缩包输入流
     * @return 文件操作异常
     */
    List<DncSendBackData> parseProgramListFromZip(InputStream inputStream) throws IOException {
        List<DncSendBackData> result = null;
        ByteArrayInputStream byteInsStream = new ByteArrayInputStream(FileUtil.copyToByteArray(inputStream));
        for (String encoding : encodings) {
            try {
                result = parseProgramListByCharset(byteInsStream,Charset.forName(encoding));
                log.error("使用编码 {} 解析成功 ",encoding);
                break;
            } catch (Exception e) {
                byteInsStream.reset();
                log.error("使用编码 {} 解析失败: ",encoding,e);
            }
        }
        if(result != null) {
            return result;
        }else{
            return Collections.emptyList();
        }
    }
    /**
     * 从压缩包 解析回传程序列表,这里解析目录即可,目录就是程序包名
     * @param inputStream 压缩包输入流
     * @return 回传程序列表
     * @throws IOException 文件操作异常
     */
    List<DncSendBackData> parseProgramListFromZip(InputStream inputStream) throws IOException {
    List<DncSendBackData> parseProgramListByCharset(InputStream inputStream,Charset charset) throws IOException {
        List<DncSendBackData> list = new ArrayList<>();
        Path tempZipFile = createTempFile(inputStream);
        List<String> fileEntryNameList = new ArrayList<>();
        List<String> dirEntryNameList = new ArrayList<>();//程序包名+工序版次 作为文件夹名
        try (ZipFile zipFile = new ZipFile(tempZipFile.toFile())) {
        ZipEntry entry;
        try (ZipFile zipFile = new ZipFile(tempZipFile.toFile(),charset)) {
            Enumeration<? extends ZipEntry> zipEntries = zipFile.entries();
            ZipEntry entry;
            //获取所有的entry名称
            while (zipEntries.hasMoreElements()) {
                entry = zipEntries.nextElement();
@@ -208,36 +243,7 @@
        return list;
    }
    /**
     * 修复程序包名,fanuc不识别下划线,下发时转换为了-,这里需要确认。应该是从导出记录中查找修改后的包名,但是现场编制的没有咋办?
     * @param packageNameInZip
     * @return
     */
    /*
    private String fixProgramPackageName(String packageNameInZip) {
        Matcher matcher = RegExpConstants.PROGRAM_PACKAGE_PATTERN.matcher(packageNameInZip);
        String drawingNo = null;
        if(matcher.find()) {
            drawingNo = matcher.group(1);
        }
        String processNo = null;
        if(matcher.find()) {
            processNo = matcher.group(2);
        }
        String processEdition = null;
        if(matcher.find()) {
            processEdition = matcher.group(3);
        }
        if(drawingNo != null && processNo != null && processEdition != null) {
            if(drawingNo.contains("_")) {
            }
        }
        return packageNameInZip;
    }
    */
    /**
     * 入库回传文件,并启动固化流程
@@ -257,7 +263,6 @@
        cureFlowService.startCureNew(pkgIdFileMap);
    }
    /**
     * 处理回传文件
     * @param ossFileName
@@ -268,12 +273,36 @@
    private Map<Long, List<FlowProgramFile>> dealWithBackFile(String ossFileName, List<Long> acceptIdList) throws IOException{
        Map<Long, List<FlowProgramFile>> pkgIdFileMap = new HashMap<>();
        //ByteArrayInputStream byteInsStream = new ByteArrayInputStream(FileUtil.copyToByteArray(inputStream));
        for (String encoding : encodings) {
            try {
                pkgIdFileMap = dealWithBackFileWithCharset(ossFileName,acceptIdList,Charset.forName(encoding));
                log.error("使用编码 {} 解析成功 ",encoding);
                break;
            } catch (Exception e) {
                //byteInsStream.reset();
                log.error("使用编码 {} 解析失败: ",encoding,e);
            }
        }
        return pkgIdFileMap;
    }
    /**
     * 处理回传文件
     * @param inputStream
     * @param acceptIdList
     * @return
     * @throws IOException
     */
    private Map<Long, List<FlowProgramFile>> dealWithBackFileWithCharset(String ossFileName, List<Long> acceptIdList,Charset charset) throws IOException{
        Map<Long, List<FlowProgramFile>> pkgIdFileMap = new HashMap<>();
        InputStream inputStream = this.ossTemplate.statFileStream(ossFileName);
        Path tempZipFile = createTempFile(inputStream);
        List<String> entryNameList = new ArrayList<>();
        ZipEntry entry;
        try (java.util.zip.ZipFile zipFile = new java.util.zip.ZipFile(tempZipFile.toFile())) {
        try (java.util.zip.ZipFile zipFile = new java.util.zip.ZipFile(tempZipFile.toFile(),charset)) {
            Enumeration<? extends ZipEntry> entries = zipFile.entries();
            while(entries.hasMoreElements()) {
                entry = entries.nextElement();
blade-service/blade-mdm/src/main/java/org/springblade/mdm/utils/FileContentUtil.java
@@ -104,11 +104,10 @@
        byte[] buffer = new byte[2048];
        try {
            int actRead = inputStream.read(buffer);
            detector.handleData(buffer, 0, actRead);
            //识别结束必须调用这个方法
            detector.dataEnd();
            detector.reset();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
blade-service/blade-mdm/src/test/java/org/springblade/mdm/commons/contants/RegExpConstantsTest.java
@@ -64,6 +64,9 @@
        m = RegExpConstants.PROGRAM_PACKAGE_PATTERN.matcher("CP3X296-A-B");
        Assertions.assertTrue(m.find());
        m = RegExpConstants.PROGRAM_PACKAGE_PATTERN.matcher("CS-A-1-1-1-P1.nc");
        Assertions.assertTrue(m.find());
        m = RegExpConstants.PROGRAM_PACKAGE_PATTERN.matcher("C_P3X296-A-B");
blade-service/blade-mdm/src/test/java/org/springblade/mdm/program/service/DNCSendBackServiceTest.java
@@ -5,6 +5,7 @@
public class DNCSendBackServiceTest {
    @Test
    public void testParseZip(){
        DNCSendBackService service = new DNCSendBackService();
    }
}
blade-service/blade-mdm/src/test/java/org/springblade/mdm/utils/ProgramFileNameParserTest.java
@@ -36,4 +36,11 @@
        Assertions.assertEquals("9",vo.getProcessNo());
        Assertions.assertEquals("B",vo.getProcessEdition());
    }
    @Test
    public void testIssValidFilename() {
        ProgramNameVO vo = ProgramFileNameParser.parseProgramName("CS-A-1-1-1-P1.nc");
        Assertions.assertTrue(vo.isValidFilename());
    }
}