EquipAlarmJob.java 16.2 KB
package com.skua.modules.quartz;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.skua.modules.alarmtmp.entity.AlarmCustomRuleRepository;
import com.skua.modules.alarmtmp.entity.AlarmRecordHistory;
import com.skua.modules.alarmtmp.entity.AlarmRuleConfigPublicTab;
import com.skua.modules.alarmtmp.entity.AlarmRuleLevelConfig;
import com.skua.modules.alarmtmp.mapper.AlarmRuleConfigMapper;
import com.skua.modules.alarmtmp.service.AlarmRecordHistoryService;
import com.skua.modules.alarmtmp.service.AlarmRuleLevelConfigService;
import com.skua.modules.alarmtmp.service.IAlarmCustomRuleRepositoryService;
import com.skua.modules.alarmtmp.service.IAlarmRuleConfigPublicTabService;
import com.skua.modules.alarmtmp.vo.AlarmRuleConfigAndLevelVO;
import com.skua.modules.alarmtmp.vo.SystemNoticeVO;
import com.skua.core.util.ConvertUtils;
import com.skua.core.util.DateUtils;
import com.skua.modules.system.datestandard.service.ISysMonitorMetricInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import com.skua.modules.util.SystemNoticeUtils;
import cn.hutool.json.JSONUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @program: skboot
 * @description: 设备报警
 * @author: xie chao
 * @create: 2020-11-02 13:48
 */
@Slf4j
@Component
public class EquipAlarmJob implements Job {

    @Autowired
    private AlarmRecordHistoryService alarmRecordHistoryService;
    @Autowired
    private SystemNoticeUtils systemNoticeUtils;
    @Autowired
    private ISysMonitorMetricInfoService sysMonitorMetricInfoService; 
    
    @Autowired
    private AlarmRuleConfigMapper alarmRuleConfigMapper;
    @Autowired
    private IAlarmCustomRuleRepositoryService alarmCustomRuleRepositoryService;
    @Autowired
    private IAlarmRuleConfigPublicTabService alarmRuleConfigPublicTabService;
    @Autowired
    private AlarmRuleLevelConfigService alarmRuleLevelConfigService;

    private static String prefix = "【金控数矿】";
    //private static String prefix = "";
    private static String departNameTemplete = "${departName}";
    private static String contentTemplete = "${alarmParamName}";
    private static String suffix = "故障,请处理!";

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {

        try {
            log.info("设备报警任务开始");
            //查询pg设备警报
            List<AlarmRuleConfigAndLevelVO> excessAlarmPgList = checkPgExcessAlarm();
            if (excessAlarmPgList != null && excessAlarmPgList.size() > 0) {
            	//获取设备信号报警类别
            	QueryWrapper<AlarmRuleConfigPublicTab> alarmRuleConfigPublicTabQueryWrapper = new QueryWrapper<AlarmRuleConfigPublicTab>();
            	alarmRuleConfigPublicTabQueryWrapper.eq("java_bean_tag", "equipAlarmJob");
            	AlarmRuleConfigPublicTab alarmRuleConfigPublicTab = alarmRuleConfigPublicTabService.getOne(alarmRuleConfigPublicTabQueryWrapper);
                //将故障报警恢复的状态修改成正常状态
                updStatus(excessAlarmPgList,alarmRuleConfigPublicTab.getId());
                sendMessage(excessAlarmPgList);
            }
            log.info("设备报警任务结束");
        } catch (Exception e) {
        	e.printStackTrace();
            log.info("设备报警任务异常:" + e);
        }

    }

