package com.skua.modules.quartz;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.flowable.engine.ProcessEngine;
import org.flowable.engine.ProcessEngines;
import org.flowable.engine.TaskService;
import org.flowable.identitylink.api.IdentityLink;
import org.flowable.identitylink.api.IdentityLinkType;
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.skua.common.report.CustomReportUtil;
import com.skua.core.context.SpringContextUtils;
import com.skua.core.util.ConvertUtils;
import com.skua.core.util.DateUtils;
import com.skua.core.util.chuanglan.HttpSenderMsg;
import com.skua.core.util.push.IPushService;
import com.skua.core.util.push.MessageEntity;
import com.skua.core.util.push.PushMessageFactory;
import com.skua.modules.alarmtmp.entity.AlarmCustomRuleConfig;
import com.skua.modules.alarmtmp.entity.AlarmMessageHistory;
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.service.AlarmMessageHistoryService;
import com.skua.modules.alarmtmp.service.AlarmRecordHistoryService;
import com.skua.modules.alarmtmp.service.AlarmRuleLevelConfigService;
import com.skua.modules.alarmtmp.service.IAlarmCustomRuleConfigService;
import com.skua.modules.alarmtmp.service.IAlarmRuleConfigPublicTabService;
import com.skua.modules.alarmtmp.vo.AlarmRuleConfigAndLevelVO;
import com.skua.modules.flow.business.service.FlowBusinessService;
import com.skua.modules.flow.business.service.IFlowService;
import com.skua.modules.flow.core.constant.ProcessConstant;
import com.skua.modules.flow.core.entity.BladeFlow;
import com.skua.modules.flow.core.utils.FlowUtil;
import com.skua.modules.flow.support.Kv;
import com.skua.modules.flow.utils.Func;
import com.skua.modules.system.datestandard.entity.SysMonitorMetricInfo;
import com.skua.modules.system.datestandard.service.ISysMonitorMetricInfoService;
import com.skua.modules.system.entity.SysDepart;
import com.skua.modules.system.entity.SysUser;
import com.skua.modules.system.service.IPgService;
import com.skua.modules.system.service.ISysDepartService;
import com.skua.modules.system.service.ISysUserService;
import com.skua.modules.util.SysMessagePushService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class SuddenDescentAlarmJob implements Job {

    @Autowired
    private AlarmRecordHistoryService alarmRecordHistoryService;
    @Autowired
    private AlarmMessageHistoryService alarmMessageHistoryService;
    @Autowired
    private AlarmRuleLevelConfigService alarmRuleLevelConfigService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IAlarmCustomRuleConfigService alarmCustomRuleConfigService;
    @Autowired
    private ISysMonitorMetricInfoService sysMonitorMetricInfoService;
    @Autowired
    private IPgService pgService;
    @Autowired
    private ISysDepartService sysDepartService;
    @Autowired
    private IAlarmRuleConfigPublicTabService alarmRuleConfigPublicTabService;
    
    @Autowired
    private IFlowService flowService;
    @Autowired
    private FlowBusinessService flowBusinessService;
    @Autowired
    private TaskService taskService;

    private static final String prefix = "【金控数矿】在";
    //private static final String prefix = "";
    private static final String departNameTemplete = "${departName}";
    private static final String suffix = ",请注意!";


    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        try {
            log.info("突降报警定时任务开始");
            DecimalFormat df = new DecimalFormat("#.##");
            //查询机构和ID对应关系的Map
            Map<String,String> departNameMap = new HashMap<>();
            List<SysDepart> sysDepartList = sysDepartService.list();
            for (SysDepart sysDepart : sysDepartList) {
                departNameMap.put(sysDepart.getId(),sysDepart.getDepartName());
            }
            //获取报警类别,已报警类别id为key,构造map对象
            Map<String,AlarmRuleConfigPublicTab> alarmTypeDictMap = new HashMap<String,AlarmRuleConfigPublicTab>();
        	List<AlarmRuleConfigPublicTab> alarmRuleConfigPublicTabList = alarmRuleConfigPublicTabService.list();
        	alarmRuleConfigPublicTabList.forEach(v->{
        		alarmTypeDictMap.put(v.getId(), v);
        	});
            
            //获取要报警指标
            QueryWrapper<AlarmCustomRuleConfig> alarmCustomRuleConfigQueryWrapper = new QueryWrapper<>();
            alarmCustomRuleConfigQueryWrapper.eq("alarm_rule_repository_id","1693925002376962050");
            List<AlarmCustomRuleConfig> alarmCustomRuleConfigList = alarmCustomRuleConfigService.list(alarmCustomRuleConfigQueryWrapper);
            //报警级别接收对象
            AlarmRuleLevelConfig alarmRuleLevelConfig = null;
            List<String> monitorDictCodeList = new ArrayList<>();
            //报警异常数据接收对象
            List<AlarmRuleConfigAndLevelVO> excessList = new ArrayList<AlarmRuleConfigAndLevelVO>();
            if(alarmCustomRuleConfigList!=null&&alarmCustomRuleConfigList.size()>0) {
                for (AlarmCustomRuleConfig alarmCustomRuleConfig : alarmCustomRuleConfigList) {
                    String alarmRuleJson = alarmCustomRuleConfig.getAlarmRuleJson();
                    String departId = alarmCustomRuleConfig.getDepartId();
                    String alarmIndexJson = alarmCustomRuleConfig.getAlarmIndexJson();
                    String alarmRuleId = alarmCustomRuleConfig.getId();
                    String alarmRuleType = alarmCustomRuleConfig.getAlarmRuleType();
                    String alarmRecommend = alarmCustomRuleConfig.getAlarmRecommend();
                    
                    String alarmRuleRepositoryTreepath = alarmCustomRuleConfig.getAlarmRuleRepositoryTreepath();
                    
                    //获取报警规则id对应的报警级别
                    QueryWrapper<AlarmRuleLevelConfig> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("alarm_rule_id", alarmRuleId);
                    alarmRuleLevelConfig = alarmRuleLevelConfigService.getOne(queryWrapper);
                    List<Map> alarmIndexList = JSON.parseArray(alarmIndexJson, Map.class);
                    alarmIndexList.forEach(alarmIndexMap ->{
                        monitorDictCodeList.add(ConvertUtils.getString(alarmIndexMap.get("id")));
                    });
                    List<String> configParamList = CustomReportUtil.getDataKey(alarmRuleJson);
                    double dynamicThreshold = Double.parseDouble(configParamList.get(0))/100; // 初始百分比阈值为50%
                    // 获取当前时间
                    Date endDate = new Date();
                    // 创建一个 Calendar 实例,并设置为当前时间
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(endDate);
                    // 将当前时间减去两分钟
                    calendar.add(Calendar.MINUTE, -10);
                    // 获取前两分钟的时间
                    Date startDate = calendar.getTime();
                    //String startTime = DateUtils.formatDate(startDate,"yyyy-MM-dd HH:mm:ss");
                    //String endTime = DateUtils.formatDate(endDate,"yyyy-MM-dd HH:mm:ss");
                    String startTime = String.valueOf(startDate.getTime()/1000);
                    String endTime = String.valueOf(endDate.getTime()/1000);
                    
                    for (String monitorDictCode : monitorDictCodeList) {
                        String msg = "";
                        AlarmRuleConfigAndLevelVO alarmRuleConfigAndLevelVO = new AlarmRuleConfigAndLevelVO();
                        QueryWrapper<SysMonitorMetricInfo> sysMonitorMetricInfoQueryWrapper = new QueryWrapper<>();
                        sysMonitorMetricInfoQueryWrapper.eq("metric_uid_tag",monitorDictCode);
                        SysMonitorMetricInfo sysMonitorMetricInfo = sysMonitorMetricInfoService.getOne(sysMonitorMetricInfoQueryWrapper);
                        String indexCode = sysMonitorMetricInfo.getId();
                        List<Map<String, Object>> list = pgService.queryAlarmInfoByXT(departId, indexCode, startTime, endTime);
//                        List<Map<String, Object>> list = new ArrayList<>();
//                        Map<String, Object> map1 = new HashMap<>();
//                        map1.put("v", 100);
//                        list.add(map1);
//                        Map<String, Object> map2 = new HashMap<>();
//                        map2.put("v", 40);
//                        list.add(map2);
//                        Map<String, Object> map3 = new HashMap<>();
//                        map3.put("v", 20);
//                        list.add(map3);
                        boolean comparisonEnded = false;
                        for (int i = 1; i < list.size(); i++) {
                            Map<String, Object> prevMap = list.get(i - 1);
                            Map<String, Object> currentMap = list.get(i);
                            double prevValue = ConvertUtils.getDouble(prevMap.get("v"),0.0);
                            double currentValue = ConvertUtils.getDouble(currentMap.get("v"),0.0);
                            if (currentValue < prevValue * (1-dynamicThreshold)) {
                                msg = sysMonitorMetricInfo.getMetricName()+"指标数值突然下降"+df.format((1-currentValue/prevValue)*100)+"%";
                                comparisonEnded = true;
                                break;
                            }
                        }
                        if (comparisonEnded){
                            //存在监测报警数据
                            alarmRuleConfigAndLevelVO.setAlarmRuleType(alarmRuleType);
                            alarmRuleConfigAndLevelVO.setDepartId(departId);
                            alarmRuleConfigAndLevelVO.setAlarmRuleLevelConfig(alarmRuleLevelConfig);
                            alarmRuleConfigAndLevelVO.setAlarmParamCode(monitorDictCode);
                            alarmRuleConfigAndLevelVO.setAlarmParamName(sysMonitorMetricInfo.getMetricName());
                            alarmRuleConfigAndLevelVO.setAlarmProgramCode(sysMonitorMetricInfo.getId());
                            alarmRuleConfigAndLevelVO.setAlarmParamUnit(sysMonitorMetricInfo.getMetricUnit());
                            alarmRuleConfigAndLevelVO.setDepartName(departNameMap.get(departId));
                            alarmRuleConfigAndLevelVO.setAlarmRuleType(alarmRuleType);
                            alarmRuleConfigAndLevelVO.setAlarmMsg(msg);
                            alarmRuleConfigAndLevelVO.setAlarmRecommend(alarmRecommend);
                            //设置报警类型
                        	alarmRuleConfigAndLevelVO.setAlarmRuleType(alarmRuleType);
                        	AlarmRuleConfigPublicTab alarmRuleConfigPublicTab = alarmTypeDictMap.get(alarmRuleType);
                        	if(alarmRuleConfigPublicTab!=null) {
                        		String alarmTypeTreePath = alarmRuleConfigPublicTab.getTreePath();
                            	String[] treeArray = alarmTypeTreePath.split(",");
                            	alarmRuleConfigAndLevelVO.setAlarmRuleTopType(treeArray[0]);
                            	alarmRuleConfigAndLevelVO.setAlarmRuleSecondType(treeArray[1]);
                            	alarmRuleConfigAndLevelVO.setAlarmRuleTypeTreepath(alarmTypeTreePath);
                        	}
                        	//设备报警方案规则类别
                            alarmRuleConfigAndLevelVO.setAlarmCustomRuleId(alarmRuleId);
                            String[] treeArray = alarmRuleRepositoryTreepath.split(",");
                            alarmRuleConfigAndLevelVO.setAlarmCustomRuleTopType(treeArray[0]);
                            //预留二级类别
                            //alarmRuleConfigAndLevelVO.setAlarmCustomRuleSecondType(treeArray[1]);
                            alarmRuleConfigAndLevelVO.setAlarmCustomRuleType(treeArray[treeArray.length-1]);
                            alarmRuleConfigAndLevelVO.setAlarmCustomRuleTypeTreepath(alarmRuleRepositoryTreepath);
                            
                            excessList.add(alarmRuleConfigAndLevelVO);
                        }
                    }
                }
            }else {
                log.info("报警规则初始参数未配置,请检查报警规则库,阈值报警规则");
                return;
            }
            sendMessage(excessList);
            log.info("突降报警定时任务结束");
        } catch (Exception e) {
            e.printStackTrace();
            log.error("突降报警定时任务异常" + e);
        }
    }


    /**
     * 判断是否需要发送短信和通知
     *
     * @param resultList
     */
    public void sendMessage(List<AlarmRuleConfigAndLevelVO> excessList) {
        //超标报警
        if (excessList != null && excessList.size() > 0) {
            excessList.forEach(alarmRuleAndAlarmRuleLevelVO -> {
                dealData(alarmRuleAndAlarmRuleLevelVO);
            });
        }
    }

    private void dealData(AlarmRuleConfigAndLevelVO alarmRuleAndAlarmRuleLevelVO) {
        String date = DateUtils.getDate("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
        SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //查询质量报警配置
        String departId = alarmRuleAndAlarmRuleLevelVO.getDepartId();
        AlarmRuleLevelConfig alarmRuleLevelConfig = alarmRuleAndAlarmRuleLevelVO.getAlarmRuleLevelConfig();
        Double alarmValue = alarmRuleAndAlarmRuleLevelVO.getValue();
        String alarmParamCode = alarmRuleAndAlarmRuleLevelVO.getAlarmProgramCode();
        String alarmParamName = alarmRuleAndAlarmRuleLevelVO.getAlarmParamName();
        String alarmRuleType = alarmRuleAndAlarmRuleLevelVO.getAlarmRuleType();
        String alarmRuleLevelName = alarmRuleLevelConfig.getAlarmRuleLevelName();
        String alarmRuleLevelConfigId = alarmRuleLevelConfig.getId();
        String content = alarmRuleAndAlarmRuleLevelVO.getAlarmMsg();
        String departName = departNameTemplete.replace("${departName}", alarmRuleAndAlarmRuleLevelVO.getDepartName());
        
        //查询短信上一条报警是否处理,未处理就不新增报警记录
        //TODO 先从数据库中获取,后期优化放redis中
        QueryWrapper<AlarmRecordHistory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("depart_id", departId);
        queryWrapper.eq("alarm_rule_type", alarmRuleType);
        queryWrapper.eq("alarm_param_code", alarmParamCode);
        queryWrapper.eq("alarm_rule_level_id", alarmRuleLevelConfigId);
        queryWrapper.orderByDesc("record_time").last("limit 1");
        AlarmRecordHistory alarmRecordHistoryOne = alarmRecordHistoryService.getOne(queryWrapper);
        //获取上次信息发送的时间,如果满足则发送
        //TODO 先从数据库中获取,后期优化方redis中
        QueryWrapper<AlarmMessageHistory> alarmMessageHistoryQueryWrapper = new QueryWrapper<>();
        alarmMessageHistoryQueryWrapper.eq("alarm_param_code", alarmParamCode);
        alarmMessageHistoryQueryWrapper.eq("alarm_send_type", "1");
        alarmMessageHistoryQueryWrapper.eq("alarm_rule_type", alarmRuleType);
        alarmMessageHistoryQueryWrapper.eq("alarm_rule_level_id", alarmRuleLevelConfigId);
        alarmMessageHistoryQueryWrapper.orderByDesc("alarm_send_time").last("limit 1");
        AlarmMessageHistory messageHistoryOne = alarmMessageHistoryService.getOne(alarmMessageHistoryQueryWrapper);
        Long nowDateLong = null;
        try {
            nowDateLong = simpleDateFormat1.parse(date).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //如果没有上条记录或者处理状态(0:未处理,1:已处理)为已处理
        if ((alarmRecordHistoryOne == null || alarmRecordHistoryOne.getHandleStatus() == 1)) {
            AlarmRecordHistory alarmRecordHistory = new AlarmRecordHistory();
            //手动创建UUID,用于报警自动送审
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            alarmRecordHistory.setId(uuid);
            alarmRecordHistory.setAlarmParamCode(alarmParamCode);
            alarmRecordHistory.setAlarmParamName(alarmParamName);
            alarmRecordHistory.setAlarmWorkName(alarmParamName+"报警");
            alarmRecordHistory.setAlarmRuleLevelName(alarmRuleLevelName);
            alarmRecordHistory.setAlarmRuleLevelId(alarmRuleLevelConfigId);
            try {
                alarmRecordHistory.setRecordTime(simpleDateFormat1.parse(date));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            alarmRecordHistory.setAlarmParamUnit(alarmRuleAndAlarmRuleLevelVO.getAlarmParamUnit());
            alarmRecordHistory.setDepartId(departId);
            //alarmRecordHistory.setActualAvgValue(alarmValue.toString());
            alarmRecordHistory.setHandleStatus(0);
            alarmRecordHistory.setDelFlag(1);
            alarmRecordHistory.setHandleMethon(alarmRuleAndAlarmRuleLevelVO.getAlarmRecommend());
            //${start}采集数据${conent}已超标,请注意!
            //alarmRecordHistory.setAlarmContent(prefix + date + "时" + departName + "" + content + suffix);
            alarmRecordHistory.setAlarmContent(content + suffix);
            alarmRecordHistory.setCreateBy("system");//标记为系统创建
            alarmRecordHistory.setHandleUser(alarmRuleLevelConfig.getAlarmWorkRecipient());
            //流程添加定义ID
            String processDefinitionId = flowBusinessService.getProcessDefinitionLastVersionId("productAlarmProcess");
            alarmRecordHistory.setProcessDefinitionId(processDefinitionId);
            
            //添加报警类型相关数据
            alarmRecordHistory.setAlarmRuleType(alarmRuleType);
            alarmRecordHistory.setAlarmRuleTopType(alarmRuleAndAlarmRuleLevelVO.getAlarmRuleTopType());
            alarmRecordHistory.setAlarmRuleSecondType(alarmRuleAndAlarmRuleLevelVO.getAlarmRuleSecondType());
            alarmRecordHistory.setAlarmRuleTypeTreepath(alarmRuleAndAlarmRuleLevelVO.getAlarmRuleTypeTreepath());
            //添加报警分类相关数据
            alarmRecordHistory.setAlarmCustomRuleId(alarmRuleAndAlarmRuleLevelVO.getAlarmCustomRuleId());
            alarmRecordHistory.setAlarmCustomRuleTopType(alarmRuleAndAlarmRuleLevelVO.getAlarmCustomRuleTopType());
            alarmRecordHistory.setAlarmCustomRuleSecondType(alarmRuleAndAlarmRuleLevelVO.getAlarmCustomRuleSecondType());
            alarmRecordHistory.setAlarmCustomRuleType(alarmRuleAndAlarmRuleLevelVO.getAlarmCustomRuleType());
            alarmRecordHistory.setAlarmCustomRuleTypeTreepath(alarmRuleAndAlarmRuleLevelVO.getAlarmCustomRuleTypeTreepath());
            
            alarmRecordHistoryService.save(alarmRecordHistory);


            //判断是否需要发送系统通知 (内容跟报警记录信息相同)
            if ("1".equals(alarmRuleLevelConfig.getIsSendNotice())) {
                if (StringUtils.isNotBlank(alarmRuleLevelConfig.getAlarmNoticeRecipient())) {
                    //义乌报警存在特定参数逻辑,不适用产品原有消息推送流程
                    SysMessagePushService sysMessagePushService = (SysMessagePushService) SpringContextUtils.getBean("sysMessagePushService");
                    sysMessagePushService.pushAlarmRecordMsgNoProcess(alarmRecordHistory);
                }
            }
            //判断是否需要自动发起工作流
            if("1".equals(alarmRuleLevelConfig.getIsFlowWork())) {
                if(StringUtils.isNotBlank(alarmRuleLevelConfig.getAlarmWorkRecipient())) {
                    //自动发起工作流 (改成到Mybatis拦截器里面去发起工单了)
                    //TODO 暂时注释掉流程发起逻辑
                    startProcessFlow("alarm_record_history","productAlarmProcess",Arrays.asList(alarmRuleLevelConfig.getAlarmWorkRecipient().split(",")),uuid,alarmRecordHistory);
                }
            }
        }
        //判断是否需要发送短信,1表示发送
        if (alarmRuleLevelConfig.getIsSendSms().equals("1")) {
            //判读是否在发送时间内
            Date allowStartDate = null;
            Date allowEndDate = null;
            Date nowDate = null;
            try {
                allowEndDate = simpleDateFormat.parse(alarmRuleLevelConfig.getSmsAllowSendTime().split("-")[1]);
                allowStartDate = simpleDateFormat.parse(alarmRuleLevelConfig.getSmsAllowSendTime().split("-")[0]);
                nowDate = simpleDateFormat.parse(date.substring(11, 16));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            //如果在发送时间内,则发送
            if (isEffectiveDate(nowDate, allowStartDate, allowEndDate)) {
                Date lastTime1 = null;
                //如果数据库没有上次时间,则设置一个默认时间
                if (messageHistoryOne != null) {
                    lastTime1 = messageHistoryOne.getAlarmSendTime();
                } else {
                    try {
                        lastTime1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2020-01-01 00:00:00");
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
                //判断是否满足报警频率,将两个时间转为毫秒
                Long lastTimeLong1 = lastTime1.getTime();
                if (nowDateLong - lastTimeLong1 > Double.parseDouble(alarmRuleLevelConfig.getSmsSendFrequency()) * 60 * 60 * 1000) {
                    List<String> userList = new ArrayList<>();
                    String alarmSmsRecipient = alarmRuleLevelConfig.getAlarmSmsRecipient();
                    //获取需要发送短信的手机号
                    if (StringUtils.isNotBlank(alarmSmsRecipient)) {
                        String[] userArr = alarmSmsRecipient.split(",");
                        for (int i = 0; i < userArr.length; i++) {
                            userList.add(userArr[i]);
                        }
                        QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<>();
                        sysUserQueryWrapper.in("id", userList);
                        List<SysUser> sysUserList = sysUserService.list(sysUserQueryWrapper);
                        //获取报警接收人的手机号
                        StringBuilder phoneStringBuilder = new StringBuilder();
                        for (int i = 0; i < sysUserList.size(); i++) {
                            phoneStringBuilder.append(",");
                            String phone1 = sysUserList.get(i).getPhone();
                            if (StringUtils.isNotBlank(phone1)) {
                                phoneStringBuilder.append(phone1);
                                //发送短信
                                HttpSenderMsg.sendMsg(prefix + date + "时" + departName + "采集数据" + content + suffix, phone1);
                                log.info("短信发送成功手机号:" + phone1 + ",内容:" + content);
                            }
                        }
                        String phone = phoneStringBuilder.toString().replaceFirst(",", "");
                        if (StringUtils.isNotBlank(phone)) {
                            //将发送的短信保存到数据库
                            AlarmMessageHistory alarmMessageHistory = new AlarmMessageHistory();
                            alarmMessageHistory.setAlarmSendUser(alarmSmsRecipient);
                            alarmMessageHistory.setAlarmSendPhone(phone);
                            try {
                                alarmMessageHistory.setAlarmSendTime(simpleDateFormat1.parse(date));
                            } catch (ParseException e) {
                                e.printStackTrace();
                            }
                            alarmMessageHistory.setAlarmSendContent(prefix + date + "时" + departName + "采集数据" + content + suffix);
                            alarmMessageHistory.setAlarmSendType("1");
                            alarmMessageHistory.setAlarmParamCode(alarmParamCode);
                            alarmMessageHistory.setAlarmParamName(alarmParamName);
                            alarmMessageHistory.setAlarmRuleLevelId(alarmRuleLevelConfigId);
                            alarmMessageHistory.setAlarmRuleType(alarmRuleType);
                            alarmMessageHistory.setAlarmParamUnit(alarmRuleAndAlarmRuleLevelVO.getAlarmParamUnit());
                            alarmMessageHistory.setDepartId(departId);
                            alarmMessageHistory.setActualAvgValue(ConvertUtils.getString(alarmValue));
                            alarmMessageHistoryService.save(alarmMessageHistory);
                        }
                    }
                }
            }
        }
    }
    public static boolean isEffectiveDate(Date nowTime, Date startTime, Date endTime) {
        if (nowTime.getTime() == startTime.getTime()
                || nowTime.getTime() == endTime.getTime()) {
            return true;
        }
        Calendar date = Calendar.getInstance();
        date.setTime(nowTime);
        Calendar begin = Calendar.getInstance();
        begin.setTime(startTime);
        Calendar end = Calendar.getInstance();
        end.setTime(endTime);
        if (date.after(begin) && date.before(end)) {
            return true;
        } else {
            return false;
        }
    }
    
    /**
     * @param businessTable
     * @param flowKey
     * @param candidateUserList
     * @param bussinessId
     * @param alarmRecordHistory
     */
    public void startProcessFlow(String businessTable,String flowKey,List<String> candidateUserList,String bussinessId,AlarmRecordHistory alarmRecordHistory) {
        // 启动流程
        Kv variables = Kv.create().set(ProcessConstant.TASK_VARIABLE_CREATE_USER, "");
        String processDefinitionId = flowBusinessService.getProcessDefinitionLastVersionId(flowKey);
        alarmRecordHistory.setProcessDefinitionId(processDefinitionId);
        BladeFlow flow = flowService.startProcessInstanceById(processDefinitionId, FlowUtil.getBusinessKey(businessTable, String.valueOf(bussinessId)), variables);
        if (Func.isNotEmpty(flow)) {
            log.debug("流程已启动,流程ID: " + flow.getProcessInstanceId());
            //动态添加下一节点候选用户
            if(candidateUserList!=null&&candidateUserList.size()>0) {
            	//获取当前活动任务
                TaskEntity taskEntity=(TaskEntity)taskService.createTaskQuery().processInstanceId(flow.getProcessInstanceId()).singleResult();
                String taskId = taskEntity.getId();
                ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
                //获取当前结点审批人  考虑到有多个审批人的情况  需要先查询出所有的审批人   所以涉及到identityLink
                List<String> userIds = processEngine.getTaskService().getIdentityLinksForTask(taskId).stream().map(IdentityLink::getUserId).distinct().collect(Collectors.toList());
                //删除identityLink中的用户关系
                for (String userId : userIds) {
                    taskService.deleteUserIdentityLink(taskId, userId, IdentityLinkType.CANDIDATE);
                }
                //清空task中的assignee
                taskService.unclaim(taskId);
                //当前节点审核人列表 清空申请人
                userIds = new ArrayList<>();
                //当前节点审核人列表 追加流转人
                userIds.addAll(candidateUserList);
                //给当前任务节点分配审核人
                for (String userId : userIds) {
                	taskService.addCandidateUser(taskId, "taskUser_"+userId);
                }
                //工单消息推送

                if (userIds != null && userIds.size() > 0) {
                    List<String> userCidList = new ArrayList<>();
                    userCidList = sysUserService.getCidByUserIds(String.join(",", userIds));

                    //获取用户列表后做消息推送
                    MessageEntity messageEntity = new MessageEntity();
                    messageEntity.setMessageTitle("流程审批消息");
                    messageEntity.setMessageBody("您有一条" + alarmRecordHistory.getAlarmWorkName() + "待审批,请及时处理");
                    messageEntity.setReceiveUser(userIds);
                    messageEntity.setReceiveUserCid(userCidList);
                    messageEntity.setSendUser("系统");
                    messageEntity.setForwardTag("todo");
                    IPushService appPushService = PushMessageFactory.getPushService("MOB");
                    IPushService webPushService = PushMessageFactory.getPushService("WEB");
                    appPushService.pushMessage(messageEntity);
                    webPushService.pushMessage(messageEntity);
                }

            }
            //返回流程id写入leave
            alarmRecordHistory.setProcessInstanceId(flow.getProcessInstanceId());
            alarmRecordHistoryService.saveOrUpdate(alarmRecordHistory);
            log.debug("流程发起成功");
        } else {
        	log.debug("流程发起失败");
        }
    }
}