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);
|
}
|
}
|
}
|