    /**
     * <pre>
     * 	更新已恢复运行的设备故障报警状态
     * </pre>
     * @param excessAlarmPgList	设备信号故障报警列表
     * @param alarmRuleType		设备信号故障报警类别
     * @author Li Yuanyuan, 2023年12月28日 下午7:42:31
     * @Description: TODO(这里描述这个方法的需求变更情况)
     */
    private void updStatus(List<AlarmRuleConfigAndLevelVO> excessAlarmPgList,String alarmRuleType) {
        QueryWrapper<AlarmRecordHistory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("alarm_rule_type", alarmRuleType);
        queryWrapper.eq("handle_status", 0);
        queryWrapper.orderByDesc("record_time");
        List<AlarmRecordHistory> list = alarmRecordHistoryService.list(queryWrapper);
        if (list != null && list.size() > 0) {
            //遍历
            Set<String> set = new HashSet<>();
            excessAlarmPgList.forEach(v -> set.add(v.getAlarmProgramCode()));
            List<AlarmRecordHistory> result = Lists.newArrayList();
            list.forEach(v -> {
                String alarmParamCode = v.getAlarmParamCode();
                if (!set.contains(alarmParamCode)) {
                    AlarmRecordHistory alarmRecordHistory = new AlarmRecordHistory();
                    alarmRecordHistory.setId(v.getId());
                    alarmRecordHistory.setHandleStatus(1);
                    alarmRecordHistory.setHandleUser("admin");
                    alarmRecordHistory.setHandleTime(DateUtils.getDate());
                    result.add(alarmRecordHistory);
                }
            });
            if (result != null && result.size() > 0) {
                alarmRecordHistoryService.updateBatchById(result);
            }
        }
    }


    /**
     * 判断pg数据库中超标的警报
     */
    public List<AlarmRuleConfigAndLevelVO> checkPgExcessAlarm() {

        //存放厂ID和指标的List集合
        Map<String, List<String>> departIndexCodeListMap = new HashMap<>();
        //查询报警配置表
        //List<NewAlarmRuleConfigVO> list = alarmRuleConfigService.getEquipAlarmInfo();
        List<AlarmRuleConfigAndLevelVO> alarmRuleConfigList = alarmRuleConfigMapper.getAlarmRuleConfigList("equipAlarmJob");
        
        //获取设备信号报警方案规则类别
        QueryWrapper<AlarmCustomRuleRepository> alarmRuleConfigQueryWrapper = new QueryWrapper<AlarmCustomRuleRepository>();
        alarmRuleConfigQueryWrapper.eq("bean_service_name", "equipAlarmJob");
        AlarmCustomRuleRepository alarmCustomRuleRepository = alarmCustomRuleRepositoryService.getOne(alarmRuleConfigQueryWrapper);
        //报警方案规则类别
        String alarmCustomRuleTypeTreepath = alarmCustomRuleRepository.getAlarmRuleTypeTreepath();
        //报警方案规则id
        String alarmRepositoryId = alarmCustomRuleRepository.getId();

        alarmRuleConfigList.forEach(v -> {
        	//向报警规则对象装入报警方案规则类别相关数据
        	String[] alarmCustomRuleTypeTreeArray = alarmCustomRuleTypeTreepath.split(",");
        	v.setAlarmCustomRuleTopType(alarmCustomRuleTypeTreeArray[0]);
        	//预留报警方案规则类别二级配置
        	//v.setAlarmCustomRuleSecondType(alarmCustomRuleTypeTreeArray[1]);
        	v.setAlarmCustomRuleType(alarmRepositoryId);
        	//预留报警方案id配置
        	//v.setAlarmCustomRuleId("");
        	v.setAlarmCustomRuleTypeTreepath(alarmCustomRuleTypeTreepath+","+alarmRepositoryId);
        	
        	//向报警报警规则对象装入报警类别相关数据
        	String alarmTypeTreePath = v.getAlarmRuleTypeTreepath();
       	 	String[] treeArray = alarmTypeTreePath.split(",");
            v.setAlarmRuleTopType(treeArray[0]);
            v.setAlarmRuleSecondType(treeArray[1]);
        	
        	//设备状态判定点位
            String alarmProgramCode = v.getAlarmProgramCode();
            if (StringUtils.isNotBlank(alarmProgramCode)) {
            	List<String> alarmProgramCodeList = departIndexCodeListMap.get(v.getDepartId());
                if (alarmProgramCodeList!=null&&alarmProgramCodeList.size()>0) {
                	alarmProgramCodeList.add(alarmProgramCode);
                } else {
                	alarmProgramCodeList = new ArrayList<String>();
                	alarmProgramCodeList.add(alarmProgramCode);
                	departIndexCodeListMap.put(v.getDepartId(), alarmProgramCodeList);
                }
            }
            //获取报警级别
            QueryWrapper<AlarmRuleLevelConfig> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("alarm_rule_id", v.getId());
            queryWrapper.eq("config_status", 1);
            List<AlarmRuleLevelConfig> alarmRuleLevelConfigList = alarmRuleLevelConfigService.list(queryWrapper);
            if(alarmRuleLevelConfigList!=null&&alarmRuleLevelConfigList.size()>0) {
            	v.setAlarmRuleLevelConfig(alarmRuleLevelConfigList.get(0));
            }
        });

        Map<String, Map<String, Map<String, Object>>> resultListMap = new HashMap<>();

        //按照机构获取设备状态
        Set<String> departIdKeySet = departIndexCodeListMap.keySet();
        for(String departId : departIdKeySet) {
        	List<String> indexCodeList = departIndexCodeListMap.get(departId);
        	Map<String, Map<String, Object>> handleIndexCodeToEquipmentStateMap = new HashMap<String,Map<String,Object>>();
        	if(indexCodeList!=null&&indexCodeList.size()>0) {
        		Map<String, Map<String, Object>> indexCodeToEquipmentStateMap = sysMonitorMetricInfoService.getEquipRunState(indexCodeList);
        		//过滤出故障设备
        		Set<String> indexCodeKeySet = indexCodeToEquipmentStateMap.keySet();
        		for(String indexCode : indexCodeKeySet) {
        			Map<String,Object> tempMap = indexCodeToEquipmentStateMap.get(indexCode);
        			//判定设备运行状态0停止/1运行/2故障
        			String equipmentState = ConvertUtils.getString(tempMap.get("value"));
        			if("2".equals(equipmentState)) {
        				handleIndexCodeToEquipmentStateMap.put(indexCode, tempMap);
        			}
        		}
        		resultListMap.put(departId, handleIndexCodeToEquipmentStateMap);
        	}
        }
        ///存放超标指标数据
        List<AlarmRuleConfigAndLevelVO> excessList = new ArrayList<>();
        alarmRuleConfigList.forEach(v -> {
            String alarmProgramCode = v.getAlarmProgramCode();
            if (StringUtils.isNotBlank(alarmProgramCode)) {
                //通过厂ID得到厂的实际所有报警指标的实际数值
            	Map<String, Map<String, Object>> mapList = resultListMap.get(v.getDepartId());
                if (!mapList.isEmpty()) {
                    mapList.forEach((key, value) -> {
                        //判断指标是否相等
                        if (alarmProgramCode.equals(key)) {
                            v.setTime(ConvertUtils.getString(value.get("time")));
                            excessList.add(v);
                            return;
                        }
                    });
                }
            }
        });
        return excessList;

    }


