package com.yeejoin.amos.boot.module.jcs.biz.service.impl;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc.Enum;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.component.emq.EmqKeeper;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ELMode;
import com.deepoove.poi.data.RowRenderData;
import com.deepoove.poi.data.style.Style;
import com.deepoove.poi.data.style.TableStyle;
import com.deepoove.poi.policy.DynamicTableRenderPolicy;
import com.deepoove.poi.policy.MiniTableRenderPolicy;
import com.deepoove.poi.util.TableTools;
import com.google.common.collect.Lists;
import com.spire.doc.Document;
import com.spire.doc.FileFormat;
import com.yeejoin.amos.boot.biz.common.constants.RuleConstant;
import com.yeejoin.amos.boot.biz.common.entity.DataDictionary;
import com.yeejoin.amos.boot.biz.common.service.impl.DataDictionaryServiceImpl;
import com.yeejoin.amos.boot.biz.common.utils.DateUtils;
import com.yeejoin.amos.boot.biz.common.utils.EnumsUtils;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.biz.common.utils.WordConverterUtils;
import com.yeejoin.amos.boot.module.common.api.dto.FirefightersDto;
import com.yeejoin.amos.boot.module.common.api.dto.FormValue;
import com.yeejoin.amos.boot.module.common.api.dto.RequestData;
import com.yeejoin.amos.boot.module.common.api.entity.FireTeam;
import com.yeejoin.amos.boot.module.common.api.entity.OrgUsr;
import com.yeejoin.amos.boot.module.common.api.feign.EquipFeignClient;
import com.yeejoin.amos.boot.module.common.api.mapper.DynamicFormInstanceMapper;
import com.yeejoin.amos.boot.module.common.api.service.IDutyPersonService;
import com.yeejoin.amos.boot.module.common.api.service.IFireTeamService;
import com.yeejoin.amos.boot.module.common.biz.service.impl.FireTeamServiceImpl;
import com.yeejoin.amos.boot.module.common.biz.service.impl.FirefightersServiceImpl;
import com.yeejoin.amos.boot.module.common.biz.service.impl.OrgUsrServiceImpl;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertCallCommandDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertCallePowerTransferRo;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertCalledFormDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertCalledMobDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertCalledObjsDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertCalledPowerInfoDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertCalledRo;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertCalledZhDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertSubmittedDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertSubmittedExtDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertSubmittedSMSDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.AlertSubmittedZHDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.CarStatusInfoDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.InstructionsZHDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.PowerData;
import com.yeejoin.amos.boot.module.jcs.api.dto.PowerTransferCompanyDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.PowerTransferCompanyResourcesDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.PowerTransferCompanyZHDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.PushMessageWebAndAppRo;
import com.yeejoin.amos.boot.module.jcs.api.dto.SchedulingReportingDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.TemplateDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.TemplateExtendDto;
import com.yeejoin.amos.boot.module.jcs.api.dto.VoiceRecordFileDto;
import com.yeejoin.amos.boot.module.jcs.api.entity.AlertCalled;
import com.yeejoin.amos.boot.module.jcs.api.entity.AlertSubmitted;
import com.yeejoin.amos.boot.module.jcs.api.entity.AlertSubmittedObject;
import com.yeejoin.amos.boot.module.jcs.api.entity.Template;
import com.yeejoin.amos.boot.module.jcs.api.enums.AlertBusinessTypeEnum;
import com.yeejoin.amos.boot.module.jcs.api.enums.AlertSchedulingTypeEnum;
import com.yeejoin.amos.boot.module.jcs.api.enums.AlertStageEnums;
import com.yeejoin.amos.boot.module.jcs.api.enums.AlertSubmitTypeEnum;
import com.yeejoin.amos.boot.module.jcs.api.enums.FireCarStatusEnum;
import com.yeejoin.amos.boot.module.jcs.api.enums.SubmissionMethodEnum;
import com.yeejoin.amos.boot.module.jcs.api.mapper.AlertSubmittedMapper;
import com.yeejoin.amos.boot.module.jcs.api.mapper.PowerTransferCompanyMapper;
import com.yeejoin.amos.boot.module.jcs.api.mapper.PowerTransferMapper;
import com.yeejoin.amos.boot.module.jcs.api.service.IAlertSubmittedObjectService;
import com.yeejoin.amos.boot.module.jcs.api.service.IAlertSubmittedService;
import com.yeejoin.amos.boot.module.jcs.biz.rule.action.AlertCalledAction;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.component.rule.RuleTrigger;
import com.yeejoin.amos.component.rule.config.RuleConfig;
import com.yeejoin.amos.feign.systemctl.Systemctl;


/**
 * 警情报送记录 服务实现类
 *
 * @author tb
 * @date 2021-06-17
 */
@Service
public class AlertSubmittedServiceImpl extends BaseService<AlertSubmittedDto, AlertSubmitted, AlertSubmittedMapper> implements IAlertSubmittedService {

    @Autowired
    IAlertSubmittedObjectService iAlertSubmittedObjectService;
    @Autowired
    AlertSubmittedObjectServiceImpl alertSubmittedObjectServiceImpl;
    @Autowired
    AlertCalledServiceImpl alertCalledService;
    @Autowired
    DataDictionaryServiceImpl dataDictionaryService;
    @Autowired
    TemplateServiceImpl templateService;
    @Autowired
    PowerTransferServiceImpl powerTransferService;
    @Autowired
    RuleAlertCalledService ruleAlertCalledService;
    @Autowired
    AlertCalledAction alertCalledAction;
    @Autowired
    OrgUsrServiceImpl orgUsrService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private FirefightersServiceImpl firefightersService;
    @Autowired
    OrgUsrServiceImpl iOrgUsrService;
    @Autowired
    IDutyPersonService iDutyPersonService;

    @Autowired
    PowerTransferMapper powerTransferMapper;

    @Autowired
    VoiceRecordFileServiceImpl voiceRecordFileService;

    @Autowired
    private EmqKeeper emqKeeper;
    @Value("${mqtt.topic.alert.reporting}")
    private String topic;

    @Value("${mqtt.topic.command.power.deployment}")
    private String powertopic;

    @Autowired
    EquipFeignClient equipFeignClient;

    @Autowired
    FireTeamServiceImpl fireTeamServiceImpl;

    @Autowired
    IFireTeamService fireTeamService;


    @Autowired
    PowerTransferCompanyResourcesServiceImpl powerTransferCompanyResourcesService;
    @Autowired
    AlertSubmittedMapper alertSubmittedMapper;

    @Autowired
    PowerTransferCompanyMapper powerTransferCompanyMapper;

    @Autowired
    DynamicFormInstanceMapper dynamicFormInstanceMapper;

    @Autowired
    private RuleTrigger ruleTrigger;


    @Value("${mqtt.topic.command.alert.noticeJa}")
    private String topicJa;

    private final String msgType = "jcs119";

    @Override
    public SchedulingReportingDto listSchedulingByParam(AlertSubmittedDto queryParam) {
        SchedulingReportingDto schedulingReportingDto = new SchedulingReportingDto();
        List<AlertSubmittedExtDto> alertSubmittedExtDtoList = this.baseMapper.listSchedulingByParam(queryParam);
        schedulingReportingDto.setSchedulingReportingList(alertSubmittedExtDtoList);
        Map<String, List<AlertSubmittedExtDto>> groupMap =
                alertSubmittedExtDtoList.stream().collect(Collectors.groupingBy(AlertSubmittedExtDto::getSubmissionMethodCode));
        int phoneSize = 0;
        int smsSize = 0;
        if (ObjectUtils.isNotEmpty(groupMap.get(SubmissionMethodEnum.PHONE.getCode()))) {
            phoneSize = groupMap.get(SubmissionMethodEnum.PHONE.getCode()).size();
        }
        if (ObjectUtils.isNotEmpty(groupMap.get(SubmissionMethodEnum.SMS.getCode()))) {
            smsSize = groupMap.get(SubmissionMethodEnum.SMS.getCode()).size();
        }
        String extraInfo = String.format("已调度电话%s起，短信%d批", phoneSize, smsSize);
        schedulingReportingDto.setExtraInfo(extraInfo);
        return schedulingReportingDto;
    }

