package org.springblade.mdm.task; import lombok.extern.slf4j.Slf4j; import org.springblade.mdm.basesetting.machine.entity.Machine; import org.springblade.mdm.basesetting.machine.service.MachineService; 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.machinefile.service.FileSendRecordService; import org.springblade.mdm.machinefile.service.MachineFileService; import org.springblade.mdm.utils.FileContentUtil; import org.springblade.mdm.utils.ProgramFileNameParser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; import java.time.LocalDateTime; import java.util.Date; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; /** * 机床回传rec文件夹内文件异常检查 */ @Slf4j @Component @EnableScheduling public class ReceiveDirCheckTask { @Autowired private MachineFileService machineFileService; @Autowired private MachineService machineService; @Autowired private ParamService paramService; @Autowired private FileSendRecordService fileSendRecordService; /** * 文件默认保存小时数,0不限制 */ private static final int DEFAULT_HOUR = 0; // 每5秒执行一次 //@Scheduled(fixedRate = 1000000) //@Scheduled(cron = "0 1 0 * * ?") // 每天上午0点1分执行 //@Scheduled(cron = "0 */3 * * * ?") //@Scheduled(cron = "0 15 19 * * ?") //test //@Scheduled(cron = "${task.cron.machine_file_scan}") @Scheduled(cron = "${task.cron.machine_rec_check:0 */10 * * * ?}") public void execute() { String networkType = paramService.getParamValue(ParamService.NETWORK_TYPE,ParamService.NETWORK_TYPE_SHEMI); if(!ParamService.NETWORK_TYPE_SHEMI.equals(networkType)){ //非涉密网,才扫描目录文件 checkFiles(); } } /** * 扫描数据库记录,超时则移动文件 */ public void checkFiles() { List machines = machineService.getEnableMachines(); for (Machine machine : machines) { List recFiles = this.machineFileService.lambdaQuery() .eq(MachineFile::getDirType,MachineFile.DIR_TYPE_REC) .eq(MachineFile::getMachineCode,machine.getCode()).list(); for(MachineFile machineFile : recFiles){ try { checkFile(machineFile, recFiles,machine); }catch(Exception e){ log.error("检查rec文件失败:"+machineFile.getName(),e); } } } } /** * 文件移动到temp * @param machineFile */ private void checkFile(MachineFile machineFile,List allFilesInDir,Machine machine) throws IOException { String srcFilepath = MachineFileService.getBasePath(machine,machineFile.getDirType())+ File.separator+machineFile.getName(); Path source = Paths.get(srcFilepath); if(!source.toFile().exists()){ return; } try(InputStream fileIns = Files.newInputStream(Paths.get(srcFilepath));) { if(!FileContentUtil.isTextFile(fileIns)){ //非文本 machineFile.setExceptionType(MachineFile.EXCEPTION_NOT_TEXT); }else{ ProgramNameVO progNameVO = ProgramFileNameParser.parseProgramName(machineFile.getName()); if(!progNameVO.isValidFilename()){ machineFile.setExceptionType(MachineFile.EXCEPTION_BAD_FILENAME); }else { String prefix = progNameVO.logicProgramName()+"-"; long matchCount = allFilesInDir.stream().filter(file -> file.getName().startsWith(prefix)).count(); if(matchCount != progNameVO.getSegmentCount()){//文件段数缺失 machineFile.setExceptionType(MachineFile.EXCEPTION_LOST_FILES); }else{ //检查是否匹配下发记录的段数 //正负3秒作为查询时间 Date beginTime = new Date(machineFile.getFileCreateTime().getTime()-3000); Date endTime = new Date(machineFile.getFileCreateTime().getTime()+3000); Optional optFile = fileSendRecordService.lambdaQuery() .eq(FileSendRecord::getMachineCode,machineFile.getMachineCode()) .likeRight(FileSendRecord::getName,prefix).between(FileSendRecord::getCreateTime,beginTime,endTime).oneOpt(); if(optFile.isPresent()){ //确实下发过,比对总段数是否相同 FileSendRecord sendFile = optFile.get(); ProgramNameVO sendProgNameVO = ProgramFileNameParser.parseProgramName(sendFile.getName()); if(progNameVO.getSegmentCount() != sendProgNameVO.getSegmentCount()){ //段数不匹配 machineFile.setExceptionType(MachineFile.EXCEPTION_NOT_MATCH_SEND); }else{ machineFile.setExceptionType(MachineFile.EXCEPTION_OK); } } } } } machineFileService.updateById(machineFile); } } }