yangys
2025-09-22 0bdfd76339bb58be09927b8c2fe268175c3a7cc8
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package org.springblade.mdm.machinefile.service;
 
import com.qiniu.util.IOUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tool.utils.Func;
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.ParamService;
import org.springblade.mdm.gkw.programnode.vo.ProgramNameVO;
import org.springblade.mdm.machinefile.entity.FileSendRecord;
import org.springblade.mdm.machinefile.entity.MachineFile;
import org.springblade.mdm.program.entity.ProgramOnMachine;
import org.springblade.mdm.program.service.ProgramAnnotationService;
import org.springblade.mdm.program.service.ProgramOnMachineService;
import org.springblade.mdm.program.service.programannotation.*;
import org.springblade.mdm.utils.FileContentUtil;
import org.springblade.mdm.utils.ProgramFileNameParser;
import org.springblade.system.pojo.entity.DictBiz;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
 
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
 
@Slf4j
@Component
public class ReceiveFileCheckService {
    @Autowired
    private MachineFileService machineFileService;
    @Autowired
    private MachineService machineService;
    @Autowired
    private ProgramOnMachineService programOnMachineService;
    @Autowired
    private FileSendRecordService fileSendRecordService;
    @Autowired
    private AnnotationProcessorHelper annoProcessHelper;
    @Autowired
    private ProgramAnnotationService programAnnotationService;
 
    /**
     * 文件合法性检查
     * @param machineFile
     */
    @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();
        log.info("开始检查文件{}",srcFilepath);
        Path checkFilePath = Paths.get(srcFilepath);
        if(!checkFilePath.toFile().exists()){
            return;
        }
 
        AnnotationProperties annoProps = AnnotationProperties.getDefault();
        try(InputStream fileIns = Files.newInputStream(checkFilePath);) {
            int excepType = MachineFile.EXCEPTION_OK;
            ByteArrayInputStream byteStream = new ByteArrayInputStream(IOUtils.toByteArray(fileIns));
            if(!FileContentUtil.isTextFile(byteStream)){
                //非文本
                excepType = MachineFile.EXCEPTION_NOT_TEXT;
            }else{
                //Matcher matcher = RegExpConstants.PROGRAM_FILE_PATTERN.matcher(machineFile.getName());
                ProgramNameVO progNameVO =  ProgramFileNameParser.parseProgramName(machineFile.getName());
                boolean filenameValid = progNameVO.isValidFilename();
                if(!filenameValid){
                    excepType = MachineFile.EXCEPTION_BAD_FILENAME;
                }else {
 
                    String prefix = progNameVO.logicProgramName()+"-";
                    long matchCount = allFilesInDir.stream().filter(file -> file.getName().startsWith(prefix)).count();
                    if(matchCount != progNameVO.getSegmentCount()){//文件段数缺失
                        excepType = MachineFile.EXCEPTION_LOST_FILES;
                    }else{
                        //检查是否匹配下发记录的段数
                        //正负3秒作为查询时间
                        Date beginTime = new Date(machineFile.getFileCreateTime().getTime()-3000);
                        Date endTime = new Date(machineFile.getFileCreateTime().getTime()+3000);
                        Optional<FileSendRecord> optFile = fileSendRecordService.lambdaQuery()
                            .eq(FileSendRecord::getMachineCode,machineFile.getMachineCode())
                            .likeRight(FileSendRecord::getName,prefix).between(FileSendRecord::getCreateTime,beginTime,endTime).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;
                            }
                        }else{
                            matchSendRecord = false;
                        }
 
                        if(!matchSendRecord){//如果文件未下发过,查看是否有现场编程记录
                            byteStream.reset();
                            //TODO 下面这些应该都没有,因为时现场编程
                            String planStatusLine = AnnotationUtil.removeAnnotation(machine.getControlSystem(),FileContentUtil.readLineAt(byteStream,annoProps.getStatusLineIndex()),programAnnotationService.getAnnotionDictList());
 
                            String lgNo;//更改单号
                            if(AnnotationUtil.LG.equals(planStatusLine)) {//是更改单
                                String lgLine = FileContentUtil.readLineAt(byteStream, annoProps.getDeviationLineIndex());
                                lgNo = AnnotationUtil.removeAnnotation(machine.getControlSystem(), lgLine, programAnnotationService.getAnnotionDictList());
                            }else{
                                lgNo = null;
                            }
 
                            long progOnMachineCount = programOnMachineService.lambdaQuery()
                                .eq(ProgramOnMachine::getDrawingNo,progNameVO.getDrawingNo())
                                .eq(ProgramOnMachine::getProcessNo,progNameVO.getProcessNo())
                                .eq(ProgramOnMachine::getProcessEdition,progNameVO.getProcessEdition())
                                .eq(lgNo != null,ProgramOnMachine::getDeviation,lgNo)//TODO 临时更改单序号匹配
 
                                .eq(ProgramOnMachine::getMachineCode,machineFile.getMachineCode()).count();
 
                            if(progOnMachineCount == 0){//无现场编程记录
                                excepType = MachineFile.EXCEPTION_NOT_MATCH_RECORD;
                            }
 
                        }
                    }
                }
            }
            machineFile.setExceptionType(excepType);
            log.info("检查文件结束{}",srcFilepath);
            machineFileService.updateById(machineFile);
        }
    }
}