    @Override
    public SchedulingReportingDto listReportingByParam(AlertSubmittedDto queryParam) {
        SchedulingReportingDto schedulingReportingDto = new SchedulingReportingDto();
        List<AlertSubmittedExtDto> alertSubmittedExtDtoList = this.baseMapper.listReportingByParam(queryParam);
        if (ObjectUtils.isNotEmpty(alertSubmittedExtDtoList)) {
            // 组装额外信息
            String _extraInfo = "报送给%s、%s";
            alertSubmittedExtDtoList.forEach(alertSubmittedExtDto -> {
                try {
                    alertSubmittedExtDto.setExtraInfo(String.format(_extraInfo, alertSubmittedExtDto.getCompanyName(),
                            alertSubmittedExtDto.getUserName()));

                    TemplateExtendDto template = null;
                    Template templateN = null;
                    if(AlertBusinessTypeEnum.警情初报.getName().equals(alertSubmittedExtDto.getBusinessType())) {
                        // 获取任务派发模板
                         templateN = templateService
                                .getOne(new QueryWrapper<Template>().eq("type_code", "JQCB").eq("format", false));
                         template = new TemplateExtendDto();
                         BeanUtils.copyProperties(templateN,template);
                        template.setRichContent(template.getContent());

                    } else {
                        template = templateService.getByType(alertSubmittedExtDto.getBusinessTypeCode());
                    }

                    AlertCalledObjsDto alertCalledVo  = (AlertCalledObjsDto) alertCalledService.selectAlertCalledByIdNoRedisNew(queryParam.getAlertCalledId());
                    AlertCalled alertCalled = alertCalledVo.getAlertCalled();
                    /**
                     * 构建警情报送规则对象
                     */
                    AlertCalledRo alertCalledRo = new AlertCalledRo();

                    String replaceContent ="";
                    if(null != alertCalled) {
                        replaceContent = RuleAlertCalledService.init(alertCalledRo, alertCalledVo);
                    }

                    Map<String, String> definitions = new HashMap<>();
                    definitions.put("$type",alertCalled.getAlertType());
                    definitions.put("$callTime", DateUtils.dateTimeToDateString(alertCalled.getCallTime()));
                    definitions.put("$replaceContent",replaceContent);
                    definitions.put("$address",ValidationUtil.isEmpty(alertCalled.getAddress()) ? "无" : alertCalled.getAddress());
                    definitions.put("$recDate",DateUtils.dateTimeToDateString(alertCalled.getRecDate()));

                    definitions.put("$contactUser",ValidationUtil.isEmpty(alertCalled.getContactUser()) ? "无" : alertCalled.getContactUser());
                    definitions.put("$trappedNum",ValidationUtil.isEmpty(alertCalledRo.getTrappedNum()) ? "无" : String.valueOf(alertCalled.getTrappedNum()));
                    definitions.put("$casualtiesNum",ValidationUtil.isEmpty(alertCalled.getCasualtiesNum()) ? "无" : String.valueOf(alertCalled.getCasualtiesNum()));
                    definitions.put("$contactPhone",ValidationUtil.isEmpty(alertCalled.getContactPhone()) ? "无" :  alertCalled.getContactPhone());

                   String  companyName = JSONObject.parseObject(alertSubmittedExtDto.getSubmissionContent()).getString("$companyName") ;

                    definitions.put("$companyName", null == companyName ? "" : companyName);

                    String content = getTaskInformation( template.getRichContent(),definitions);

                    alertSubmittedExtDto.setSubmissionContentValue(JSONObject.parseObject(alertSubmittedExtDto.getSubmissionContent()));
                    alertSubmittedExtDto.setSubmissionContent(content);

                } catch (JSONException e) {
                    alertSubmittedExtDto.setSubmissionContentValue(alertSubmittedExtDto.getSubmitContent());
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            });
            schedulingReportingDto.setSchedulingReportingList(alertSubmittedExtDtoList);

            String extraInfo = String.format("已报送%d条", alertSubmittedExtDtoList.size());
            schedulingReportingDto.setExtraInfo(extraInfo);
        }
        return schedulingReportingDto;
    }

    @Override
    public Boolean save(AlertSubmittedDto alertSubmittedDto, String userName) throws Exception {
        try {
            Map<String,String> map = saveAlertSubmitted(alertSubmittedDto, userName);
            // 组装规则入参
            AlertCalled alertCalled = alertCalledService.getById(alertSubmittedDto.getAlertCalledId());
            AlertCalledObjsDto alertCalledVo  = (AlertCalledObjsDto) alertCalledService.selectAlertCalledByIdNoRedisNew(alertCalled.getSequenceNbr());
            alertCalledVo.setAlertCalled(alertCalled);

            // 调用规则
            ruleAlertCalledService.fireAlertCalledRule(alertCalledVo, map.get("alertWay"),map.get("mobiles"), map.get("usIds"), map.get("feedBack"));
            //通知实战指挥页面发送mqtt 默认发送 String 类型 0, 新警情 1 警情状态变化
            emqKeeper.getMqttClient().publish(powertopic, "0".getBytes(), RuleConfig.DEFAULT_QOS, true);
        } catch (MqttException e) {
            throw new RuntimeException();
        }
        return true;
    }

    /**
     * 规则回调
     */
    public void ruleCallbackAction(String smsCode, List<Map<String,Object>> sendIds, Object object) throws Exception {
        // 获取报送对象列表
        List<AlertSubmittedObject> alertSubmittedObjectList = Lists.newArrayList();

        Set<String> mobiles = new HashSet<>();
        HashMap<String, String> smsParams = new HashMap<>();
        String alertCalledId = null;

        List<Map<String, Object>> orgUsers = new LinkedList<>();
        String sCode = "";
        String alertWay = "";
        AlertCalled alertCalled = null;
        List<String> usIds = new ArrayList<>();
        if (object instanceof AlertCalledRo) {
            AlertCalledRo calledRo = (AlertCalledRo) object;
            String alertSubmittedId = calledRo.getAlertSubmittedId();
            alertCalledId = calledRo.getSequenceNbr();

            AlertCalledObjsDto alertCalledObjsDto = (AlertCalledObjsDto)alertCalledService.selectAlertCalledByIdNoRedisNew(Long.valueOf(calledRo.getSequenceNbr()));
            alertCalled = alertCalledObjsDto.getAlertCalled();

//            AlertCalledRo tempCalledRo = new AlertCalledRo();
//            RuleAlertCalledService.init(tempCalledRo,alertCalledObjsDto);
//            BeanUtils.copyProperties(tempCalledRo,calledRo,"feedback","usIds","ids","alertWay","replaceContent","unitInvolved","alertSubmittedId");

            String alertTypeCode = calledRo.getAlertTypeCode();
            alertWay = calledRo.getAlertWay();
            String unitInvolved = calledRo.getUnitInvolved();

            // 警情续报 警情结案，非警情确认选择人员电话号码
            String ids = calledRo.getIds();
            if(!ValidationUtil.isEmpty(ids)) {
                List<String> ls = Arrays.asList(ids.split(","));
                ls.stream().forEach(e->mobiles.add(e));
            }
            // 获取报送规则
            sendIds.stream().forEach(e->{

                // 一般火灾 // 航空器救援
                if(alertTypeCode.equals(AlertStageEnums.YBHZ.getCode()) || alertTypeCode.equals(AlertStageEnums.HKJY.getCode())) {
                    if(e.containsKey("onDuty")) {
                        // 当日值班人员：获值班表中包括消救部、综合办公室、消防支队、应急指挥科的值班人员。
                        String [] arr = e.get("onDuty").toString().split(",");
                        List<String> list = Arrays.asList(arr);

                        List<Map<String, Object>> mapList = iDutyPersonService.queryByCompanyId(list);
                        orgUsers.addAll(mapList);
                    }
                    if(e.containsKey("fireBrigade")) {
                        //  根据人员岗位：班组长、队长、通讯员； 消防队伍--消防人员 中，对应岗位的人员
                        List<FirefightersDto> fireBrigade = firefightersService.queryById(e.get("fireBrigade").toString().split(","), e.get("name").toString());
                        fireBrigade.stream().forEach(f->{
                            HashMap<String,Object> map = new HashMap<>();
                            map.put("telephone",f.getMobilePhone());
                            map.put("sequenceNbr",f.getSequenceNbr());
                            map.put("bizOrgName",f.getName());
                            map.put("amosUserId",f.getAmosUserId());
                            map.put("companyName", e.get("name").toString());
                            orgUsers.add(map);
                        });

                    }

                    if(e.containsKey("name")) {
                        //  消防救援保障部
                        List<Map<String, Object>> mapList = iOrgUsrService.queryCompanyIdNew(e.get("name").toString());
                        orgUsers.addAll(mapList);
                    }

                    // 安运部
                    if(e.get("type").toString().equals("AY")) {
                        if(e.containsKey("name")) {
                            String [] arr = e.get("airportPost").toString().split(",");
                            List<String> list = Arrays.asList(arr);

                            List<Map<String, Object>> mapList = iOrgUsrService.queryCompanyId(e.get("name").toString(),list);
                            orgUsers.addAll(mapList);
                        }
                    }

                    // 事发单位
                    if(e.get("type").toString().equals("SF")) {
                        if(e.containsKey("airportPost")) {
                            String [] arr = e.get("airportPost").toString().split(",");
                            List<String> list = Arrays.asList(arr);
                            List<Map<String, Object>> mapList = iOrgUsrService.queryCompanyId(unitInvolved,list);
                            orgUsers.addAll(mapList);
                        }
                    }
                }

                // 突发事件救援   // 漏油现场安全保障   // 专机保障  // 其他
                if(alertTypeCode.equals(AlertStageEnums.HKJY.getCode())  || alertTypeCode.equals(AlertStageEnums.LYXC.getCode())
                        || alertTypeCode.equals(AlertStageEnums.ZJBZ.getCode()) || alertTypeCode.equals(AlertStageEnums.QTJQ.getCode())) {
                    if(e.containsKey("onDuty")) {
                        List<Map<String, Object>> mapList = iDutyPersonService.queryByCompanyNew(e.get("name").toString());
                        orgUsers.addAll(mapList);
                    }
                }

                // 120急救
                if(alertTypeCode.equals(AlertStageEnums.JJJQ.getCode())) {
                    if (e.containsKey("name")) {
                        List<Map<String, Object>> mapList = iDutyPersonService.queryByCompanyNew(e.get("name").toString());
                        orgUsers.addAll(mapList);

                        List<Map<String, Object>> mapList1 = iOrgUsrService.queryCompanyIdNew(e.get("name").toString());
                        orgUsers.addAll(mapList1);
                    }
                }
            });

            // 警情初报 续报 结案
            // 1.保存警情记录主表
            AlertSubmitted alertSubmitted = new AlertSubmitted();
            alertSubmitted.setAlertCalledId(Long.valueOf(calledRo.getSequenceNbr()));
            // 保存初报细分类型（一般火灾、航空器救援等）
            alertSubmitted.setBusinessTypeCode(calledRo.getAlertTypeCode());
            // 警情初报 --- 续报 结案
            if(alertWay.equals(AlertBusinessTypeEnum.警情初报.getCode())) {
                alertSubmitted.setBusinessType(AlertBusinessTypeEnum.警情初报.getName());

                Optional<SubmissionMethodEnum> submissionMethodEnum = Optional.of(SubmissionMethodEnum.SMS);
                alertSubmitted.setSubmissionMethodCode(submissionMethodEnum.get().getCode());
                alertSubmitted.setSubmissionMethod(submissionMethodEnum.get().getName());
                Optional<AlertSchedulingTypeEnum> alertSchedulingTypeEnum = Optional.of(AlertSchedulingTypeEnum.融合调度);
                alertSubmitted.setSchedulingTypeCode(alertSchedulingTypeEnum.get().getCode());
                alertSubmitted.setSchedulingType(alertSchedulingTypeEnum.get().getName());
                alertSubmitted.setSubmissionContent(JSONObject.toJSONString(objectToMap(calledRo)));

                alertSubmitted.setUpdateTime(new Date());
                alertSubmitted.setSubmissionTime(new Date());

                this.baseMapper.insert(alertSubmitted);
                alertSubmittedId = alertSubmitted.getSequenceNbr().toString();

            } else if(alertWay.equals(AlertBusinessTypeEnum.警情续报.getCode())) {
                alertSubmitted.setBusinessType(AlertBusinessTypeEnum.警情续报.getName());
                sCode = "SMS_JCS_XB";
            } else if(alertWay.equals(AlertBusinessTypeEnum.警情结案.getCode())) {
                alertSubmitted.setBusinessType(AlertBusinessTypeEnum.警情结案.getName());
                sCode = "SMS_JCS_JA";
            } else {
                alertSubmitted.setBusinessType(AlertBusinessTypeEnum.非警情确认.getName());
                sCode = "SMS_JCS_QR";
            }

            AlertSubmitted alertSubmittedNew = null;
            Optional<AlertBusinessTypeEnum> alertBusinessTypeEnum =
                    EnumsUtils.getEnumObject(AlertBusinessTypeEnum.class,
                            e -> e.getCode().equals(calledRo.getAlertTypeCode()));
            smsCode = alertBusinessTypeEnum.get().getSms_code();


            if(!alertWay.equals(AlertBusinessTypeEnum.警情初报.getCode())) {
                LambdaQueryWrapper<AlertSubmitted> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(AlertSubmitted::getAlertCalledId,alertCalledId);
                queryWrapper.orderByDesc(AlertSubmitted::getSequenceNbr);
                List<AlertSubmitted> alertSubmitteds = alertSubmittedMapper.selectList(queryWrapper);
                alertSubmittedNew = alertSubmitteds.get(0);

                if(!ValidationUtil.isEmpty(calledRo.getUsIds())) {
                    usIds.addAll(Arrays.asList(calledRo.getUsIds().split(",")));
                }
            }

            // 组装人员信息
            for (Map<String, Object> orgUser : orgUsers) {
                AlertSubmittedObject alertSubmittedObject = new AlertSubmittedObject();
                if(!alertWay.equals(AlertBusinessTypeEnum.警情初报.getCode())) {
                    alertSubmittedObject.setAlertSubmittedId(alertSubmittedNew.getSequenceNbr());
                } else {
                    alertSubmittedObject.setAlertSubmittedId(Long.parseLong(alertSubmittedId));
                }

                if (!ValidationUtil.isEmpty(orgUser.get("amosUserId"))) {
                    usIds.add(orgUser.get("amosUserId").toString());
                }

                alertSubmittedObject.setType(false);

                alertSubmittedObject.setUserId(Long.valueOf(String.valueOf(orgUser.get("sequenceNbr"))));
                alertSubmittedObject.setUserName((String) orgUser.get("bizOrgName"));
                alertSubmittedObject.setCompanyName((String) orgUser.get("companyName"));

                if (!ValidationUtil.isEmpty(orgUser.get("telephone"))) {
                    mobiles.add((String) orgUser.get("telephone"));
                    alertSubmittedObject.setUserPhone((String) orgUser.get("telephone"));
                }
                alertSubmittedObjectList.add(alertSubmittedObject);
            }

            // 组装报送内容
            smsParams.put("callTimeStr", calledRo.getCallTimeStr());
            smsParams.put("address", calledRo.getAddress());
            smsParams.put("fireLocation", calledRo.getFireLocation());
            smsParams.put("burningMaterial", calledRo.getBurningMaterial());
            smsParams.put("fireSituation", calledRo.getFireSituation());
            smsParams.put("trappedNum", calledRo.getTrappedNum());
            smsParams.put("casualtiesNum", calledRo.getCasualtiesNum());
            smsParams.put("dangerousExplosives", calledRo.getDangerousExplosives());
            smsParams.put("companyName", calledRo.getCompanyName());
            smsParams.put("contactUser", calledRo.getContactUser());
            smsParams.put("contactPhone", calledRo.getContactPhone());
            smsParams.put("replaceContent", calledRo.getReplaceContent());
            smsParams.put("alertType", calledRo.getAlertType());
            smsParams.put("feedback", calledRo.getFeedback());
        }
        // 短信报送对象
        alertSubmittedObjectServiceImpl.saveBatch(alertSubmittedObjectList);
        // 发送任务消息
        // 组织短信内容
        // 调用短信发送接口

        Map<String,String> besidesMap = new HashMap<>();
        besidesMap.put("alterId",String.valueOf(alertCalled.getSequenceNbr()));

        if(alertWay.equals(AlertBusinessTypeEnum.警情初报.getCode())) {
            alertCalledAction.sendAlertCalleCmd(smsCode, mobiles, smsParams);
            besidesMap.put("sendTime", DateUtils.dateFormat(alertCalled.getCallTime(), DateUtils.DATE_TIME_PATTERN));
            pushPowerTransferToAppAndWeb(AlertBusinessTypeEnum.警情初报.getCode(),besidesMap,smsParams,usIds);
        } else {
            if(alertWay.equals(AlertBusinessTypeEnum.警情续报.getCode())) {
                besidesMap.put("sendTime", DateUtils.dateFormat(alertCalled.getCallTime(), DateUtils.DATE_TIME_PATTERN));
                pushPowerTransferToAppAndWeb(AlertBusinessTypeEnum.警情续报.getCode(),besidesMap,smsParams,usIds);
            }

            if(alertWay.equals(AlertBusinessTypeEnum.警情结案.getCode())) {
                besidesMap.put("startTime", DateUtils.dateFormat(alertCalled.getCallTime(), DateUtils.DATE_TIME_PATTERN));
                besidesMap.put("endTime", DateUtils.dateFormat(alertCalled.getRecDate(), DateUtils.DATE_TIME_PATTERN));
                pushPowerTransferToAppAndWeb(AlertBusinessTypeEnum.警情结案.getCode(),besidesMap,smsParams,usIds);
            }

            if(alertWay.equals(AlertBusinessTypeEnum.非警情确认.getCode())) {
                pushPowerTransferToAppAndWeb(AlertBusinessTypeEnum.非警情确认.getCode(),besidesMap,smsParams,usIds);
            }

            alertCalledAction.sendAlertCalleCmd(sCode, mobiles, smsParams);
        }





        emqKeeper.getMqttClient().publish(topic, alertCalledId.getBytes(), RuleConfig.DEFAULT_QOS, false);
    }

    /**
     * 短信报送
     *
     * @param alertSubmittedDto 警情信息
     * @param userName          用户名
     */
    @Transactional(rollbackFor = Exception.class)
    public Map<String,String> saveAlertSubmitted(AlertSubmittedDto alertSubmittedDto, String userName) {
        try { Long alertSubmittedId = alertSubmittedDto.getSequenceNbr();
        String alertWay = "";
        Map<String,String> map = new HashMap<>();
        Set<String> mobiles = new HashSet<>();
        List<Long> userIds = new ArrayList<>();
        if (alertSubmittedId == null) {
            // 1.保存警情记录主表
            AlertSubmitted alertSubmitted = new AlertSubmitted();
            String bussTypeCode;
            alertSubmitted.setAlertCalledId(alertSubmittedDto.getAlertCalledId());
            // 任务 4174  日常值班---融合调度----短信模版中的内容用户可以全部删除掉，按照自定义内容重新录入发送内容 by litw 2021年10月27日
            alertSubmitted.setBusinessTypeCode(alertSubmittedDto.getBusinessTypeCode());
            bussTypeCode = alertSubmittedDto.getBusinessTypeCode();

            Optional<AlertBusinessTypeEnum> businessTypeEnum = EnumsUtils.getEnumObject(AlertBusinessTypeEnum.class,
                    e -> e.getCode().equals(bussTypeCode));
            alertSubmitted.setBusinessType(businessTypeEnum.get().getName());
            alertSubmitted.setCallLogId(alertSubmittedDto.getCallLogId());
            alertSubmitted.setSubmissionMethodCode(alertSubmittedDto.getSubmissionMethodCode());
            Optional<SubmissionMethodEnum> submissionMethodEnum = EnumsUtils.getEnumObject(SubmissionMethodEnum.class,
                    e -> e.getCode().equals(alertSubmittedDto.getSubmissionMethodCode()));
            alertSubmitted.setSubmissionMethod(submissionMethodEnum.get().getName());
            Optional<AlertSchedulingTypeEnum> alertSchedulingTypeEnum =
                    EnumsUtils.getEnumObject(AlertSchedulingTypeEnum.class,
                            e -> e.getCode().equals(alertSubmittedDto.getSchedulingTypeCode()));
            alertSubmitted.setSchedulingTypeCode(alertSubmittedDto.getSchedulingTypeCode());
            alertSubmitted.setSchedulingType(alertSchedulingTypeEnum.get().getName());

            // 任务 4174  日常值班---融合调度----短信模版中的内容用户可以全部删除掉，按照自定义内容重新录入发送内容 by litw 2021年10月27日
            alertSubmitted.setBusinessTypeCode(alertSubmittedDto.getBusinessTypeCode());
            alertSubmitted.setSubmissionContent(alertSubmittedDto.getSubmitContent().toJSONString());

            alertSubmitted.setSender(userName);
            alertSubmitted.setRecUserName(userName);
            alertSubmitted.setUpdateTime(new Date());
            alertSubmitted.setSubmissionTime(new Date());

            this.baseMapper.insert(alertSubmitted);

            alertSubmittedId = alertSubmitted.getSequenceNbr();
        }

        // 2.保存任务表
        List<AlertSubmittedObject> alertSubmittedObjectList = Lists.newArrayList();
        Long finalAlertSubmittedId = alertSubmittedId;
        // 报送给单位
        if (AlertSubmitTypeEnum.Org.getKey().equals(alertSubmittedDto.getType())) {
            alertSubmittedDto.getSubmitCompanyList().forEach(company -> {
                AlertSubmittedObject alertSubmittedObject = new AlertSubmittedObject();
                alertSubmittedObject.setAlertSubmittedId(finalAlertSubmittedId);
                alertSubmittedObject.setType(true);
                alertSubmittedObject.setCompanyId(company.getCompanyId());
                alertSubmittedObject.setCompanyName(company.getCompanyName());
                alertSubmittedObject.setRecUserName(userName);

                alertSubmittedObjectList.add(alertSubmittedObject);
            });
        } else {
            // 报送给个人
            alertSubmittedDto.getSubmitCompanyList().forEach(company -> {
                company.getPersonList().forEach(person -> {
                    AlertSubmittedObject alertSubmittedObject = new AlertSubmittedObject();
                    alertSubmittedObject.setAlertSubmittedId(finalAlertSubmittedId);
                    alertSubmittedObject.setType(false);
                    alertSubmittedObject.setCompanyId(company.getCompanyId());
                    alertSubmittedObject.setCompanyName(company.getCompanyName());
                    alertSubmittedObject.setUserId(person.getPersonId());
                    userIds.add(person.getPersonId());
                    alertSubmittedObject.setUserName(person.getPersonName());
                    alertSubmittedObject.setUserPhone(person.getPersonPhone());
                    alertSubmittedObject.setRecUserName(userName);
                    if (!ValidationUtil.isEmpty(person.getPersonPhone())) {
                        mobiles.add(person.getPersonPhone());
                    }
                    alertSubmittedObjectList.add(alertSubmittedObject);
                });
            });
        }

        // 查询AmousUserId
        LambdaQueryWrapper<OrgUsr> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(true, OrgUsr::getSequenceNbr, userIds);
        List<String> usIds = new ArrayList<>();
        List<OrgUsr> list = orgUsrService.getBaseMapper().selectList(queryWrapper);
        if(null != list && list.size() > 0) {
            list.stream().forEach(e->{
                if(!ValidationUtil.isEmpty(e.getAmosOrgId())) {
                    usIds.add(e.getAmosOrgId());
                }
            });

            map.put("usIds",  StringUtils.join(usIds.toArray(new String[userIds.size()]),","));
        } else {
            map.put("usIds",  "");
        }

        alertSubmittedObjectServiceImpl.saveBatch(alertSubmittedObjectList);

        // 3.更新警情状态
        alertCalledService.updateAlertCalled(alertSubmittedDto.getAlertCalledId(),
                alertSubmittedDto.getBusinessTypeCode());

        // 警情续报
        if(AlertBusinessTypeEnum.警情续报.getCode().equals(alertSubmittedDto.getBusinessTypeCode())) {
            alertWay = AlertBusinessTypeEnum.警情续报.getCode();
        }

        if(AlertBusinessTypeEnum.警情结案.getCode().equals(alertSubmittedDto.getBusinessTypeCode())) {
            alertWay = AlertBusinessTypeEnum.警情结案.getCode();

            // 警情结案生成模板
            try {
                AlertCalledFormDto alertCalledFormDto = (AlertCalledFormDto)alertCalledService.selectAlertCalledById(alertSubmittedDto.getAlertCalledId());
                AlertCalled alertCalled = alertCalledFormDto.getAlertCalled();
                generateMob(alertCalled);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }

        if(AlertBusinessTypeEnum.非警情确认.getCode().equals(alertSubmittedDto.getBusinessTypeCode())) {
            alertWay = AlertBusinessTypeEnum.非警情确认.getCode();
        }








        if (AlertBusinessTypeEnum.警情结案.getCode().equals(alertSubmittedDto.getBusinessTypeCode())
                || AlertBusinessTypeEnum.非警情确认.getCode().equals(alertSubmittedDto.getBusinessTypeCode())) {
            // 查询本次警情调派的车辆
            List<String> transferCarIdList =
                    powerTransferService.queryTransferCarIdsByAlertCalledId(alertSubmittedDto.getAlertCalledId());
            List<Object> carStatusInfoDtoList = Lists.newArrayList();
            if (!ValidationUtil.isEmpty(transferCarIdList)) {
                transferCarIdList.forEach(carId -> {
                    CarStatusInfoDto carStatusInfo = new CarStatusInfoDto();
                    carStatusInfo.setSequenceNbr(carId);
                    carStatusInfo.setStatus(FireCarStatusEnum.执勤.getCode());
                    carStatusInfoDtoList.add(carStatusInfo);
                });
            }

            //修改调派车辆任务

            powerTransferCompanyResourcesService.updateByAlertCalledId(alertSubmittedDto.getAlertCalledId());
            // 更新所有车辆状态为执勤
            equipFeignClient.updateCarStatus(carStatusInfoDtoList);
//            //跟车辆状态
//            powerTransferCompanyResourcesService.update(new UpdateWrapper<PowerTransferCompanyResources>().eq("resources_id", transferCarIdList).set("status", FireCarStatusEnum.返队.getCode()));
        }


        //警情結案推送
        if(AlertBusinessTypeEnum.警情结案.getCode().equals(alertSubmittedDto.getBusinessTypeCode())) {

                //tuisongxinjingqing
                RequestData par=new RequestData();
                par.setAlertId(alertSubmittedDto.getAlertCalledId());
                List<AlertCalledZhDto> list4 = alertCalledService.alertCalledListByAlertStatus(null, null, par);

                String json=list4!=null&&list4.size()>0?JSONObject.toJSONString(list4.get(0), SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue):"";
                emqKeeper.getMqttClient().publish(topicJa, json.getBytes(), RuleConfig.DEFAULT_QOS, false);

        }



        // 4.发送任务消息
        // 4.1组织短信内容  废弃

        JSONObject submitContent = alertSubmittedDto.getSubmitContent();

        String feedBack = submitContent.get("editContent") != null ?  submitContent.get("editContent").toString(): "";


        // 4.2调用短信发送接口 废弃
        //  alertCalledAction.sendAlertCalleCmd(smsCode, mobiles, smsParams);\

        map.put("feedBack",feedBack);
        map.put("alertWay",alertWay);
        map.put("mobiles", StringUtils.join(mobiles,","));
        return map;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("报送失败，系统异常!");
        }
    }

    public void generateMob(AlertCalled alertCalled) throws ParseException, FileNotFoundException {
        AlertCalledMobDto report = new AlertCalledMobDto();

        report.setYear(String.valueOf(DateUtils.getYear(new Date())));
        report.setUnit(ValidationUtil.isEmpty(alertCalled.getUnitInvolved()) ? "" : alertCalled.getUnitInvolved());
        report.setAddress(ValidationUtil.isEmpty(alertCalled.getAddress()) ? "" : alertCalled.getAddress());
        report.setAlertType(ValidationUtil.isEmpty(alertCalled.getAlertType()) ? "" : alertCalled.getAlertType());
        report.setSourceType(ValidationUtil.isEmpty(alertCalled.getAlertSource()) ? "" : alertCalled.getAlertSource());
        report.setReportName(ValidationUtil.isEmpty(alertCalled.getContactUser()) ? "" : alertCalled.getContactUser());
        report.setConectPhone(ValidationUtil.isEmpty(alertCalled.getContactPhone()) ? "" : alertCalled.getContactPhone());
        report.setCallTime(ValidationUtil.isEmpty(alertCalled.getCallTime()) ? "" : DateUtils.convertDateToString(alertCalled.getCallTime(), DateUtils.DATE_TIME_PATTERN));


        String urlString="";
        report.setEndTime(DateUtils.convertDateToString(new Date(), DateUtils.DATE_TIME_PATTERN));

        // 查询第一次调派
        List<Map<String, Object>> first = alertSubmittedMapper.getFirst(alertCalled.getSequenceNbr());

        // 查询后续调派
        List<Map<String, Object>> other = alertSubmittedMapper.getFirst(alertCalled.getSequenceNbr());

        LinkedList<AlertCalledPowerInfoDto> list = new LinkedList<>();
        for(int i = 0; i <first.size(); i++) {
            AlertCalledPowerInfoDto dto = new AlertCalledPowerInfoDto();
            if(i == 0) {
                dto.setDisatchNum(String.valueOf(first.size()));
            }

            handleFunc(dto,first.get(i));
            LocalDateTime dateTime =  (LocalDateTime)first.get(i).get("recDate");
            Date date = Date.from(dateTime.toInstant(ZoneOffset.of("+8")));

            report.setToTime((DateUtils.dateFormat(date,DateUtils.HOUR_PATTERN)));

            report.setArriveTime((DateUtils.dateFormat(date,DateUtils.HOUR_PATTERN)));

            dto.setArriveTime((DateUtils.dateFormat(date,DateUtils.HOUR_PATTERN)));
            list.add(dto);
        }

        for(int i = 0; i <other.size(); i++) {
            AlertCalledPowerInfoDto dto = new AlertCalledPowerInfoDto();

            handleFunc(dto,first.get(i));
            LocalDateTime dateTime =  (LocalDateTime)first.get(i).get("recDate");
            Date date = Date.from(dateTime.toInstant(ZoneOffset.of("+8")));

            dto.setArriveTime((DateUtils.dateFormat(date,DateUtils.HOUR_PATTERN)));
            list.add(dto);
        }

        // 查询应急指挥辅屏值班人员
        List<Map<String, Object>> mapList = iDutyPersonService.listOnDutyPerson();
        List<AlertCallCommandDto> list1 = new ArrayList<>();
        mapList.forEach(e->{
            AlertCallCommandDto dto = new AlertCallCommandDto();
            dto.setName(e.get("userName").toString());
            dto.setDuty(e.get("postTypeName").toString());
            list1.add(dto);
        });

        if (mapList.size() == 0) {
            AlertCallCommandDto commandDto = new AlertCallCommandDto();
            commandDto.setName("");
            commandDto.setDuty("");
            list1.add(commandDto);
        }

        report.setAlertCallCommandDtoList(list1);

        report.setAlertCalledPowerInfoDtoList(list);

        if (!ValidationUtil.isEmpty(report)) {

            String os = System.getProperty("os.name");
            InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("templates/check-report-template.docx");
            String path = this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
//            String checkReportTemplatePath = this.getClass().getClassLoader().getResource("templates/check-report-template" +
//                    ".docx").getFile();

           // String filePath = this.getClass().getClassLoader().getResource("templates").getPath();
            String filePath = "";
            String fileName =  "";
            if(os.toLowerCase().startsWith("win")) {
                filePath = this.getClass().getClassLoader().getResource("templates").getPath();
                fileName = filePath + "/" +  System.currentTimeMillis() + ".docx";
            } else {
//                String [] arr = path.split("amos-boot-system-jcs-1.0.0.jar!");
//                System.out.println(arr[0].substring(0,arr[0].lastIndexOf("/")));
//                fileName = arr[0].substring(0,arr[0].lastIndexOf("/"))  + "/" + System.currentTimeMillis() + ".docx";
                fileName = "/opt/file/"+System.currentTimeMillis() + ".docx";
            }

            String newFileName= "";

            AlertCalledPowerInfoTablePolicy calledPowerInfoTablePolicy = new AlertCalledPowerInfoTablePolicy();
            AlertCallCommandTablePolicy alertCallCommandTablePolicy = new AlertCallCommandTablePolicy();

            Configure.ConfigureBuilder configureBuilder = Configure.newBuilder();
            configureBuilder.setElMode(ELMode.SPEL_MODE).bind("alertCalledPowerInfoDtoList", calledPowerInfoTablePolicy)
                    .bind("alertCallCommandDtoList", alertCallCommandTablePolicy).build();
            XWPFTemplate template = XWPFTemplate.compile(resourceAsStream, configureBuilder.build()).render(report);

            File file = new File(fileName);
            if (!file .getParentFile().exists()) {
                file .getParentFile().mkdirs();
            }
            if(!file .exists()) {
                try {
                    file .createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                file.setExecutable(true);
                file.setReadable(true);
                file.setWritable(true);
            }

            FileOutputStream out = new FileOutputStream(fileName);
            BufferedOutputStream bos = null;
            try {
                bos = new BufferedOutputStream(out);
                template.write(bos);
                bos.flush();
                out.flush();

                // docx 转 doc
                Document document = new Document();

                //拼接完整连接
                String pa1 = "";
                if(os.toLowerCase().startsWith("win")){
                    String pa =  fileName.substring(1);
                    document.loadFromFile(pa);
                    newFileName = System.currentTimeMillis()+".doc";
                    //保存结果文件
                    pa1  = newFileName.substring(1);
                    document.saveToFile(pa1, FileFormat.Doc);
                } else {
                    document.loadFromFile(fileName);
                    System.out.println(fileName);
                    newFileName  = "/opt/file/" +  System.currentTimeMillis()+".doc";
                    System.out.println(newFileName);
                    document.saveToFile(newFileName, FileFormat.Doc);
                    pa1 = newFileName;
                }
                System.out.println(pa1);

                FeignClientResult<Map<String, String>> date = Systemctl.fileStorageClient.updateCommonFile(WordConverterUtils.fileToMultipartFile(new File(pa1)));

                if (date != null) {
                    Map<String, String> map = date.getResult();
                    Iterator<String> it = map.keySet().iterator();
                    while (it.hasNext()) {
                        urlString=it.next();
                    }
                }
                System.out.println(urlString);

                // 更新警情信息
                alertCalled.setRecordUrl(urlString);
                alertCalledService.updateById(alertCalled);
            } catch (IOException e) {
                log.error("生成文档失败---------->");
                e.printStackTrace();
            } finally {
                try {
                    bos.close();
                    out.close();
                    template.close();

                    File file2 = new File(fileName);
                    if(file2.exists()) {
                        file2.delete();
                    }

                    File file1 = new File(newFileName);
                    if(file1.exists()) {
                        file1.delete();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    void handleFunc(AlertCalledPowerInfoDto dto,Map<String, Object> map) {
        if (map.containsKey("carName")) {
            dto.setCarName(map.get("carName").toString());
        }

        dto.setStation(map.get("companyName").toString());
        // 随车人员
        if (map.containsKey("id")) {
            List<PowerData> powerDataOne = powerTransferMapper.getPowerDataOne(Long.valueOf(map.get("id").toString()));
            if (!ValidationUtil.isEmpty(powerDataOne)) {
                dto.setPersonNum(String.valueOf(powerDataOne.size()));
            } else {
                dto.setPersonNum("0");
            }
        }
    }

    static int dangerListDataStartRow = 2; // 表头占两行

    static int dangerListDataStartRowNew = 1; // 表头占一行

    public static <T> Consumer<T> foreachWithIndex(BiConsumer<T, Integer> consumer) {
        class Obj {
            int i;
        }
        Obj obj = new Obj();
        return t -> {
            int index = obj.i++;
            consumer.accept(t, index);
        };
    }

    public static class AlertCalledPowerInfoTablePolicy extends DynamicTableRenderPolicy {

        @Override
        public void render(XWPFTable table, Object o) {
            if (ValidationUtil.isEmpty(o)) {
                table.removeRow(dangerListDataStartRow);
                return;
            }
            List<AlertCalledPowerInfoDto> reportDto = (List<AlertCalledPowerInfoDto>) o;

            List<RowRenderData> checkDangerList = Lists.newArrayList();
            reportDto.forEach(foreachWithIndex((report, index) -> {
                RowRenderData rowRenderData = RowRenderData.build(String.valueOf(reportDto.size() - index),
                        report.getStation(), report.getArriveTime(), report.getCarName(),report.getPersonNum(),report.getDisatchNum(),report.getDryPowder(),report.getFoam(),report.getOther());
                checkDangerList.add(rowRenderData);
            }));
            generateTableData(table, checkDangerList);
        }
    }

    public static class AlertCallCommandTablePolicy extends DynamicTableRenderPolicy {

        @Override
        public void render(XWPFTable table, Object o) {
            if (ValidationUtil.isEmpty(o)) {
                table.removeRow(dangerListDataStartRow);
                return;
            }
            List<AlertCallCommandDto> reportDto = (List<AlertCallCommandDto>) o;

            List<RowRenderData> checkDangerList = Lists.newArrayList();
            reportDto.forEach(foreachWithIndex((report, index) -> {
                RowRenderData rowRenderData = RowRenderData.build(String.valueOf(reportDto.size() - index),
                        report.getName(), report.getDuty());
                checkDangerList.add(rowRenderData);
            }));
            generateTableDataNew(table, checkDangerList);
        }

        private void generateTableDataNew(XWPFTable table, List<RowRenderData> dangerList) {
            if (!ValidationUtil.isEmpty(dangerList)) {
                // 表格渲染和列表数据下标相反，需要翻转一下列表
                List<RowRenderData> reverseList = Lists.reverse(dangerList);
                table.removeRow(dangerListDataStartRowNew);
                // 循环插入行
                int listLength = dangerList.size();
                for (int i = 0; i < listLength; i++) {
                    reverseList.get(i).getCellDatas().forEach(cellRenderData -> {
                        Style style = new Style();
                        style.setFontFamily("仿宋");
                        style.setFontSize(12);
                        cellRenderData.getRenderData().setStyle(style);
                    });
                    XWPFTableRow insertNewTableRow = table.insertNewTableRow(dangerListDataStartRowNew);
                    IntStream.range(2,6).forEach(j -> insertNewTableRow.createCell());
                    MiniTableRenderPolicy.Helper.renderRow(table, dangerListDataStartRowNew, reverseList.get(i));
                }

                TableTools.mergeCellsVertically(table, 0, 0, listLength);
            }
        }
    }

    public static void generateTableData(XWPFTable table, List<RowRenderData> dangerList) {
        String firstSize ="";
        if (!ValidationUtil.isEmpty(dangerList)) {
            firstSize = dangerList.get(0).getCellDatas().get(5).getRenderData().getText();
            int fSizs = Integer.parseInt(firstSize);

            // 表格渲染和列表数据下标相反，需要翻转一下列表
            List<RowRenderData> reverseList = Lists.reverse(dangerList);
            table.removeRow(dangerListDataStartRow);
            // 循环插入行
            int listLength = dangerList.size();
            for (int i = 0; i < fSizs; i++) {
                if(i == 0) {
                    TableStyle tableStyle = new TableStyle();
                    tableStyle.setAlign(Enum.forInt(2));
                    reverseList.get(i).getCellDatas().get(0).setCellStyle(tableStyle);
                    reverseList.get(i).getCellDatas().get(0).getRenderData().setText("增\n援\n力\n量");
                    Style style = new Style();
                    style.setFontFamily("宋体");
                    style.setFontSize(12);
                    style.setBold(true);
                    reverseList.get(i).getCellDatas().get(0).getRenderData().setStyle(style);
                } else {
                    reverseList.get(i).getCellDatas().forEach(cellRenderData -> {
                        Style style = new Style();
                        style.setFontFamily("仿宋");
                        style.setFontSize(12);
                        cellRenderData.getRenderData().setStyle(style);
                    });
                }

                XWPFTableRow insertNewTableRow = table.insertNewTableRow(dangerListDataStartRow);
                IntStream.range(5,14).forEach(j -> insertNewTableRow.createCell());
                MiniTableRenderPolicy.Helper.renderRow(table, dangerListDataStartRow, reverseList.get(i));
            }

            for (int i = fSizs; i < listLength  ; i++) {
              reverseList.get(i).getCellDatas().forEach(cellRenderData -> {
                        Style style = new Style();
                        style.setFontFamily("仿宋");
                        style.setFontSize(12);
                        cellRenderData.getRenderData().setStyle(style);
                    });
                XWPFTableRow insertNewTableRow = table.insertNewTableRow(dangerListDataStartRow);
                IntStream.range(5,14).forEach(j -> insertNewTableRow.createCell());
                MiniTableRenderPolicy.Helper.renderRow(table, dangerListDataStartRow, reverseList.get(i));
            }

            TableTools.mergeCellsVertically(table, 0, 0, fSizs + 1);

            if(listLength - fSizs > 1 ) {
                TableTools.mergeCellsVertically(table, 0, fSizs + 2 , listLength + 1);
            }
        }
    }

    /**
     * 短信报送对象
     *
     * @param alertSubmittedObjectList 报送对象列表
     * @param smsCode                  短信模板code
     * @param mobiles                  电话号码列表
     * @param smsParams                报送内容
     */
    public void saveAlertSubmittedObject(List<AlertSubmittedObject> alertSubmittedObjectList, String smsCode,
                                         Set<String> mobiles, HashMap<String, String> smsParams) {


//        alertSubmittedObjectServiceImpl.saveBatch(alertSubmittedObjectList);
        // 发送任务消息
        // 组织短信内容
        // 调用短信发送接口
        alertCalledAction.sendAlertCalleCmd(smsCode, mobiles, smsParams);
    }

    public void getAlertSubmittedContent(Long alertCalledId, ArrayList<TemplateDto> templateDtos, String companyName) throws IllegalAccessException, ParseException {
        AlertCalled alertCalled = alertCalledService.getById(alertCalledId);
        Map<String, Object> map = objectToMap(alertCalled);
        map.put("companyName", companyName);
        map.put("editContent", "可自编辑续报内容");

        AlertCalledObjsDto alertCalledVo  = (AlertCalledObjsDto) alertCalledService.selectAlertCalledByIdNoRedisNew(alertCalled.getSequenceNbr());

        /**
         * 构建警情报送规则对象
         */
        AlertCalledRo alertCalledRo = new AlertCalledRo();

        String replaceContent = RuleAlertCalledService.init(alertCalledRo,alertCalledVo);

        // 获取模板内容
        List<DataDictionary> dataDictionaries =
                dataDictionaryService.list(new QueryWrapper<DataDictionary>().eq("type",
                        "JQBSLX"));
        for (DataDictionary dataDictionary : dataDictionaries) {
            Template template = templateService.getOne(new QueryWrapper<Template>().eq("type_code",
                    dataDictionary.getCode()).eq("format", true));
            Map<String, String> definitions = new HashMap<>();
            definitions.put("$type",alertCalled.getAlertType());
            definitions.put("$callTime", DateUtils.dateTimeToDateString(alertCalled.getCallTime()));
            definitions.put("$replaceContent",replaceContent);
            definitions.put("$address",alertCalled.getAddress());
            definitions.put("$recDate", DateUtils.convertDateToString(alertCalled.getRecDate(), DateUtils.DATE_TIME_PATTERN));
            String content = getTaskInformation( template.getContent(),definitions);
            template.setContent(content);
            TemplateDto templateDto = new TemplateDto();
            BeanUtils.copyProperties(template, templateDto);
            templateDto.setData(map);
            templateDtos.add(templateDto);
        }
    }

    private String getTaskInformation(String content, Map<String, String> definitions) {
        int size = definitions.size();
        String[] keys = definitions.keySet().toArray(new String[size]);
        String[] values = definitions.values().toArray(new String[size]);
        return StringUtils.replaceEach(content, keys, values);
    }

    @Override
    public AlertSubmittedSMSDto getSchedulingContent(Long id) {
        return this.baseMapper.getSchedulingContent(id);
    }

    @Override
    public List<InstructionsZHDto> getInstructionsZHDtoList(Long id) {

        List<InstructionsZHDto> listInstructionsZHDto = new ArrayList<>();

        //获取接警录音
        List<VoiceRecordFileDto> voiceRecordFileDtos = voiceRecordFileService.listByAlertId(id);
        voiceRecordFileDtos.stream().forEach(voiceRecordFileDto -> {
            InstructionsZHDto instruct = new InstructionsZHDto(voiceRecordFileDto.getSequenceNbr(), "接警录音", voiceRecordFileDto.getRecDate(), voiceRecordFileDto.getFilePath(),null);
            listInstructionsZHDto.add(instruct);
        });

        //获取调派记录
        List<PowerTransferCompanyZHDto> listPowerTransferCompanyZHDto = powerTransferCompanyMapper.listPowerTransferCompanyZHDto(id);

        listPowerTransferCompanyZHDto.stream().forEach(PowerTransferCompanyZHDto -> {
            String content = "";
            if (PowerTransferCompanyZHDto.getIsDistributionAgencies()) {
                content = "调派" + PowerTransferCompanyZHDto.getCompanyName() + "前往" + PowerTransferCompanyZHDto.getAddress();
            } else {
                content = "调派" + PowerTransferCompanyZHDto.getCompanyName() + PowerTransferCompanyZHDto.getSubmissionContent() + "前往" + PowerTransferCompanyZHDto.getAddress();
            }
            InstructionsZHDto instruct = new InstructionsZHDto(PowerTransferCompanyZHDto.getSequenceNbr(), PowerTransferCompanyZHDto.getDispatchType(), PowerTransferCompanyZHDto.getRecDate(), content, null);
            listInstructionsZHDto.add(instruct);
        });


        //获取融合调度信息
        List<AlertSubmittedZHDto> listAlertSubmittedZHDto = alertSubmittedMapper.listAlertSubmittedZHDto(id);

        listAlertSubmittedZHDto.stream().forEach(AlertSubmittedZHDto -> {
            JSONObject js = JSONObject.parseObject(AlertSubmittedZHDto.getSubmissionContent());
            String content = "";

            switch (AlertSubmittedZHDto.getBusinessType()) {
                case "警情初报":


                    content = "通知" + AlertSubmittedZHDto.getCompanyName() + ":" + AlertSubmittedZHDto.getUserName() + "," + js.getString("address") + "发生" + js.getString("alertType");

                    break;
                case "警情续报":

                    content = "通知" + AlertSubmittedZHDto.getCompanyName() + ":" + AlertSubmittedZHDto.getUserName() + "," + "现场被困人数：" + js.getString("trappedNum") + "人伤亡人数：" + js.getString("casualtiesNum") + "人。";

                    break;
                case "非警情确认":

                    content = "通知" + AlertSubmittedZHDto.getCompanyName() + ":" + AlertSubmittedZHDto.getUserName() + "," + "此警情现场确认为假警情。";

                    break;
                case "警情结案":
                    content = "通知" + AlertSubmittedZHDto.getCompanyName() + ":" + AlertSubmittedZHDto.getUserName() + "," + "此警情已完场警情处置，警情已结案。";
                    break;

                default:

                    break;
            }
            InstructionsZHDto instruct = new InstructionsZHDto(AlertSubmittedZHDto.getSequenceNbr(), AlertSubmittedZHDto.getBusinessType(), AlertSubmittedZHDto.getSubmissionTime(), content,null);
            listInstructionsZHDto.add(instruct);

        });

        // 获取归并得警情信息
        LambdaQueryWrapper<AlertCalled> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(AlertCalled::getFatherAlert,id);
        List<AlertCalled> alertCalleds = alertCalledService.getBaseMapper().selectList(queryWrapper);
        alertCalleds.stream().forEach(e->{
            AlertSubmittedZHDto alertSubmittedZHDto = new AlertSubmittedZHDto();
            AlertCalledFormDto alertCalledFormDto = (AlertCalledFormDto) alertCalledService.selectAlertCalledByIdNoRedis(e.getSequenceNbr());
            alertSubmittedZHDto.setAlertCalledFormDto(alertCalledFormDto);
            alertSubmittedZHDto.setSequenceNbr(e.getSequenceNbr());
            alertSubmittedZHDto.setBusinessType("警情归并");
            alertSubmittedZHDto.setSubmissionTime(alertCalledFormDto.getAlertCalled().getCallTime());
            alertSubmittedZHDto.setCompanyName(alertCalledFormDto.getAlertCalled().getCompanyName());
            alertSubmittedZHDto.setUserName(alertCalledFormDto.getAlertCalled().getRecUserName());
            InstructionsZHDto instruct = new InstructionsZHDto(alertSubmittedZHDto.getSequenceNbr(), alertSubmittedZHDto.getBusinessType(), alertSubmittedZHDto.getSubmissionTime(), null, alertSubmittedZHDto.getAlertCalledFormDto());
            listInstructionsZHDto.add(instruct);
        });

        //排序时间倒序
        /* Bug 2613 修改排序 按照发送时间排序 2021-09-01 陈召 开始*/
        Collections.sort(listInstructionsZHDto, new Comparator<InstructionsZHDto>() {
            @Override
            public int compare(InstructionsZHDto o1, InstructionsZHDto o2) {
                long i = o2.getSubmissionTime().getTime() - o1.getSubmissionTime().getTime();
                if (i == 0) {
                    return (int) (o2.getSubmissionTime().getTime() - o1.getSubmissionTime().getTime());
                }
                return (int) i;
            }
        });
        /* Bug 2613 修改排序 按照发送时间排序 2021-09-01 陈召 结束*/
        return listInstructionsZHDto;

    }

    /**
     * 将Object对象里面的属性和值转化成Map对象
     *
     * @param obj 源对象
     * @return 转化结果
     * @throws IllegalAccessException IllegalAccessException
     */
    @SuppressWarnings("unchecked")
    public static Map<String, Object> objectToMap(Object obj) throws IllegalAccessException {
        Map<String, Object> map = new HashMap<>();
        Class<?> clazz = obj.getClass();
        Field[] fields = clazz.getDeclaredFields();

        for (Field field : fields) {
            field.setAccessible(true);
            String fieldName = field.getName();
            if ("dynamicFormAlert".equalsIgnoreCase(fieldName)) {
                List<FormValue> dynamicFormAlert = (List<FormValue>) field.get(obj);
                for (FormValue formValue : dynamicFormAlert) {
                    map.put(formValue.getLabel(), formValue.getValue());
                }
            } else {
                Object value = field.get(obj);
                map.put(fieldName, value);
            }
        }
        return map;
    }



    @SuppressWarnings("unchecked")
    public void ruleCallbackActionForPowerTransferForCar(String smsCode, List sendIds, Object object, List<String> pList)
            throws IllegalAccessException, MqttPersistenceException, MqttException {
        List<AlertSubmittedObject> alertSubmittedObjectList = Lists.newArrayList();

        Set<String> mobiles = new HashSet<>();
        HashMap<String, String> smsParams = new HashMap<>();
        String alertCalledId = null;
        Set<Map<String, Object>> userIdList = new HashSet<Map<String, Object>>();
        // 判断当前的规则中是否指定了给当前的车辆驾驶员
        boolean designatedDriver = false;

        for (Object id : sendIds) {
            JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(id));
            if (jsonObject.containsKey("type") && jsonObject.getString("type").equals(AlertStageEnums.BD.getCode())) {
                designatedDriver = true;
            }
        }

        List<Map<String, Object>> orgUsers = new LinkedList<>();
        String sCode = "";
        if (object instanceof AlertCallePowerTransferRo) {
            AlertCallePowerTransferRo calledRo = (AlertCallePowerTransferRo) object;
            String alertSubmittedId = calledRo.getAlertSubmittedId();
            alertCalledId = calledRo.getSequenceNbr();
            AlertCalled alertCalled =   alertCalledService.getAlertCalledById(Long.parseLong(alertSubmittedId));
            //响应级别
            String responseLevelString ="";
            if(alertCalled!=null && alertCalled.getResponseLevel()!=null) {
                responseLevelString = alertCalled.getResponseLevel();
            }
            //先获取消救部领导、消救部值班人员信息
            sendIds.stream().forEach(e -> {
                JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(e));
                // 消救部
                if (jsonObject.containsKey("airportUnit")) {
                    String departmentName=	jsonObject.getString("name");
                    if (jsonObject.containsKey("airportUnit")) { {
                        List<Map<String, Object>> mapList = dynamicFormInstanceMapper.getFireRescueDepartmentStaff(departmentName,null);
                        userIdList.addAll(mapList);
                    }

                        if(jsonObject.containsKey("onDuty")) {
                            List<Map<String, Object>> mapList = dynamicFormInstanceMapper.getDutyPersonByTeamIdAndCarId(DateUtils.getDateNowShortStr(),departmentName);
                            userIdList.addAll(mapList);
                        }
                    }
                }
            });
            List<Object> companyDetail = JSONArray.parseArray(JSON.toJSON(calledRo.getCompany()).toString(),Object.class);
            for (Object powerTransferCompanyDto : companyDetail) {
                PowerTransferCompanyDto powerDto =	JSONObject.parseObject(JSON.toJSON(powerTransferCompanyDto).toString(), PowerTransferCompanyDto.class);
                Long companyId = powerDto.getCompanyId();
                String companyName = powerDto.getCompanyName();
                StringBuffer resourcesNum = new StringBuffer();
                Set<Map<String, Object>> sendUserIds = new HashSet<Map<String, Object>>();
                //FireTeam fireTeam= fireTeamServiceImpl.getById(companyId);
                String alertTypeCode = calledRo.getAlertTypeCode();
                FireTeam fireTeam= fireTeamServiceImpl.getById(companyId);
                sendIds.stream().forEach(e -> {
                    JSONObject jsonObject1 = JSONObject.parseObject(JSONObject.toJSONString(e));
                    if (jsonObject1.containsKey("type") && (jsonObject1.getString("type").equals(AlertStageEnums.DD.getCode()))) {
                        String [] groupCode = jsonObject1.getString("fireBrigade").split(",");
                        List<String> positionType= Arrays.asList(groupCode);
                        if (jsonObject1.containsKey("fireBrigade")) { {

                            List<Map<String, Object>> mapList = dynamicFormInstanceMapper.getFireRescueDepartmentStaff(fireTeam.getCompanyName(),positionType);
                            sendUserIds.addAll(mapList);
                        }
                            if(jsonObject1.containsKey("onDuty")) {
                                List<Map<String, Object>> mapList = dynamicFormInstanceMapper.getDutyPersonByTeamIdAndCarId(DateUtils.getDateNowShortStr(),fireTeam.getCompanyName());
                                sendUserIds.addAll(mapList);
                            }
                        }
                    }else if (jsonObject1.containsKey("type") && (jsonObject1.getString("type").equals(AlertStageEnums.ZD.getCode()))) {
                        String [] groupCode = jsonObject1.get("fireBrigade").toString().split(",");
                        List<String> positionType= Arrays.asList(groupCode);
                        String departmentName=	jsonObject1.getString("name");
                        if (jsonObject1.containsKey("fireBrigade")) { {
                            List<Map<String, Object>> mapList = dynamicFormInstanceMapper.getFireRescueDepartmentStaff(departmentName,positionType);
                            sendUserIds.addAll(mapList);
                        }
                            if(jsonObject1.containsKey("onDuty")) {
                                List<Map<String, Object>> mapList = dynamicFormInstanceMapper.getDutyPersonByTeamIdAndCarId(DateUtils.getDateNowShortStr(),departmentName);
                                sendUserIds.addAll(mapList);
                            }
                        }
                    }
                });
                sendUserIds.addAll(userIdList);
                smsCode = AlertBusinessTypeEnum.力量调派.getSms_code();
                // 组装人员信息

                for (Map<String, Object> orgUser : sendUserIds) {
                    AlertSubmittedObject alertSubmittedObject = new AlertSubmittedObject();
                    alertSubmittedObject.setAlertSubmittedId(Long.parseLong(alertSubmittedId));
                    alertSubmittedObject.setType(false);
                    alertSubmittedObject.setCompanyId(companyId);
                    alertSubmittedObject.setCompanyName(companyName);
                    alertSubmittedObject.setType(false);
                    alertSubmittedObject.setUserId(Long.parseLong(orgUser.get("userId").toString()));
                    alertSubmittedObject.setUserName(orgUser.get("userName").toString());

                    // 将发送人放入 list
                    pList.add(orgUser.get("userName").toString());

                    if (!ValidationUtil.isEmpty(orgUser.get("telephone"))) {
                        mobiles.add((String) orgUser.get("telephone"));
                        alertSubmittedObject.setUserPhone((String) orgUser.get("telephone"));
                    }
                    alertSubmittedObjectList.add(alertSubmittedObject);
                }
                smsParams.put("callTimeStr", calledRo.getCallTimeStr());
                smsParams.put("address", calledRo.getAddress());
                smsParams.put("content", calledRo.getContent());
                smsParams.put("trappedNum", calledRo.getTrappedNum());
                smsParams.put("casualtiesNum", calledRo.getCasualtiesNum());
                smsParams.put("companyName", calledRo.getCompanyName());
                smsParams.put("contactUser", calledRo.getContactUser());
                smsParams.put("contactPhone", calledRo.getContactPhone());
                smsParams.put("alertType", calledRo.getAlertType());
                List<PowerTransferCompanyResourcesDto> list = powerDto
                        .getPowerTransferCompanyResourcesDtoList();
                if (list != null && list.size() > 0) {
                    for (PowerTransferCompanyResourcesDto i : list) {
                        String carName = i.getResourcesName();
                        String resourceName = i.getResourcesNum();
                        String type = i.getType();
                        resourcesNum.append("车辆" + type);
                        resourcesNum.append("车牌号" + carName + " " + resourceName);
                        resourcesNum.append("、");
                        if (designatedDriver) {
                            // 发送单个车辆的信息数据到客户
                            smsParams.put("resourcesNum",
                                    resourcesNum.toString().substring(resourcesNum.toString().length() - 2));
                            List<AlertSubmittedObject> alertSubmittedObjectListSub = Lists.newArrayList();
                            Map<String, Object> map = dynamicFormInstanceMapper
                                    .getCurentCarIsUserPhone(Long.parseLong(i.getResourcesId()));
                            AlertSubmittedObject alertSubmittedObjectSub = new AlertSubmittedObject();
                            alertSubmittedObjectSub.setAlertSubmittedId(Long.parseLong(alertSubmittedId));
                            alertSubmittedObjectSub.setType(false);
                            alertSubmittedObjectSub.setCompanyId(companyId);
                            alertSubmittedObjectSub.setCompanyName(companyName);
                            alertSubmittedObjectSub.setType(false);
                            if(map==null || !map.containsKey("userId")) {
                                continue;
                            }
                            alertSubmittedObjectSub.setUserId(Long.parseLong(map.get("userId").toString()));
                            alertSubmittedObjectSub.setUserName(map.get("userName").toString());
                            //
                            pList.add(map.get("userName").toString());
                            Set<String> mobile =null;
                            List<String> userList=null;
                            if (!ValidationUtil.isEmpty(map.get("mobilePhone"))) {
                                mobile = new HashSet<String>() {
                                    {
                                        add(map.get("mobilePhone").toString());
                                    }
                                };
                                userList=new ArrayList<String>();
                                if(!ValidationUtil.isEmpty(map.get("amosId"))) {
                                    userList.add(map.get("amosId").toString());
                                }
                                alertSubmittedObjectSub.setUserPhone(map.get("mobilePhone").toString());
                            }
                            alertSubmittedObjectListSub.add(alertSubmittedObjectSub);
                          //  alertSubmittedObjectServiceImpl.saveBatch(alertSubmittedObjectListSub);
                            // 调用短信发送接口
                            alertCalledAction.sendAlertCalleCmd(sCode, mobile, smsParams);
                            Map<String, String> besidesMap = new HashMap<String, String>();
                            besidesMap.put("responseLevelString", responseLevelString);
                            besidesMap.put("alterId", alertCalledId);
                            if(userList.size()>0) {
                                pushPowerTransferToAppAndWeb(AlertBusinessTypeEnum.力量调派.getCode(),besidesMap,smsParams,userList);
                            }

                            emqKeeper.getMqttClient().publish(topic, alertCalledId.getBytes(), RuleConfig.DEFAULT_QOS,
                                    false);
                        }
                    }
                }
                String resourcesNumStr = resourcesNum.toString();
                List<String> userList= new ArrayList<String>();
                sendUserIds.stream().forEach(i -> {
                    if (i.containsKey("mobilePhone")) {
                        mobiles.add(i.get("mobilePhone").toString());
                    }
                    if (i.containsKey("amosId")&& !ValidationUtil.isEmpty(i.get("amosId"))) {
                        userList.add(i.get("amosId").toString());
                    }
                });
                smsParams.put("resourcesNum", resourcesNumStr.substring(resourcesNumStr.length() - 2));
                // 短信报送对象
                // alertSubmittedObjectServiceImpl.saveBatch(alertSubmittedObjectList);
                // 发送任务消息
                // 组织短信内容
                // 调用短信发送接口
                try {
                    alertCalledAction.sendAlertCalleCmd(smsCode, mobiles, smsParams);
                } catch (Exception e) {
                }
                Map<String, String> besidesMap = new HashMap<String, String>();
                besidesMap.put("responseLevelString", responseLevelString);//响应级别
                besidesMap.put("alterId", alertCalledId);
                if(userList.size()>0) {
                    pushPowerTransferToAppAndWeb(AlertBusinessTypeEnum.力量调派.getCode(),besidesMap,smsParams,userList);
                }
                emqKeeper.getMqttClient().publish(topic, alertCalledId.getBytes(), RuleConfig.DEFAULT_QOS, false);
            }
        }

    }

    @SuppressWarnings("unchecked")
    public void ruleCallbackActionForPowerTransferForSurvBrigade(String smsCode, List sendIds, Object object, List<String> pList) throws MqttPersistenceException, MqttException {

        List<AlertSubmittedObject> alertSubmittedObjectList = Lists.newArrayList();

        Set<String> mobiles = new HashSet<>();
        HashMap<String, String> smsParams = new HashMap<>();
        String alertCalledId = null;
        if (object instanceof AlertCallePowerTransferRo) {
            AlertCallePowerTransferRo calledRo = (AlertCallePowerTransferRo) object;
            String alertSubmittedId = calledRo.getAlertSubmittedId();
            alertCalledId = calledRo.getSequenceNbr();
            Set<Map<String, Object>> userIds = new HashSet<Map<String, Object>>();
            List<Object> companyDetail =JSONArray.parseArray(JSON.toJSON(calledRo.getCompany()).toString(),Object.class);
            for(Object e:sendIds) {
                JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(e));
                if(jsonObject.containsKey("type") &&( (jsonObject.getString("type").equals(AlertStageEnums.ZH.getCode())) || jsonObject.getString("type").equals(AlertStageEnums.XJ.getCode()))) {
                    String departmentName=	jsonObject.getString("name");
                    if (jsonObject.containsKey("airportUnit")) { {
                        List<Map<String, Object>> mapList = dynamicFormInstanceMapper.getFireRescueDepartmentStaff(departmentName,null);
                        userIds.addAll(mapList);
                    }
                        if(jsonObject.containsKey("onDuty")) {
                            List<Map<String, Object>> mapList = dynamicFormInstanceMapper.getDutyPersonByTeamIdAndCarId(DateUtils.getDateNowShortStr(),departmentName);
                            userIds.addAll(mapList);
                        }
                    }
                }
            }
            for (Object powerTransferCompanyDto : companyDetail) {
                Set<Map<String, Object>> sendUserIds = new HashSet<Map<String, Object>>();
                PowerTransferCompanyDto powerDto =	JSONObject.parseObject(JSON.toJSON(powerTransferCompanyDto).toString(), PowerTransferCompanyDto.class);
                Long companyId = powerDto.getCompanyId();
                String companyName = powerDto.getCompanyName();
                FireTeam fireTeam= fireTeamServiceImpl.getById(companyId);

                for(Object sendObject:sendIds) {
                    JSONObject jsonObject1 = JSONObject.parseObject(JSONObject.toJSONString(sendObject));
                    if (jsonObject1.containsKey("type") && (jsonObject1.getString("type").equals(AlertStageEnums.监控大队.getCode()))) {
                        if(jsonObject1.containsKey("onDuty")) {
                            List<Map<String, Object>> dutyList = dynamicFormInstanceMapper.getDutyPersonByTeamIdAndCarId(
                                    DateUtils.getDateNowShortStr(), fireTeam.getCompanyName());
                            sendUserIds.addAll(dutyList);
                        }
                        if (jsonObject1.containsKey("airportUnit")) { {
                            List<Map<String, Object>> mapList = dynamicFormInstanceMapper.getFireRescueDepartmentStaff( fireTeam.getCompanyName(),null);
                            sendUserIds.addAll(mapList);
                        }
                        }
                    }
                }
                sendUserIds.addAll(userIds);
                smsCode = AlertBusinessTypeEnum.力量调派.getSms_code();
                // 组装人员信息

                for (Map<String, Object> orgUser : sendUserIds) {
                    AlertSubmittedObject alertSubmittedObject = new AlertSubmittedObject();
                    alertSubmittedObject.setAlertSubmittedId(Long.parseLong(alertSubmittedId));
                    alertSubmittedObject.setType(false);
                    alertSubmittedObject.setCompanyId(companyId);
                    alertSubmittedObject.setCompanyName(companyName);
                    alertSubmittedObject.setType(false);
                    alertSubmittedObject.setUserId(Long.parseLong(orgUser.get("userId").toString()));
                    alertSubmittedObject.setUserName(orgUser.get("userName").toString());
                    pList.add(orgUser.get("userName").toString());

                    if (!ValidationUtil.isEmpty(orgUser.get("telephone"))) {
                        mobiles.add((String) orgUser.get("telephone"));
                        alertSubmittedObject.setUserPhone((String) orgUser.get("telephone"));
                    }
                    alertSubmittedObjectList.add(alertSubmittedObject);
                }
                smsParams.put("callTimeStr", calledRo.getCallTimeStr());
                smsParams.put("address", calledRo.getAddress());
                smsParams.put("content", calledRo.getContent());
                smsParams.put("trappedNum", calledRo.getTrappedNum());
                smsParams.put("casualtiesNum", calledRo.getCasualtiesNum());
                smsParams.put("companyName", calledRo.getCompanyName());
                smsParams.put("contactUser", calledRo.getContactUser());
                smsParams.put("contactPhone", calledRo.getContactPhone());
                smsParams.put("alertType", calledRo.getAlertType());

                List<String> userList= new ArrayList<String>();
                sendUserIds.stream().forEach(i -> {
                    if (i.containsKey("mobilePhone")) {
                        mobiles.add(i.get("mobilePhone").toString());
                    }
                    if (i.containsKey("amosId")&& !ValidationUtil.isEmpty(i.get("amosId"))) {
                        userList.add(i.get("amosId").toString());
                    }
                });
                smsParams.put("resourcesNum", companyName);
                // 短信报送对象
              //  alertSubmittedObjectServiceImpl.saveBatch(alertSubmittedObjectList);
                // 发送任务消息
                // 组织短信内容
                // 调用短信发送接口
                try {
                    alertCalledAction.sendAlertCalleCmd(smsCode, mobiles, smsParams);
                }catch(Exception e){

                }
                Map<String, String> besidesMap = new HashMap<String, String>();
                besidesMap.put("alterId", alertCalledId);
                if(userList.size()>0) {
                    pushPowerTransferToAppAndWeb(AlertBusinessTypeEnum.力量调派.getCode(),besidesMap,smsParams,userList);
                }
                emqKeeper.getMqttClient().publish(topic, alertCalledId.getBytes(), RuleConfig.DEFAULT_QOS, false);
            }
        }
    }





    public void ruleCallbackActionForPowerTransferForAid(String smsCode, List sendIds, Object object, List<String> pList) throws MqttPersistenceException, MqttException {

        List<AlertSubmittedObject> alertSubmittedObjectList = Lists.newArrayList();

        Set<String> mobiles = new HashSet<>();

        Set<Map<String, Object>> userIds = new HashSet<Map<String, Object>>();

        HashMap<String, String> smsParams = new HashMap<>();
        String alertCalledId = null;
        if (object instanceof AlertCallePowerTransferRo) {
            AlertCallePowerTransferRo calledRo = (AlertCallePowerTransferRo) object;
            String alertSubmittedId = calledRo.getAlertSubmittedId();
            alertCalledId = calledRo.getSequenceNbr();
            //List<FireTeam> fireTeamList= new ArrayList<FireTeam>();
            List<Object> companyDetail =JSONArray.parseArray(JSON.toJSON(calledRo.getCompany()).toString(),Object.class);
            //获取急救科、消救部人员信息
            for(Object e:sendIds) {
                JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(e));
                if(jsonObject.containsKey("type") &&( (jsonObject.getString("type").equals(AlertStageEnums.ZH.getCode())) || jsonObject.getString("type").equals(AlertStageEnums.XJ.getCode()))) {
                    String departmentName=	jsonObject.getString("name");
                    if (jsonObject.containsKey("airportUnit")) { {
                        List<Map<String, Object>> mapList = dynamicFormInstanceMapper.getFireRescueDepartmentStaff(departmentName,null);
                        userIds.addAll(mapList);
                    }

                        if(jsonObject.containsKey("onDuty")) {
                            List<Map<String, Object>> mapList = dynamicFormInstanceMapper.getDutyPersonByTeamIdAndCarId(DateUtils.getDateNowShortStr(),departmentName);
                            userIds.addAll(mapList);
                        }
                    }
                }
            }
            //获取对应急救站的当日值班员信息
            for (Object powerTransferCompanyDto : companyDetail) {
                Set<Map<String, Object>> sendUserIds = new HashSet<Map<String, Object>>();
                PowerTransferCompanyDto powerDto =	JSONObject.parseObject(JSON.toJSON(powerTransferCompanyDto).toString(), PowerTransferCompanyDto.class);
                Long companyId = powerDto.getCompanyId();
                String companyName = powerDto.getCompanyName();
                FireTeam fireTeam= fireTeamServiceImpl.getById(companyId);//这个公司ID实际上是120急救站的id值
                //fireTeamList.add(fireTeam);
                for(Object e:sendIds) {
                    JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(e));
                    //获取120急救站的规则
                    if (jsonObject.containsKey("type") && (jsonObject.getString("type").equals(AlertStageEnums.JJZ.getCode()))) {
                        if(!jsonObject.containsKey("onDuty")) {
                            continue;
                        }
                        //fireTeamList.stream().forEach(i->{
                        //获取120急救排版值班的人员信息
                        List<Map<String, Object>> dutyList = dynamicFormInstanceMapper.getDutyPersonByTeamIdAndAirId(
                                DateUtils.getDateNowShortStr(), fireTeam.getCompanyName());
                        sendUserIds.addAll(dutyList);
                        //});

                    }
                }
                sendUserIds.addAll(userIds);
                smsCode = AlertBusinessTypeEnum.力量调派.getSms_code();
                // 组装人员信息

                for (Map<String, Object> orgUser : sendUserIds) {
                    AlertSubmittedObject alertSubmittedObject = new AlertSubmittedObject();
                    alertSubmittedObject.setAlertSubmittedId(Long.parseLong(alertSubmittedId));
                    alertSubmittedObject.setCompanyId(companyId);
                    alertSubmittedObject.setCompanyName(companyName);
                    alertSubmittedObject.setType(false);
                    alertSubmittedObject.setUserId(Long.parseLong(orgUser.get("userId").toString()));
                    alertSubmittedObject.setUserName(orgUser.get("userName").toString());
                    pList.add(orgUser.get("userName").toString());

                    if (!ValidationUtil.isEmpty(orgUser.get("mobilePhone"))) {
                        mobiles.add((String) orgUser.get("mobilePhone"));
                        alertSubmittedObject.setUserPhone(orgUser.get("mobilePhone").toString());
                    }
                    alertSubmittedObjectList.add(alertSubmittedObject);
                }
                smsParams.put("callTimeStr", calledRo.getCallTimeStr());
                smsParams.put("address", calledRo.getAddress());
                smsParams.put("content", calledRo.getContent());
                smsParams.put("trappedNum", calledRo.getTrappedNum());
                smsParams.put("casualtiesNum", calledRo.getCasualtiesNum());
                smsParams.put("companyName", calledRo.getCompanyName());
                smsParams.put("contactUser", calledRo.getContactUser());
                smsParams.put("contactPhone", calledRo.getContactPhone());
                smsParams.put("alertType", calledRo.getAlertType());
                List<String> userList= new ArrayList<String>();
                sendUserIds.stream().forEach(i -> {
                    if (i.containsKey("mobilePhone")) {
                        mobiles.add(i.get("mobilePhone").toString());
                    }
                    if (i.containsKey("amosId")&& !ValidationUtil.isEmpty(i.get("amosId"))) {
                        userList.add(i.get("amosId").toString());
                    }
                });
                smsParams.put("resourcesNum", companyName);
                // 短信报送对象
              //  alertSubmittedObjectServiceImpl.saveBatch(alertSubmittedObjectList);
                // 发送任务消息
                // 组织短信内容
                // 调用短信发送接口
                try {
                    alertCalledAction.sendAlertCalleCmd(smsCode, mobiles, smsParams);
                }catch (Exception e) {// TODO: handle exception

                }
                Map<String, String> besidesMap = new HashMap<String, String>();
                besidesMap.put("alterId", alertCalledId);
                if(userList.size()>0) {
                    pushPowerTransferToAppAndWeb(AlertBusinessTypeEnum.力量调派.getCode(),besidesMap,smsParams,userList);
                }

                emqKeeper.getMqttClient().publish(topic, alertCalledId.getBytes(), RuleConfig.DEFAULT_QOS, false);
            }
        }
    }

    /**
     * app消息web 消息推送
     * @param
     * @throws MqttPersistenceException
     * @throws MqttException
     */
    public void pushPowerTransferToAppAndWeb(String type,Map<String, String> besidesMap, HashMap<String, String> smsParams, List<String> userList){

        PushMessageWebAndAppRo pushMessageWebAndAppRo  = new PushMessageWebAndAppRo();
        pushMessageWebAndAppRo.setRelationId(besidesMap.get("alterId"));
        pushMessageWebAndAppRo.setRecivers(userList);
        pushMessageWebAndAppRo.setCategory(RuleConstant.NOTIFY);
        pushMessageWebAndAppRo.setIsSendApp(true);
        pushMessageWebAndAppRo.setIsSendWeb(true);
        pushMessageWebAndAppRo.setRuleType(type);
        pushMessageWebAndAppRo.setMsgType(this.msgType);
        pushMessageWebAndAppRo.setTerminal(RuleConstant.APP_WEB);
        Map<String,String> map= new HashMap<String,String>();
        //map.put("url", "disasterPage");
        map.put("sequenceNbr", besidesMap.get("alterId"));

        if(AlertBusinessTypeEnum.警情结案.getCode().equals(type)) {
            pushMessageWebAndAppRo.setName("消息");
            pushMessageWebAndAppRo.setStartTime(besidesMap.get("startTime"));
            pushMessageWebAndAppRo.setEndTime(besidesMap.get("endTime"));
            pushMessageWebAndAppRo.setAddress(smsParams.get("address"));
            pushMessageWebAndAppRo.setRuleType("endAlert");
        }
        if(AlertBusinessTypeEnum.非警情确认.getCode().equals(type)) {
            pushMessageWebAndAppRo.setName("消息");
            pushMessageWebAndAppRo.setSendTime(smsParams.get("callTimeStr"));
            pushMessageWebAndAppRo.setAddress(smsParams.get("address"));
            pushMessageWebAndAppRo.setRuleType("notAlert");
        }
        if(AlertBusinessTypeEnum.警情续报.getCode().equals(type)) {
            pushMessageWebAndAppRo.setName("消息");
            pushMessageWebAndAppRo.setCompanyName(smsParams.get("alertType"));
            pushMessageWebAndAppRo.setAddress(smsParams.get("address"));
            pushMessageWebAndAppRo.setSendTime(besidesMap.get("sendTime"));
            pushMessageWebAndAppRo.setTransferLocation(smsParams.get("replaceContent"));
            pushMessageWebAndAppRo.setTrappedNum(smsParams.get("trappedNum"));//被困人数
            pushMessageWebAndAppRo.setCasualtiesNum(smsParams.get("casualtiesNum"));//伤亡人数
            pushMessageWebAndAppRo.setRuleType("followReportAlert");
        }
        if(AlertBusinessTypeEnum.力量调派.getCode().equals(type)) {
            //map.put("url", "powerInformationPage");
            pushMessageWebAndAppRo.setName(AlertBusinessTypeEnum.力量调派.getName());
            pushMessageWebAndAppRo.setCompanyName(smsParams.get("resourcesNum"));
            pushMessageWebAndAppRo.setAddress(smsParams.get("address"));
            pushMessageWebAndAppRo.setSendTime(smsParams.get("callTimeStr"));
            if(StringUtils.isNotBlank(besidesMap.get("transferLocation"))) {
                pushMessageWebAndAppRo.setTransferLocation(besidesMap.get("responseLevelString"));//响应级别
                pushMessageWebAndAppRo.setRuleType("fullTime");
            }else {
                pushMessageWebAndAppRo.setRuleType("monitor");
            }
        }
        if(AlertBusinessTypeEnum.警情初报.getCode().equals(type)) {
            pushMessageWebAndAppRo.setRuleType("reportAlert");
            pushMessageWebAndAppRo.setName(AlertBusinessTypeEnum.警情初报.getName());
            pushMessageWebAndAppRo.setSendTime(besidesMap.get("sendTime"));
            pushMessageWebAndAppRo.setCompanyName(smsParams.get("companyName"));//发送单位
            pushMessageWebAndAppRo.setAddress(smsParams.get("address"));
            pushMessageWebAndAppRo.setFireSituation(smsParams.get("fireSituation"));//火势情况
            pushMessageWebAndAppRo.setTrappedNum(smsParams.get("trappedNum"));//被困人数
            pushMessageWebAndAppRo.setCasualtiesNum(smsParams.get("casualtiesNum"));//伤亡人数
        }
        pushMessageWebAndAppRo.setExtras(map);;
        try {

            ruleTrigger.publish(pushMessageWebAndAppRo, "消息/addAlterMessageCheck", new String[0]);
        } catch (Exception e) {
        }
    }

}