    /**
     * 判断是否需要发送短信和通知
     */
    public void sendMessage(List<AlarmRuleConfigAndLevelVO> alarmList) {
        String date = DateUtils.getDate("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<AlarmRecordHistory> alarmRecordHistoryList = new ArrayList<>();
        alarmList.forEach(alarmRuleConfigVO -> {
            String metricCode = alarmRuleConfigVO.getAlarmProgramCode();
            String metricName = alarmRuleConfigVO.getAlarmParamName();
            String departName = alarmRuleConfigVO.getDepartName();
            String departId = alarmRuleConfigVO.getDepartId();
            String content = "";

            content = contentTemplete.replace("${alarmParamName}", metricName);
            departName = departNameTemplete.replace("${departName}", departName);

            //查询短信上一条报警是否处理,未处理就不新增报警记录
            //TODO 先从数据库中获取,后期优化放redis中
            QueryWrapper<AlarmRecordHistory> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("depart_id", departId);
            queryWrapper.eq("alarm_param_code", metricCode);
            queryWrapper.eq("alarm_rule_type", alarmRuleConfigVO.getAlarmRuleType());
            queryWrapper.orderByDesc("record_time").last("limit 1");
            AlarmRecordHistory alarmRecordHistoryOne = alarmRecordHistoryService.getOne(queryWrapper);


            //如果没有上条记录或者处理状态(0:未处理,1:已处理)为已处理
            if ((alarmRecordHistoryOne == null || alarmRecordHistoryOne.getHandleStatus() == 1)) {
                AlarmRecordHistory alarmRecordHistory = new AlarmRecordHistory();
                AlarmRuleLevelConfig alarmRuleLevelConfig = alarmRuleConfigVO.getAlarmRuleLevelConfig();
                //手动创建UUID,用于报警自动送审
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");

                alarmRecordHistory.setId(uuid);
                alarmRecordHistory.setAlarmParamCode(metricCode);
                alarmRecordHistory.setAlarmParamName(metricName);
                alarmRecordHistory.setAlarmWorkName(metricName+"报警");
                alarmRecordHistory.setAlarmRuleLevelName(alarmRuleLevelConfig.getAlarmRuleLevelName());
                alarmRecordHistory.setAlarmRuleLevelId(alarmRuleLevelConfig.getId());
                alarmRecordHistory.setAlarmRuleType(alarmRuleConfigVO.getAlarmRuleType());

                try {
                    alarmRecordHistory.setRecordTime(simpleDateFormat1.parse(date));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                alarmRecordHistory.setDepartId(departId);
                alarmRecordHistory.setHandleStatus(0);
                alarmRecordHistory.setDelFlag(1);
                
                //添加报警类别数据
                alarmRecordHistory.setHandleMethon(alarmRuleConfigVO.getAlarmRecommend());
                alarmRecordHistory.setAlarmRuleTopType(alarmRuleConfigVO.getAlarmRuleTopType());
                alarmRecordHistory.setAlarmRuleSecondType(alarmRuleConfigVO.getAlarmRuleSecondType());
                alarmRecordHistory.setAlarmRuleTypeTreepath(alarmRuleConfigVO.getAlarmRuleTypeTreepath());
                //添加报警方案规则类别数据
                alarmRecordHistory.setAlarmCustomRuleTopType(alarmRuleConfigVO.getAlarmCustomRuleTopType());
                alarmRecordHistory.setAlarmCustomRuleSecondType(alarmRuleConfigVO.getAlarmCustomRuleSecondType());
                alarmRecordHistory.setAlarmCustomRuleType(alarmRuleConfigVO.getAlarmCustomRuleType());
                alarmRecordHistory.setAlarmCustomRuleTypeTreepath(alarmRuleConfigVO.getAlarmCustomRuleTypeTreepath());
                //构造报警指标数据json
                List<Map<String,Object>> indexDataList = new ArrayList<Map<String,Object>>();
                Map<String,Object> indexJsonMap = new HashMap<String,Object>();
                indexJsonMap.put("indexCode", metricCode);
                indexJsonMap.put("indexName", metricName);
                //预留设备id存储
                indexJsonMap.put("indexValue", "");
                indexDataList.add(indexJsonMap);
                alarmRecordHistory.setAlarmCustomIndexJsonData(JSONUtil.toJsonStr(indexDataList));
                
                ////${departName}在${date}时检测到设备${conent}故障,请处理!
                alarmRecordHistory.setAlarmContent("检测到设备" + content + suffix);
                alarmRecordHistory.setCreateBy("admin");
                alarmRecordHistory.setActualAvgValue("设备故障");
                
                alarmRecordHistoryList.add(alarmRecordHistory);

                //判断是否需要发送系统通知 (内容跟报警记录信息相同)
                if ("1".equals(alarmRuleLevelConfig.getIsSendNotice())) {
                    if (StringUtils.isNotBlank(alarmRuleLevelConfig.getAlarmNoticeRecipient())) {
                        SystemNoticeVO systemNoticeVO = new SystemNoticeVO(alarmRuleLevelConfig.getAlarmNoticeRecipient(),
                                alarmRuleConfigVO.getAlarmRuleLevelName(), prefix+departName + "在" + date + "时检测到设备" + content + suffix, departId, "4");
                        systemNoticeUtils.dealNoticeMessage(systemNoticeVO);
                    }
                }
            }

        });
        alarmRecordHistoryService.saveBatch(alarmRecordHistoryList);
    }
}