package com.skua.modules.quartz;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
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.service.ISequenceService;
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.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.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.entity.SysUser;
import com.skua.modules.system.service.ISysUserService;
import com.skua.modules.util.SysMessagePushService;
import lombok.extern.slf4j.Slf4j;
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.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.MathContext;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <pre>
 * 	设备到期提醒定时任务开始
 * </pre>
 * @author Li Yuanyuan
 * @version V1.0, 2023年9月12日 上午9:40:35
 */
@Slf4j
@Component
public class EquipmentMaintainReminderJob implements Job {
	@Autowired
	private ISequenceService sequenceService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IAlarmRuleConfigPublicTabService alarmRuleConfigPublicTabService;
    @Autowired
    private AlarmRuleLevelConfigService alarmRuleLevelConfigService;
    @Autowired
    private AlarmRecordHistoryService alarmRecordHistoryService;
    @Autowired
    private AlarmMessageHistoryService alarmMessageHistoryService;

    @Autowired
    private FlowBusinessService flowBusinessService;
    @Autowired
    private IFlowService flowService;
    @Autowired
    private TaskService taskService;

    private static String prefix = "【金控数矿】";
    private static String suffix = ",请处理!";

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        try {
            log.info("设备到期提醒定时任务开始");
            JdbcTemplate masterDB = (JdbcTemplate) SpringContextUtils.getBean("master");
            //获取报警类别,已报警类别id为key,构造map对象
            Map<String,AlarmRuleConfigPublicTab> alarmTypeDictMap = new HashMap<String,AlarmRuleConfigPublicTab>();
        	List<AlarmRuleConfigPublicTab> alarmRuleConfigPublicTabList = alarmRuleConfigPublicTabService.list();
        	alarmRuleConfigPublicTabList.forEach(v->{
        		alarmTypeDictMap.put(v.getId(), v);
        	});
            //获取设备到期提醒规则配置
        	List<Map<String,Object>> paramList = masterDB.queryForList("select a.*,b.depart_name from alarm_custom_rule_config a left join sys_depart b on a.depart_id=b.id where a.alarm_rule_repository_id='1717108665534263300'");
        	//报警异常数据接收对象
            List<AlarmRuleConfigAndLevelVO> excessList = new ArrayList<AlarmRuleConfigAndLevelVO>();
            //遍历报警规则,查询
            if(paramList!=null&&paramList.size()>0) {
            	for(Map<String,Object> paramMap : paramList) {
            		String alarmRuleJson = ConvertUtils.getString(paramMap.get("alarm_rule_json"));
                	String departId = ConvertUtils.getString(paramMap.get("depart_id"));
                	String departName = ConvertUtils.getString(paramMap.get("depart_name"));
                	String alarmIndexJson = ConvertUtils.getString(paramMap.get("alarm_index_json"));
                	String alarmRuleId = ConvertUtils.getString(paramMap.get("id"));
                	String alarmRuleType = ConvertUtils.getString(paramMap.get("alarm_rule_type"));
                	String alarmRecommend = ConvertUtils.getString(paramMap.get("alarm_recommend"));
                	String alarmRuleRepositoryTreepath = ConvertUtils.getString(paramMap.get("alarm_rule_repository_treepath"));

                	//获取报警规则id对应的报警级别
                	QueryWrapper<AlarmRuleLevelConfig> queryWrapper = new QueryWrapper<AlarmRuleLevelConfig>();
                	queryWrapper.eq("alarm_rule_id", alarmRuleId);
                	AlarmRuleLevelConfig alarmRuleLevelConfig = alarmRuleLevelConfigService.getOne(queryWrapper);
                	//获取参与报警提醒的设备列表
                	List<Map> equipmentList = JSON.parseArray(alarmIndexJson, Map.class);
                	//解析配置数据
                	List<String> configParamList = CustomReportUtil.getDataKey(alarmRuleJson);
                	//获取月运行时长阈值
                	double monthThreshold = ConvertUtils.getDouble(configParamList.get(0), 0);
                	//获取累计运行时长阈值
                	double sumThreshold = ConvertUtils.getDouble(configParamList.get(1), 0);
                	//获取截至到今天本月运行时长,注意:如果有提醒记录,则以提醒时间作为开始时间
                	if(equipmentList!=null&&equipmentList.size()>0) {
                		equipmentList.forEach(equipmentMap ->{
                			String equipmentId = ConvertUtils.getString(equipmentMap.get("id"));
                			String equipmentName = ConvertUtils.getString(equipmentMap.get("equipmentName"));
                			//获取这个设备上一次提醒日期,如果有,则以这个时间作为开始时间,如果没有,本月则以当月第一天作为起始时间,累计则不设置开始时间查询条件
                			List<Map<String,Object>> reminderTimeList = masterDB.queryForList("select max(record_time) as reminder_time from alarm_record_history where alarm_param_code='"+equipmentId+"' and alarm_rule_type='"+alarmRuleType+"'");
                			String startTime = "";
                			//默认提醒时间不在当月内
                			boolean startTimeIsInMonth = false;
                			if(reminderTimeList!=null&&reminderTimeList.size()>0) {
                				startTime = ConvertUtils.getString(reminderTimeList.get(0).get("reminder_time"));
                				//判断本月运行时长是否符合设备保养提醒条件
                				if(StringUtils.isNotEmpty(startTime)) {
                					startTimeIsInMonth = DateUtil.isIn(DateUtil.parse(startTime,"yyyy-MM-dd HH:mm:ss"), DateUtil.beginOfMonth(DateUtil.date()), DateUtil.endOfMonth(DateUtil.date()));
                				}
                			}

                			//如果上一次提醒时间不在本月,则开始时间为本月第一天,结束时间为本月最后一天
                			String startTimeForMonth = startTime;
                			String endTimeForMonth = DateUtil.format(DateUtil.endOfMonth(DateUtil.date()), "yyyy-MM-dd HH:mm:ss");
                			if(!startTimeIsInMonth) {
                				startTimeForMonth = DateUtil.format(DateUtil.beginOfMonth(DateUtil.date()), "yyyy-MM-dd HH:mm:ss");
                			}
                			//获取设备运行时长sql
                			String sql=buildRunLengthSql(startTimeForMonth,endTimeForMonth,equipmentId);
                			//这里如果模拟数据不存在可以构造mock数据测试
                			List<Map<String, Object>> dataList = masterDB.queryForList(sql,equipmentId);

                			if(dataList!=null&&dataList.size()>0) {
                				//获取运行时间
                				Map<String,Object> dataMap = dataList.get(0);
                				double runCount = ConvertUtils.getDouble(dataMap.get("runCount"), 0,2);
                				String msg = "";
                				String dateTime = DateUtil.now();

                				if(runCount>monthThreshold) {
                					//触发本月运行时长超过阈值设备到期提醒
                					System.out.println("当月设备运行时长触发提醒通知");
                					msg = equipmentName+"设备当月运行时长:"+runCount+"小时,大于设定阈值:"+monthThreshold+"小时,触发提醒通知" + suffix;
                				}else {
                					//判定累计运行时长阈值
                					startTimeForMonth = startTime;
                					sql=buildRunLengthSql(startTimeForMonth,endTimeForMonth,equipmentId);
                					dataList = masterDB.queryForList(sql,equipmentId);
                					if(dataList!=null&&dataList.size()>0) {
                						//获取运行时间
                        				dataMap = dataList.get(0);
                        				runCount = ConvertUtils.getDouble(dataMap.get("runCount"), 0,2);
                        				if(runCount>sumThreshold) {
                        					//触发累计设备运行时长超过阈值设备到期提醒
                        					System.out.println("累计设备运行时长触发提醒通知");
                        					msg = equipmentName+"设备累计运行时长:"+runCount+"小时,大于设定阈值:"+monthThreshold+"小时,触发提醒通知";
                        				}
                					}
                				}
                				if(StringUtils.isNotEmpty(msg)) {
                					//构造报警记录
                            		AlarmRuleConfigAndLevelVO alarmRuleConfigAndLevelVO = new AlarmRuleConfigAndLevelVO();
                            		//存在监测报警数据
                                	alarmRuleConfigAndLevelVO.setDepartId(departId);
                                	alarmRuleConfigAndLevelVO.setAlarmRuleLevelConfig(alarmRuleLevelConfig);
                                	alarmRuleConfigAndLevelVO.setAlarmParamCode(equipmentId);
                                	alarmRuleConfigAndLevelVO.setAlarmParamName(equipmentName);
                                	alarmRuleConfigAndLevelVO.setEquipmentId(equipmentId);
                                	alarmRuleConfigAndLevelVO.setAlarmProgramCode(equipmentId);
                                	alarmRuleConfigAndLevelVO.setDepartName(departName);
                                	alarmRuleConfigAndLevelVO.setAlarmMsg(msg);
                                	alarmRuleConfigAndLevelVO.setAlarmRecommend(alarmRecommend);
                                	alarmRuleConfigAndLevelVO.setRecordTime(dateTime);
                                	//设置报警类型
                                	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);

                                    //构造报警指标数据json
                                    List<Map<String,Object>> indexDataList = new ArrayList<Map<String,Object>>();
                                    Map<String,Object> equipmentJsonMap = new HashMap<String,Object>();
                                    equipmentJsonMap.put("indexCode", equipmentId);
                                    equipmentJsonMap.put("indexName", equipmentName);
                                    equipmentJsonMap.put("indexValue", runCount);
                                    indexDataList.add(equipmentJsonMap);
                                    alarmRuleConfigAndLevelVO.setAlarmCustomIndexJsonData(JSONUtil.toJsonStr(indexDataList));
                                	excessList.add(alarmRuleConfigAndLevelVO);
                				}
                			}
                		});
                	}
            	}
            }else {
            	log.info("设备到期提醒规则初始参数未配置,请检查设备到期提醒规则库,设备运行时长规则");
            	return;
            }
            //发送短信,存储设备到期提醒结果
            sendMessage(excessList);
            log.info("设备到期提醒定时任务结束");
        } catch (Exception e) {
        	e.printStackTrace();
            log.error("设备到期提醒定时任务异常" + e);
        }
    }
    /**
     * <pre>
     * 	构造设备运行时长sql
     * </pre>
     * @return
     * @author Li Yuanyuan, 2023年9月11日 下午4:49:52
     * @Description: TODO(这里描述这个方法的需求变更情况)
     */
    public String buildRunLengthSql(String startTime,String endTime,String equipmentId) {
    	String startTimeSql = "";
    	if(StringUtils.isNotEmpty(startTime)) {
    		startTimeSql = " and a.data_time >='"+startTime+"'";
    	}
    	String endTimeSql = "";
    	if(StringUtils.isNotEmpty(endTime)) {
    		endTimeSql = " and a.data_time <='"+endTime+"'";
    	}

    	String sql="SELECT\r\n" +
				"	sum(a.run_time / 60 / 60 ) AS runCount\r\n" +
				"FROM\r\n" +
				"	equipment_run_child a\r\n" +
				"LEFT JOIN equipment_run b ON a.equipment_run_id = b.id\r\n" +
				"LEFT JOIN equipment_info c ON b.equipment_id = c.id\r\n" +
				"WHERE 1=1 \r\n" + startTimeSql + endTimeSql+
				" and b.equipment_id=?";
    	return sql;
    }


    public static String handleDoubleValue(String doubleValue) {
        if(doubleValue.contains("E")) {
            MathContext mc = new MathContext(32);
            BigDecimal bigNumber = new BigDecimal(doubleValue, mc);
            BigDecimal setScale = bigNumber.setScale(4,BigDecimal.ROUND_HALF_UP);
            return setScale.toString();
        }else {
            return ConvertUtils.getString(ConvertUtils.getDouble(doubleValue,0.0,4));
        }
    }

    /**
     * <pre>
     * 	提醒消息落地及短信提醒
     * </pre>
     * @param reminderList
     * @author Li Yuanyuan, 2023年9月12日 上午11:04:17
     * @Description: TODO(这里描述这个方法的需求变更情况)
     */
    public void sendMessage(List<AlarmRuleConfigAndLevelVO> reminderList) {
        if (reminderList != null && reminderList.size() > 0) {
        	reminderList.forEach(map -> {
                dealData(map);
            });
        }
    }

    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 = alarmRuleAndAlarmRuleLevelVO.getDepartName();

        //如果没有上条记录或者处理状态(0:未处理,1:已处理)为已处理
        AlarmRecordHistory alarmRecordHistory = new AlarmRecordHistory();
        String uuid = String.valueOf(sequenceService.nextId());
        alarmRecordHistory.setId(uuid);
        alarmRecordHistory.setAlarmParamCode(alarmParamCode);
        alarmRecordHistory.setAlarmParamName(alarmParamName);
        alarmRecordHistory.setAlarmWorkName(alarmParamName+"报警");
        alarmRecordHistory.setAlarmRuleLevelName(alarmRuleLevelName);
        alarmRecordHistory.setAlarmRuleLevelId(alarmRuleLevelConfigId);
        String recordTime = alarmRuleAndAlarmRuleLevelVO.getRecordTime();
        alarmRecordHistory.setRecordTime(DateUtil.parse(recordTime));
        alarmRecordHistory.setAlarmParamUnit(alarmRuleAndAlarmRuleLevelVO.getAlarmParamUnit());
        alarmRecordHistory.setDepartId(departId);
        //alarmRecordHistory.setActualAvgValue(alarmValue.toString());
        alarmRecordHistory.setHandleStatus(0);
        alarmRecordHistory.setDelFlag(1);
        //alarmRecordHistory.setAlarmDataSource("gyfz_mxyxgj");
        alarmRecordHistory.setHandleMethon(alarmRuleAndAlarmRuleLevelVO.getAlarmRecommend());
        //${start}采集数据${conent}已超标,请注意!
        //alarmRecordHistory.setAlarmContent(prefix + recordTime + "时" + 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());
        alarmRecordHistory.setAlarmCustomIndexJsonData(alarmRuleAndAlarmRuleLevelVO.getAlarmCustomIndexJsonData());
        //设备类型,填充视频流地址
        //alarmRecordHistory.setImgPath(alarmRuleAndAlarmRuleLevelVO.getImgPath());
        //设备报警,存储设备id
        alarmRecordHistory.setEquipmentId(alarmRuleAndAlarmRuleLevelVO.getEquipmentId());

        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())) {
        		//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)) {
                //判断是否满足报警频率,将两个时间转为毫秒
            	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 + recordTime + "时" + 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 + recordTime + "时" + 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("流程发起失败");
        }
    }
}