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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.SystemClock;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Maps;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.entity.BaseEntity;
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.RedisKey;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.common.api.dto.AttachmentDto;
import com.yeejoin.amos.boot.module.common.api.service.ISourceFileService;
import com.yeejoin.amos.boot.module.elevator.api.dto.*;
import com.yeejoin.amos.boot.module.elevator.api.entity.*;
import com.yeejoin.amos.boot.module.elevator.api.enums.AlertStageEnums;
import com.yeejoin.amos.boot.module.elevator.api.enums.DispatchPaperEnums;
import com.yeejoin.amos.boot.module.elevator.api.enums.EquipmentClassifityEnum;
import com.yeejoin.amos.boot.module.elevator.api.enums.TzsCommonParam;
import com.yeejoin.amos.boot.module.elevator.api.mapper.AlertCalledMapper;
import com.yeejoin.amos.boot.module.elevator.api.service.IAlertCalledService;
import com.yeejoin.amos.boot.module.elevator.api.service.IRescueStationService;
import com.yeejoin.amos.boot.module.elevator.api.service.TzsAuthService;
import com.yeejoin.amos.boot.module.elevator.biz.utils.BeanDtoVoUtils;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.text.StrBuilder;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.redisson.api.RAtomicLong;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.DateUtil;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;

import static com.alibaba.fastjson.JSON.parseArray;

/**
 * 警情接警填报记录服务实现类
 *
 * @author litw
 * @date 2021-08-03
 */
@Service
public class AlertCalledServiceImpl extends BaseService<AlertCalledDto,AlertCalled,AlertCalledMapper> implements IAlertCalledService {

    @Autowired
    RedisUtils redisUtils;

    @Value("${redis.cache.failure.time}")
    private long time;

    @Autowired
    private AlertFormValueServiceImpl iAlertFormValueService;

    @Autowired
    TemplateServiceImpl templateService;

    @Autowired
    private ESAlertCalledService eSAlertCalledService;

    @Autowired
    private ElevatorServiceImpl iElevatorService;

    @Autowired
    AlertCalledMapper alertCalledMapper;

    @Autowired
    RescueProcessServiceImpl rescueProcessServiceImpl;

    @Autowired
    RepairConsultServiceImpl repairConsultServiceImpl;

    @Autowired
    DispatchPaperServiceImpl dispatchPaperService;

    @Autowired
    DispatchTaskServiceImpl dispatchTaskService;

    @Autowired
    ISourceFileService ISourceFileService;

    @Autowired
    VoiceRecordFileServiceImpl voiceRecordFileServiceImpl;

    @Autowired
    TzsAuthService tzsAuthService;

    @Autowired
    TzsCitInfoServiceImpl citInfoService;

    @Autowired
    CtiServiceImpl ctiService;

    @Autowired
    DataDictionaryServiceImpl iDataDictionaryService;

    @Value("${duty.seats.role.ids}")
    private String dutySeatsRoleIds;
    @Autowired
    RepairConsultServiceImpl repairConsultService;

    private RedissonClient redissonClient;

    private RAtomicLong rAtomicLong;

    @Autowired
    ElevatorServiceImpl elevatorServiceImpl;
    @Autowired
    IRescueStationService iRescueStationService;
    @Autowired
    DispatchTaskServiceImpl dispatchTaskServiceImpl;
    @Autowired
    DispatchPaperServiceImpl dispatchPaperServiceImpl;
    @Autowired

    @Value("classpath:/json/emergencyInformation.json")
    private Resource emergencyInformation;
    @Value("classpath:/json/emergencyBasic.json")
    private Resource emergencyBasic;
    @Value("classpath:/json/dispatchRecordFirst.json")
    private Resource dispatchRecordFirst;
    @Value("classpath:/json/dispatchRecordSecond.json")
    private Resource dispatchRecordSecond;
    @Value("classpath:/json/dispatchRecordPower.json")
    private Resource dispatchRecordPower;
    @Value("classpath:/json/rescueFollow.json")
    private Resource rescueFollowJson;
    @Value("classpath:/json/repairFollow.json")
    private Resource repairFollowJson;

    @Value("${global-config.worker-id:1}")
    private int workId;


    public AlertCalledServiceImpl(RedissonClient client){
        this.redissonClient = client;
        rAtomicLong = redissonClient.getAtomicLong("AUTO_INCR_LONG");
    }


    private final Logger logger = LogManager.getLogger(AlertCalledServiceImpl.class);


    @Override
    public Object selectAlertCalledById(Long id) {
//        AlertCalled alertCalled = this.getBaseMapper().selectById(id);
//        if (!ObjectUtils.isEmpty(alertCalled.getFatherAlert())) {
//            id = alertCalled.getFatherAlert();
//        }
        if (redisUtils.hasKey(RedisKey.TZS_ALERTCALLED_ID + id)) {
             return redisUtils.get(RedisKey.TZS_ALERTCALLED_ID + id);
        }
        AlertCalledFormDto alertCalledFormVo = getAlertCalledFormDto(id);
//        //归并警情--报警类型显示自身的
//        if (alertCalled.getFatherAlert() != null) {
//            alertCalledFormVo.getAlertCalledDto().setType(alertCalled.getType());
//        }
        redisUtils.set(RedisKey.TZS_ALERTCALLED_ID + id, JSON.toJSON(alertCalledFormVo), time);
        return alertCalledFormVo;
    }

    public AlertCalledFormDto getAlertCalledFormDto(Long id) {
        // 警情基本信息
        AlertCalled alertCalled = this.getById(id);
        LambdaQueryWrapper<AlertFormValue> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AlertFormValue::getAlertCalledId, id);
        // 警情动态表单数据
        List<AlertFormValue> list = iAlertFormValueService.list(queryWrapper);
        List<FormValue> formValue = new ArrayList<FormValue>();
        if(list!=null&&list.size()>0) {
            for (AlertFormValue alertFormValue : list) {
                FormValue value = new FormValue(alertFormValue.getFieldCode(), alertFormValue.getFieldName(), "text", alertFormValue.getFieldValue(),alertFormValue.getBlock());
                formValue.add(value);
            }
        }
        AlertCalledDto alertCalledDto = new AlertCalledDto();
        BeanUtils.copyProperties(alertCalled,alertCalledDto);
        Elevator elevator = new Elevator();
        elevator.setRescueCode(Integer.valueOf(alertCalled.getDeviceId()));
        elevator.setRegisterCode(alertCalled.getRegistrationCode());
        Map<String,Object> map =  iElevatorService.selectElevator(elevator);
        if(!ObjectUtils.isEmpty(map)){
            alertCalledDto.setAddress(String.valueOf(map.get("address")));
            alertCalledDto.setProvince(String.valueOf(map.get("province")));
            alertCalledDto.setCity(String.valueOf(map.get("city")));
            alertCalledDto.setDistrict(String.valueOf(map.get("district")));
            alertCalledDto.setUseStatus(String.valueOf(map.get("useStatus")));
            alertCalledDto.setUseSiteCategory(ObjectUtils.isEmpty(map.get("useSiteCategory")) || "null".equals(String.valueOf(map.get("useSiteCategory"))) ? null : String.valueOf(map.get("useSiteCategory")));
            alertCalledDto.setUseUnit(String.valueOf(map.get("useUnit")));
            alertCalledDto.setRegionCode(String.valueOf(map.get("regionCode")));
        }
//              数据源切换
//            LambdaQueryWrapper<Elevator> elevatorQueryWrapper = new LambdaQueryWrapper<>();
//            elevatorQueryWrapper.eq(Elevator::getRescueCode, alertCalled.getDeviceId());
//            elevatorQueryWrapper.eq(Elevator::getRegisterCode, alertCalled.getRegistrationCode());
//            Elevator elevator =  iElevatorService.getOne(elevatorQueryWrapper);
//            if(null !=  elevator) {
//                alertCalledDto.setAddress(elevator.getAddress());
//                alertCalledDto.setProvince(elevator.getProvince());
//                alertCalledDto.setCity(elevator.getCity());
//                alertCalledDto.setDistrict(elevator.getDistrict());
//                alertCalledDto.setUseStatus(elevator.getUseStatus());
//                alertCalledDto.setUseSiteCategory(elevator.getUseSiteCategory());
//                alertCalledDto.setUseUnit(elevator.getUseUnit());
//                alertCalledDto.setRegionCode(elevator.getRegionCode());
//            }
        String voiceRecord = "";
        VoiceRecordFile temp = voiceRecordFileServiceImpl.getOne(new LambdaQueryWrapper<VoiceRecordFile>().eq(VoiceRecordFile::getAlertId, id).eq(VoiceRecordFile::getAlertStageCode,"860").orderByAsc(VoiceRecordFile::getTelStartTime).last("limit 1"));
        if(temp != null) {
            voiceRecord = temp.getFilePath();
        }
        AlertCalledFormDto alertCalledFormVo = new AlertCalledFormDto(alertCalledDto, formValue,voiceRecord);
        return alertCalledFormVo;
    }

    public void selectAlertCalledByIdNew(AlertPaperInfoDto alertCalled) {
        // 警情基本信息

        LambdaQueryWrapper<AlertFormValue> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AlertFormValue::getAlertCalledId, alertCalled.getAlertId());
        // 警情动态表单数据
        List<AlertFormValue> list = iAlertFormValueService.list(queryWrapper);
        if(list!=null&&list.size()>0) {
            for (AlertFormValue alertFormValue : list) {
                if(alertFormValue.getFieldCode().equals("trapped_num")) {
                    alertCalled.setTrappedNum(alertFormValue.getFieldValue());
                }
                if(alertFormValue.getFieldCode().equals("injured_num")) {
                    alertCalled.setInjuredNum(alertFormValue.getFieldValue());
                }
                if(alertFormValue.getFieldCode().equals("die_num")) {
                    alertCalled.setDieNum(alertFormValue.getFieldValue());
                }
            }
        }
    }

    @Override
    public AlertCalledFormDto selectAlertCalledByIdNoCache(Long id) {
        // 警情基本信息
        AlertCalled alertCalled = this.getById(id);
        LambdaQueryWrapper<AlertFormValue> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AlertFormValue::getAlertCalledId, id);
        // 警情动态表单数据
        List<AlertFormValue> list = iAlertFormValueService.list(queryWrapper);
        List<FormValue> formValue = new ArrayList<FormValue>();
        if(list!=null&&list.size()>0) {
            for (AlertFormValue alertFormValue : list) {
                FormValue value = new FormValue(alertFormValue.getFieldCode(), alertFormValue.getFieldName(), "text", alertFormValue.getFieldValue(),alertFormValue.getBlock());
                formValue.add(value);
            }
        }
        AlertCalledDto alertCalledDto = BeanDtoVoUtils.convert(alertCalled,AlertCalledDto.class);
        LambdaQueryWrapper<Elevator> elevatorQueryWrapper = new LambdaQueryWrapper<>();
        elevatorQueryWrapper.eq(Elevator::getRescueCode, alertCalled.getDeviceId());
        elevatorQueryWrapper.eq(Elevator::getRegisterCode, alertCalled.getRegistrationCode());
        Elevator elevator =  iElevatorService.getOne(elevatorQueryWrapper);
        if(null !=  elevator) {
            alertCalledDto.setAddress(elevator.getAddress());
            alertCalledDto.setProvince(elevator.getProvince());
            alertCalledDto.setCity(elevator.getCity());
            alertCalledDto.setDistrict(elevator.getDistrict());
            alertCalledDto.setUseStatus(String.valueOf(elevator.getUseStatus()));
            alertCalledDto.setUseSiteCategory(elevator.getUseSiteCategory());
            alertCalledDto.setUseUnit(elevator.getUseUnit());
            alertCalledDto.setRegionCode(elevator.getRegionCode());
        }
        String voiceRecord = "";
//        VoiceRecordFile temp = voiceRecordFileServiceImpl.getOne(new LambdaQueryWrapper<VoiceRecordFile>().eq(VoiceRecordFile::getAlertId,id).eq(VoiceRecordFile::getAlertStageCode,"860").orderByAsc(VoiceRecordFile::getRecDate));
//        if(temp != null) {
//            voiceRecord = temp.getFilePath();
//        }
        AlertCalledFormDto alertCalledFormVo = new AlertCalledFormDto(alertCalledDto, formValue,voiceRecord);
        return alertCalledFormVo;
    }

    @Override
    public Page<AlertCalledQueryDto> queryAlertListByQueryDto(IPage<AlertCalledQueryDto> page,
                                                              String workOrderNumber,
                                                              String creator,
                                                              String emergency,
                                                              String emergencyTimeStart,
                                                              String emergencyTimeEnd,
                                                              String emergencyCall,
                                                              String deviceId,
                                                              String elevatorAddress,
                                                              String district,
                                                              String alertType,
                                                              String alertSource,
                                                              String alertStage,
                                                              String alertStatus,
                                                              String sortParam,
                                                              String sortRule,
                                                              List<String> ids,
                                                              AgencyUserModel userModel
                                                              ) {
        //获取当前登陆人所在的技能组
        String groupCode = ctiService.getSkillGroup(userModel.getUserId());
        if (null == groupCode) {
            return new Page<>();
        }
        Page<List<AlertCalledQueryDto>> list = alertCalledMapper.queryAlertListByQueryDto(page,
                workOrderNumber, creator, emergency, emergencyTimeStart,
                emergencyTimeEnd, emergencyCall, deviceId, elevatorAddress, district, alertType,
                alertSource, alertStage, alertStatus, sortParam, sortRule, groupCode, ids);
        Page<AlertCalledQueryDto> page1 = new Page<>();
        List<AlertCalledQueryDto> resultDtoList = JSONArray.parseArray(JSONArray.toJSONString(list.getRecords()),AlertCalledQueryDto.class);
        page1.setCurrent(page.getCurrent());
        page1.setSize(page.getSize());
        page1.setTotal(list.getTotal());
        page1.setRecords(resultDtoList);
        return page1;
    }

    @Override
    public Boolean updateAlertStage(AlertCalledDto alertCalledVo, DispatchPaperEnums stage,Long alertId) {
        LambdaUpdateWrapper<AlertCalled> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(AlertCalled::getSequenceNbr,alertCalledVo.getSequenceNbr());
        updateWrapper.set(AlertCalled::getAlertStageCode,stage.getId());
        alertCalledVo.setAlertStage(stage.getValue());
        alertCalledVo.setAlertStageCode(stage.getId());
        updateWrapper.set(AlertCalled::getAlertStage,stage.getValue());
        if(stage == DispatchPaperEnums.reportorBack || stage == DispatchPaperEnums.complainantBack) {
            updateWrapper.set(AlertCalled::getAlertStatus,true);
            alertCalledVo.setAlertStatus(true);
        } else if(alertCalledVo.getAlarmTypeCode().equals(AlertStageEnums.KRJY.getId())) {
            LambdaQueryWrapper<RepairConsult> queryWrapper = new LambdaQueryWrapper<RepairConsult>();
            queryWrapper.eq(RepairConsult::getParentId, alertId).orderByDesc(RepairConsult::getRecDate);
            List<RepairConsult> list = repairConsultService.list(queryWrapper);
            List<RepairConsult> collect = list.stream().filter(item -> item.getType().length() > 3).collect(Collectors.toList());
            if(collect.size()>1){
                updateWrapper.set(AlertCalled::getAlertStatus,true);
                alertCalledVo.setAlertStatus(true);
            }
        }
        Boolean flag = this.update(updateWrapper);
        if(flag) { //更新redis 和 es 信息
            try {
                redisUtils.del(RedisKey.TZS_ALERTCALLED_ID+alertCalledVo.getSequenceNbr());
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("删除redis失败:" + e.getMessage());
            }
            try {
                eSAlertCalledService.updateEsAlertCalled(alertCalledVo);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("更新es失败:" + e.getMessage());
            }
        }
        return this.update(updateWrapper);
    }

    /**
     *  警情处置流程信息
     */
    @Override
    public AlertHandlerDto getHandlerInfo(String alertId) {
        AlertHandlerDto alertHandlerDto = new AlertHandlerDto();
        LinkedHashMap<String,Date> map = new LinkedHashMap<>();
        List<AlertHandlerInfoDto> list = new ArrayList<>();
        AlertHandlerInfoDto alertHandlerInfoDtoHead = new AlertHandlerInfoDto();
        alertHandlerInfoDtoHead.setAbProcess("处置流程");
        alertHandlerInfoDtoHead.setAcAnswerThePolice("接警");
        alertHandlerInfoDtoHead.setAcReport("上报");
        alertHandlerInfoDtoHead.setAdNotice("派遣/通知");
        alertHandlerInfoDtoHead.setAedArrive("到达");
        alertHandlerInfoDtoHead.setAfeComplete("完成");
        alertHandlerInfoDtoHead.setAgReturnVisit("回访");
        list.add(alertHandlerInfoDtoHead);

        AlertCalled called = this.getById(Long.valueOf(alertId));

        if(null == called) {
            throw new BadRequest("警情不存在");
        }
        map.put("acAnswerThePolice",called.getCallTime());
        map.put("acReport",called.getRecDate());

        LambdaQueryWrapper<DispatchPaper> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(DispatchPaper::getAlertId,Long.valueOf(alertId));
        DispatchPaper dispatchPaper = dispatchPaperService.getOne(queryWrapper);
        List<DispatchTask> dispatchTask = null;
        if(!ValidationUtil.isEmpty(dispatchPaper)) {
            LambdaQueryWrapper<DispatchTask> queryWrapper1 = new LambdaQueryWrapper();
            queryWrapper1.eq(DispatchTask::getPaperId,Long.valueOf(dispatchPaper.getSequenceNbr()));
            dispatchTask  = dispatchTaskService.list(queryWrapper1);
        }

        String [] str = new String[]{"使用单位","一级响应","二级响应","三级响应","市级监督"};

        if(null != dispatchPaper) {
            map.put("adNotice",dispatchPaper.getDispatchTime());
            map.put("aedArrive",dispatchPaper.getArriveTime());
            map.put("afeComplete",dispatchPaper.getSaveTime());
            for(String s:str) {
                AlertHandlerInfoDto alertHandlerInfoDto = new AlertHandlerInfoDto();
                if(null != dispatchTask &&dispatchTask.size() > 0 ) {
                    List<DispatchTask> taskList =  dispatchTask.stream().filter(e->e.getOrgType().equals(s)).collect(Collectors.toList());
                    if(taskList.size() > 0) {
                        dataInit(alertHandlerInfoDto,s,"", "","已派遣",
                                taskList.get(0).getArriveTime() == null ? "" : "已到达" ,taskList.get(0).getSaveTime() == null ? "" : "已完成",
                                dispatchPaper.getFeedbackTime() != null || dispatchPaper.getFeedbackFinishTime() != null ? "已回访" : "");
                    } else {
                        dataInit(alertHandlerInfoDto,s,"","","","","","");
                    }
                }
                list.add(alertHandlerInfoDto);
            }
            map.put("agReturnVisit",dispatchPaper.getFeedbackFinishTime()); // 修复BUG 3439 by kongfm
        } else {
            for(String s:str) {
                AlertHandlerInfoDto alertHandlerInfoDto = new AlertHandlerInfoDto();
                dataInit(alertHandlerInfoDto,s,"","","","","","");
                list.add(alertHandlerInfoDto);
            }
            map.put("adNotice",null);
            map.put("aedArrive",null);
            map.put("afeComplete",null);
            map.put("agReturnVisit",null);
        }
        alertHandlerDto.setAlertHandlerInfoDto(list);
        alertHandlerDto.setHandlerTime(map);
        return alertHandlerDto;
    }

    @Override
    public Object getCalledInfo() {
        LambdaQueryWrapper<AlertCalled> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(AlertCalled::getAlertStageCode,"860");
        queryWrapper.ge(AlertCalled::getCallTime,DateUtils.stampToDate(System.currentTimeMillis(),DateUtils.DATE_PATTERN));
        queryWrapper.le(AlertCalled::getCallTime,DateUtils.stampToDate(DateUtils.dateAddDays(new Date(),1).getTime(),DateUtils.DATE_PATTERN));
        Object list =   this.list(queryWrapper);
        return list;
    }

    @Override
    public WechatMyBussinessDto getBussinessInfoById(Long alertId) {
        return  baseMapper.getBussinessInfoById(alertId);
    }

    @Override
    public List<WechatMyBusinessListDto> getBussinessListByPhonePager(String phone, String bussinessCode, Long current) {
        return baseMapper.getBussinessListByPhonePager(phone, bussinessCode, current*5);
    }

    @Override
    public List<AlertCalledRecordDto> queryAlertRecordListByQueryDto(String callTimeStart, String callTimeEnd, String type, String alertSource, String alarmType, String groupCode, List<String> ids) {
        List<AlertCalledRecordDto> list = alertCalledMapper.queryAlertRecordListByQueryDto(callTimeStart, callTimeEnd, type, alertSource, alarmType, groupCode, ids);
        return list;
    }

    @Override
    public List<TzsCitInfoDto> getSeatInfos() {
        // 获取人员信息
//        FeignClientResult<List<AgencyUserModel>> userListResult = Privilege.agencyUserClient.list(null,null);
//        FeignClientResult<List<AgencyUserModel>> userListResult = Privilege.agencyUserClient.queryByRoleId(dutySeatsRoleIds,null);
        ReginParams reginParams = citInfoService.getReginParams();
        String companyCode = reginParams.getCompany().getCompanyCode();
        LambdaQueryWrapper<TzsCitInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TzsCitInfo::getRegionCode, companyCode);
        List<TzsCitInfo> citInfoList = citInfoService.list(wrapper);
        List<TzsCitInfoDto> citInfoDtoList = new ArrayList<>();
        for(TzsCitInfo citInfo : citInfoList){
            TzsCitInfoDto citInfoDto = new TzsCitInfoDto();
            BeanUtils.copyProperties(citInfo, citInfoDto);
            //服务评分写死100分
            citInfoDto.setServiceSocre("100");
            //在线
            Map map = ctiService.getUserStatus();
            citInfoDto.setStatus(0);
            Integer status = (Integer) map.get(citInfo.getCode());
            if(!ValidationUtil.isEmpty(status)){
                if(status!=0&&status!=1){
                    status = 2;
                }
                citInfoDto.setStatus(status);
            }
            citInfoDto.setCountNum(countNum(citInfo.getCtiUserName(), citInfo.getCtiUserId()));
            citInfoDtoList.add(citInfoDto);
        }
//        List<AgencyUserModel> userList = userListResult.getResult();
//        List<DutySeatDto> dutyList = new ArrayList<>();
//        userList.stream().forEach(u -> {
//            // 排除非系统中人员
//            if(!u.getRealName().equals(u.getMobile())) { // 公众号创建
//                DutySeatDto temp = new DutySeatDto();
//                temp.setUserId(u.getUserId());
//                temp.setUserName(u.getRealName());
//                temp.setUserRole("管理员");
//                temp.setSeatCode("1001");
//                temp.setUserStatus("1");
//                // 获取当日警情处理件数
//                Calendar c = Calendar.getInstance();
//                c.set(Calendar.SECOND,0);
//                c.set(Calendar.HOUR_OF_DAY,0);
//                c.set(Calendar.MINUTE,0);
//                String beginDate = DateUtils.date2LongStr(c.getTime());
//                c.set(Calendar.SECOND,59);
//                c.set(Calendar.HOUR_OF_DAY,23);
//                c.set(Calendar.MINUTE,59);
//                String endDate = DateUtils.date2LongStr(c.getTime());
//                List<AlertCalled> dealAlert = this.list(new LambdaQueryWrapper<AlertCalled>().eq(AlertCalled::getIsDelete,false).eq(AlertCalled::getRecUserId,u.getUserId())
//                        .gt(AlertCalled::getCallTime,beginDate).lt(AlertCalled::getCallTime,endDate).eq(AlertCalled::getAlertStatus, true));
//                int count = 0;
//                if(dealAlert != null && dealAlert.size() > 0) {
//                    count = dealAlert.size();
//                }
//                temp.setTodayDeal(count);
//                temp.setServiceSocre("95");
//                dutyList.add(temp);
//            }
//
//        });

        return citInfoDtoList;
    }

    private void dataInit(AlertHandlerInfoDto alertHandlerInfoDto, String process,String answerThePolice, String report, String notice, String arrive, String complete,String returnVisit) {
        alertHandlerInfoDto.setAbProcess(process);
        alertHandlerInfoDto.setAcAnswerThePolice(answerThePolice);
        alertHandlerInfoDto.setAcReport(report);
        alertHandlerInfoDto.setAdNotice(notice);
        alertHandlerInfoDto.setAedArrive(arrive);
        alertHandlerInfoDto.setAfeComplete(complete);
        alertHandlerInfoDto.setAgReturnVisit(returnVisit);
    }


    /**
     *
     * <pre>
     * 保存警情信息
     * </pre>
     *
     * @param alertCalledObjsDto
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public AlertCalledObjsDto createAlertCalled(AlertCalledObjsDto alertCalledObjsDto, AgencyUserModel user) {
        try {
            // 警情基本信息
            AlertCalled alertCalled = BeanDtoVoUtils.convert(alertCalledObjsDto.getAlertCalledDto(),AlertCalled.class);
            alertCalled.setEquipmentClassification(alertCalledObjsDto.getAlertCalledDto().getEquipment());
            Map<String, String> getCode = EquipmentClassifityEnum.getCode;
            String code= getCode.get(alertCalledObjsDto.getAlertCalledDto().getEquipment());
            alertCalled.setEquipmentClassificationCode(code);
            alertCalled.setCallTime(DateUtils.longStr2Date(alertCalled.getCallTimeStr()));
            String groupCode = ctiService.getSkillGroup(user.getUserId());
            alertCalled.setSkillGroup(groupCode);
            // 重复填报使用覆盖原有最新(按照主键倒叙排列)且非删除状态的警情，工单号唯一，正常不会出现一个工单号有两条数据
            AlertCalled existAlertCalled =  this.getOne(new LambdaQueryWrapper<AlertCalled>().eq(AlertCalled::getWorkOrderNumber, alertCalled.getWorkOrderNumber()).eq(BaseEntity::getIsDelete, false).orderByDesc(AlertCalled::getSequenceNbr).last("limit 1"));
            if(existAlertCalled != null){
                alertCalled.setSequenceNbr(existAlertCalled.getSequenceNbr());
            }
            // 判断是否归并警情
            if (alertCalled.getFatherAlert() != null) {
                // 警情归并，设置当前警情状态为结束。
                alertCalled.setAlertStatus(true);
                alertCalled.setAlertStage(DispatchPaperEnums.receivedAlert.getValue());
                alertCalled.setAlertStageCode(DispatchPaperEnums.receivedAlert.getId());
                alertCalled.setType(AlertStageEnums.JQGB.getValue());
                alertCalled.setTypeCode(AlertStageEnums.JQGB.getId());
                this.saveOrUpdate(alertCalled);
                // 动态表单
                List<AlertFormValue> alertFormValuelist = alertCalledObjsDto.getAlertFormValue();
                // 填充警情主键
                alertFormValuelist.forEach(alertFormValue -> {
                    alertFormValue.setAlertCalledId(alertCalled.getSequenceNbr());
                    alertFormValue.setAlertTypeCode(alertCalled.getAlarmTypeCode());
                });
                // 保存动态表单数据
                iAlertFormValueService.saveBatch(alertFormValuelist);
                // 返回父警情基本信息和自身alertID
                AlertCalled alertCalledFather = this.getById(alertCalled.getFatherAlert());
                AlertCalledDto alertCalledDto = BeanDtoVoUtils.convert(alertCalledFather, AlertCalledDto.class);
                alertCalledDto.setSelfAlert(alertCalled.getSequenceNbr());
                alertCalledObjsDto.setAlertCalledDto(alertCalledDto);
            } else {
                // 警情报送
                // ****************************************************待确认开发
                alertCalled.setAlertStatus(false);
                alertCalled.setIsDelete(false);
                alertCalled.setAlertStage(AlertStageEnums.JJ.getValue());
                alertCalled.setAlertStageCode(AlertStageEnums.JJ.getId());
                alertCalled.setType(AlertStageEnums.JQCB.getValue());
                alertCalled.setTypeCode(AlertStageEnums.JQCB.getId());
                Elevator elevator = new Elevator();
                elevator.setRescueCode(Integer.valueOf(alertCalledObjsDto.getAlertCalledDto().getDeviceId()));
                Map<String,Object> map =  iElevatorService.selectElevator(elevator);
                if(!ObjectUtils.isEmpty(map)){
                    alertCalled.setEquipmentId(map.get("sequenceNbr").toString());
                    alertCalled.setCity(map.get("city").toString());
                    alertCalled.setDistrict(map.get("district").toString());
                    alertCalled.setRegionCode(map.get("regionCode").toString());
                    alertCalled.setBizOrgCode(map.get("orgCode") + "");
                }
                this.saveOrUpdate(alertCalled);
                // 动态表单
                List<AlertFormValue> alertFormValuelist = alertCalledObjsDto.getAlertFormValue();
                // 填充警情主键
                alertFormValuelist.forEach(alertFormValue -> {
                    alertFormValue.setAlertCalledId(alertCalled.getSequenceNbr());
                    alertFormValue.setAlertTypeCode(alertCalled.getAlarmTypeCode());
                });
                if(AlertStageEnums.KRJY.getId().equals(alertCalled.getAlarmTypeCode()) ) {
                    //困人救援创建警情时创建救援过程信息
                    rescueProcessServiceImpl.getProcessByAlertId(alertCalled.getSequenceNbr());
                }
                // 保存动态表单数据
                iAlertFormValueService.saveBatch(alertFormValuelist);
                alertCalledObjsDto.setAlertCalledDto(BeanDtoVoUtils.convert(alertCalled,AlertCalledDto.class));
                alertCalledObjsDto.setAlertFormValue(alertFormValuelist);
                //保存处置记录-接警
                repairConsultServiceImpl.saveRepairConsultByAlertIdType(alertCalled.getSequenceNbr(),AlertStageEnums.JJ.getCode(),null, user); //保存接警日志
                //同步保存ES
                eSAlertCalledService.saveAlertCalledToES(alertCalled);
            }
            return alertCalledObjsDto;
        } catch (Exception e) {
            logger.error("报送失败",e);
            throw new RuntimeException("报送失败，系统异常!");
        }
    }

    /**
     *
     * <pre>
     * 保存警情信息  公众号
     * </pre>
     *
     * @param alertCalledDto
     * @return
     */
    @Transactional(rollbackFor = RuntimeException.class)
    public AlertCalledDto createAlertCalled(AlertCalledDto alertCalledDto) {
        try {
            // 警情基本信息
            AlertCalled alertCalled = BeanDtoVoUtils.convert(alertCalledDto,AlertCalled.class);

            alertCalled.setCallTime(new Date());

            // 警情报送
            alertCalled.setAlertStatus(false);
            alertCalled.setAlertSource(AlertStageEnums.APPJJ.getValue());
            alertCalled.setAlertSourceCode(AlertStageEnums.APPJJ.getId());
            alertCalled.setIsDelete(false);
            alertCalled.setAlertStage(AlertStageEnums.JJ.getValue());
            alertCalled.setAlertStageCode(AlertStageEnums.JJ.getId());
            alertCalled.setType(AlertStageEnums.JQCB.getValue());
            alertCalled.setTypeCode(AlertStageEnums.JQCB.getId());
            this.save(alertCalled);

            // 保存照片
            Map<String, List<AttachmentDto>> attachmentMap = new HashMap<>();
            attachmentMap.put("imgs",alertCalledDto.getImages());
            ISourceFileService.saveAttachments(alertCalled.getSequenceNbr(),attachmentMap);

            // 动态表单
            AlertFormValue  alertFormValue = new AlertFormValue();
            // 填充警情主键
            alertFormValue.setAlertCalledId(alertCalled.getSequenceNbr());
            alertFormValue.setAlertTypeCode(alertCalled.getAlarmTypeCode());
            if(AlertStageEnums.GZWX.getCode().equals(alertCalled.getAlarmTypeCode())) {
                alertFormValue.setFieldName("故障报修描述");
                alertFormValue.setFieldValue(alertCalledDto.getDescribe());
                alertFormValue.setAlertFormId(8L);
                alertFormValue.setFieldCode("fault_report");
            } else {
                alertFormValue.setFieldName("投诉咨询描述");
                alertFormValue.setFieldValue(alertCalledDto.getDescribe());
                alertFormValue.setFieldCode("complaint_consulttation");
                alertFormValue.setAlertFormId(9L);
            }

            // 保存动态表单数据
            iAlertFormValueService.save(alertFormValue);
            //保存处置记录-接警  保存接警日志
            repairConsultServiceImpl.saveRepairConsultByAlertIdType(alertCalled.getSequenceNbr(), TzsCommonParam.APPJJ,null, null);

            /**
             * 同步保存ES
             */
            eSAlertCalledService.saveAlertCalledToES(alertCalled);

            return alertCalledDto;
        } catch (Exception e) {
            logger.error("报送失败",e);
            throw new RuntimeException("报送失败，系统异常!");
        }
    }


    public Map<String, Object> getNearlyInfo(String beginDate, String endDate, String groupCode) {
        Map<String, Object> result = Maps.newHashMap();
        List<Map<String, Object>> statusCountMap = alertCalledMapper.queryNearlyCount(beginDate, endDate, groupCode);
        for (int i = 0; i < statusCountMap.size(); i++) {
            if (statusCountMap.get(i).size() > 1) {
                result.put("dateTime" + i, statusCountMap.get(i).get("dateTime"));
                result.put("majorAlertCount" + i, statusCountMap.get(i).get("majorAlertCount"));
            } else {
                result.put("dateTime" + i, statusCountMap.get(i).get("dateTime"));
                result.put("majorAlertCount" + i, 0);
            }
        }
        return result;
    }

	public Object getTodayEmergencyCount(String regionCode) {
        Map<String,Integer> map = alertCalledMapper.getTodayEmergencyCount(regionCode);
        Map<String,Integer> map1  =  alertCalledMapper.getImportantEventCount(regionCode);
        map.put("importantEventCount",map1.get("importantEventCount"));
	    return	map;
	}

//	public Object getImportantEventCount() {
//		return
//	}

	public Object getImportantEventOrTodayEmergencyCount(String type,String regionCode) {
//		List<Map<String, Object>> map=null;
//        List<Map<String, Object>> map1= new LinkedList<>();
//		LambdaQueryWrapper<AlertCalled> queryWrapper=new LambdaQueryWrapper<AlertCalled>();
//		queryWrapper.eq(AlertCalled::getIsDelete, 0);
//		queryWrapper.eq(AlertCalled::getAlarmTypeCode, "960");
//		if("rescueTotal".equals(type)) {
//			queryWrapper.in(AlertCalled::getAlertStageCode,Arrays.asList("861","862"));
//		}else if("rescueComplete".equals(type)) {
//			queryWrapper.in(AlertCalled::getAlertStageCode,Arrays.asList("864","865","866"));
//		}
		if("importantEventCount".equals(type)) {
            return alertCalledMapper.getImportantEventDetail(type,regionCode);
		} else {
            if("rescueTotal".equals(type)) {
                return alertCalledMapper.getTodayEmergencyDetail(type,null,regionCode);
            } else if("rescueComplete".equals(type))  {
                return alertCalledMapper.getTodayEmergencyDetail(null,type,regionCode);
            } else {
                return alertCalledMapper.getTodayEmergencyDetail(null,null,regionCode);
            }
        }

//        for (Map<String,Object> m:  map
//             ) {
//            LambdaQueryWrapper<Elevator> queryWrapper1=new LambdaQueryWrapper<>();
//            queryWrapper1.eq(Elevator::getIsDelete, 0);
//            queryWrapper1.eq(Elevator::getSequenceNbr, m.get("equipment_id"));
//            Elevator elevator = iElevatorService.getOne(queryWrapper1);
//            m.put("injured","无伤亡");
//            if(null != elevator) {
//                m.put("longitude",elevator.getLongitude());
//                m.put("latitude",elevator.getLatitude());
//                m.put("regionCode",elevator.getRegionCode());
//
//                if(elevator.getRegionCode().contains(regionCode)) {
//                    map1.add(m);
//                }
//            }
//        }
	}

    public List<AlertPaperInfoDto> getAlertPaperInfoList(List<String> regionCodes, Boolean isHistory) {
        List<AlertPaperInfoDto> temp = baseMapper.getAlertPaperInfoList(regionCodes, isHistory);
        temp.forEach(t -> {
            DispatchPaper paper = dispatchPaperService.getOne(new LambdaQueryWrapper<DispatchPaper>().eq(DispatchPaper::getIsDelete,false).eq(DispatchPaper::getAlertId,t.getAlertId()));
            if(paper != null) {
                t.setFinishTime(paper.getFeedbackFinishTime());
            }
        });
        return temp;
    }

    public List<String> authRegionCodeList(List<String> regionCodes) {
        // 警情id 警情地址 警情状态 警情类型 警情发生时间
        List<String> useRegionCode = tzsAuthService.getUserRegionCode();
        if(regionCodes == null) {
            regionCodes = useRegionCode;
        } else {
            // 判断传入regionCodes 是否越权
            List<String> tempList = new ArrayList<>();
            Iterator<String> regionIt =  regionCodes.iterator();
            while(regionIt.hasNext()) {
                String tempCode = regionIt.next();
                String districtCode = tempCode.substring(4,6);
                String provinceCode = tempCode.substring(2,6);
                if("0000".equals(provinceCode)) {// 为省则默认使用用户现有权限查询数据
                    regionCodes = useRegionCode;
                } else {
                    if("00".equals(districtCode)) { // 为市
                        if(!useRegionCode.contains(tempCode)) { // 不包含该市权限 需要移除市搜索条件 添加 该市下区搜索条件
                            for(String tempUsercode : useRegionCode) {
                                if(tempUsercode.contains(tempCode.substring(0, 4))) {
                                    tempList.add(tempUsercode);
                                }
                            }
                            regionIt.remove();
                        }
                    } else { // 为区 不会出现越权情况

                    }
                }
            }
            regionCodes.addAll(tempList);
        }
        return regionCodes;
    }

    @Override
    public List<AlertPaperInfoDto> getEquipmentHistory(List<String> regionCodes, String equipmentClassCode, Integer current, Integer pageNum, String equipmentCode) {
        current = pageNum * ( current - 1);
        List<AlertPaperInfoDto> temp = baseMapper.getEquipmentHistory(regionCodes, equipmentClassCode,current,pageNum ,equipmentCode);
        return temp;
    }

    @Override
    public Integer getEquipmentHistoryCount(List<String> useRegionCode, String equipmentClassCode, String equipmentCode) {
        return baseMapper.getEquipmentHistoryCount(useRegionCode,equipmentClassCode,equipmentCode);
    }

    @Override
    public String nextId() {
        RLock lock = redissonClient.getLock("WORK_ORDER_NUMBER_LOCK_KEY");
        String workOrderNumber = "";
        try {
            lock.lock();
            long remainTimeToLive = rAtomicLong.remainTimeToLive();
            // 判断是否过期，设置过期时间，序列开始重置为0
            if (remainTimeToLive <= 0) {
                resetCounterAndExpire();
            }
            long seq = rAtomicLong.addAndGetAsync(1).get();
            String number = DateUtils.stampToDate(SystemClock.now(), "yyyyMMddHHmmss");
            workOrderNumber = number + workId + seq;
        } catch (ExecutionException | InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        return workOrderNumber;
    }

    @Override
    public AlarmStatisticsDto getAlertStatistics(ReginParams reginParams) {
        AlarmStatisticsDto alarmStatisticsDto = new AlarmStatisticsDto();
        //获取当前登录人所在的技能组code
        String groupCode = ctiService.getSkillGroup(reginParams.getUserModel().getUserId());

        if (groupCode != null) {
            Map<String, Long> myBacklogMap = alertCalledMapper.getMyBacklog(groupCode);
            // 全部待办数量
            QueryWrapper<AlertCalled> allNumQueryWrapper = new QueryWrapper<>();
            allNumQueryWrapper.eq("alert_status", false);
            // 投诉咨询数量
            alarmStatisticsDto.setSuggestions(myBacklogMap.get("suggestionsCount"));
            // 故障维修数量
            alarmStatisticsDto.setFaultRescue(myBacklogMap.get("faultRescueCount"));
            // 困人救援数量
            alarmStatisticsDto.setSleepyIncident(myBacklogMap.get("sleepyIncidentCount"));

            // 我的待办数量
            QueryWrapper<AlertCalled> todoNumQueryWrapper = new QueryWrapper<>();
            todoNumQueryWrapper.eq("alert_status", false);
            todoNumQueryWrapper.eq("skill_group", groupCode);
            todoNumQueryWrapper.eq("rec_user_id", reginParams.getUserModel().getUserId());
            alarmStatisticsDto.setTodoNum(this.count(todoNumQueryWrapper));

            Map<String, Long> map = alertCalledMapper.queryAlertStatusCount(
                    DateUtils.stampToDate(System.currentTimeMillis(), DateUtils.DATE_PATTERN),
                    DateUtils.stampToDate(DateUtils.dateAddDays(new Date(), 1).getTime(), DateUtils.DATE_PATTERN),
                    groupCode,
                    reginParams.getUserModel().getUserId());

            // 当天接警
            alarmStatisticsDto.setTodayAlarmNum(
                    map.get("calledCount") == null ? 0L : map.get("calledCount"));
            // 当天提交
            alarmStatisticsDto.setSubmitNum(
                    map.get("majorAlertCount") == null ? 0L : map.get("majorAlertCount"));
            alarmStatisticsDto.setAllNum(this.count(allNumQueryWrapper));


            LinkedHashMap<String, Long> recordMap = new LinkedHashMap<>();
            // 近七天办理数量
            Map<String, Object> nearlySevenDaysMap = getNearlyInfo(
                    DateUtils.stampToDate(System.currentTimeMillis(), DateUtils.DATE_PATTERN),
                    DateUtils.stampToDate(DateUtils.dateAddDays(new Date(), 1).getTime(), DateUtils.DATE_PATTERN), groupCode);

            for (int i = 0; i < nearlySevenDaysMap.size() / 2; i++) {
                recordMap.put(DateUtils.dateToString(nearlySevenDaysMap.get("dateTime" + i).toString()),
                        Long.valueOf(nearlySevenDaysMap.get("majorAlertCount" + i).toString()));
            }
            alarmStatisticsDto.setNearlySevenDaysNum(recordMap);
        } else {
            alarmStatisticsDto.setAllNum(0);
            alarmStatisticsDto.setFaultRescue(0L);
            alarmStatisticsDto.setSleepyIncident(0L);
            alarmStatisticsDto.setSubmitNum(0L);
            alarmStatisticsDto.setSuggestions(0L);
            alarmStatisticsDto.setTodayAlarmNum(0L);
            alarmStatisticsDto.setTodoNum(0);
            alarmStatisticsDto.setNearlySevenDaysNum(getDate());
        }
        return alarmStatisticsDto;
    }

    private Map<String, Long> getDate() {
        HashMap<String, Long> map = new LinkedHashMap<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 7; i > 0; i--) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(new Date());
            calendar.add(Calendar.DAY_OF_MONTH, -i);
            Date previousDate = calendar.getTime();
            map.put(sdf.format(previousDate), 0L);
        }
        return map;
    }
    private void resetCounterAndExpire() {
        // 第二天凌晨序列重置 新开始
        rAtomicLong.set(0);
        rAtomicLong.expireAt(calculateExpirationTime());
    }

    private long calculateExpirationTime() {
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime nextDay = now.plusDays(1).withHour(0).withMinute(0).withSecond(0).withNano(0);
        return nextDay.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }


    // 今日值班人员接警数量统计
    public Integer countNum(String userName, String userId){
        //获取当前登录人所在的技能组code
        String groupCode = ctiService.getSkillGroup(userId);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String format = simpleDateFormat.format(new Date());
        StrBuilder strBuilderStart = new StrBuilder();
        String startTimeString = strBuilderStart.append(format).append(" ").append("00:00:00").toString();
        StrBuilder strBuilderEnd = new StrBuilder();
        String endTimeString = strBuilderEnd.append(format).append(" ").append(" ").append("23:59:59").toString();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date startTime =null;
        Date endTime =null;
        try {
            startTime= sdf.parse(startTimeString);
             endTime = sdf.parse(endTimeString);
        } catch (ParseException e) {
            e.printStackTrace();
            logger.error("日期转化失敗:" + e.getMessage());
        }
        return alertCalledMapper.getCountNum(userName, startTime, endTime, groupCode);
    }

    public Object getCallRecords(Long id, int number, int size) {
        Page<VoiceRecordFileDto> voiceRecordFileDtoPage = new Page<>();
        HashMap<String, Object> map = new HashMap<>();
        LambdaQueryWrapper<VoiceRecordFile> queryWrapper = new LambdaQueryWrapper<VoiceRecordFile>();
        queryWrapper.eq(VoiceRecordFile::getAlertId, id).orderByDesc(VoiceRecordFile::getRecDate);
        List<VoiceRecordFile> list = voiceRecordFileServiceImpl.list(queryWrapper);
        List<VoiceRecordFileDto> dtoList = new ArrayList<VoiceRecordFileDto>(list.size());
        list.stream().forEach(voiceRecord -> {
            // 创建新的对象实例
            VoiceRecordFileDto target = new VoiceRecordFileDto();
            // 把原对象数据拷贝到新对象
            BeanUtils.copyProperties(voiceRecord, target);
            dtoList.add(target);
        });
//        map.put("dataList", dtoList);
        List<VoiceRecordFileDto> collect = dtoList.stream()
                .skip((long) (number - 1) * size)
                .limit(size)
                .collect(Collectors.toList());
        voiceRecordFileDtoPage.setRecords(collect);
        voiceRecordFileDtoPage.setCurrent(number);
        voiceRecordFileDtoPage.setSize(size);
        return voiceRecordFileDtoPage;
    }

    private static Map<String, String> regionCodeOrgCodeMap = new ConcurrentHashMap<>();

    public Object getDispatchRecord(Long id) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        HashMap<String, Object> result = new HashMap<>();
        ArrayList<Map<String, Object>> group = new ArrayList<>();
        String json;
        try {
            json = IOUtils.toString(dispatchRecordFirst.getInputStream(), String.valueOf(StandardCharsets.UTF_8));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        List<Map> columns = parseArray(json, Map.class);
        // 一级调派
        // 获取根据警情获取电梯信息
        Map<String, Object> map = elevatorServiceImpl.selectByAlertId(id);
        if (ObjectUtils.isEmpty(map)) {
            throw new BadRequest("设备未找到");
        }
        // 根据设备使用id 获取维保单位信息
        HashMap<String, Object> first = new HashMap<>();
        ArrayList<Map> firstDatas = new ArrayList<>();
        HashMap<String, Object> firstData = new HashMap<>();
        first.put("key", "firstLevelDispatch");
        first.put("renderType", "table");
        first.put("columns", columns);
        first.put("displayName", "一级调派");
        List<Map<String, Object>> list = elevatorServiceImpl.selectMtByAlertId(String.valueOf(map.get("sequenceNbr")));
        firstDatas.add(firstData);
        first.put("dataList", list);
        first.put("rowKey", "sequenceNbr");
        // 二级调派
        String secondJson;
        try {
            secondJson = IOUtils.toString(dispatchRecordSecond.getInputStream(), String.valueOf(StandardCharsets.UTF_8));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        List<Map> secondColumns = parseArray(secondJson, Map.class);
        // 获取根据警情获取电梯信息
        Map<String, Object> map2 = elevatorServiceImpl.selectByAlertId(id);
        String longitude = String.valueOf(map2.get("longitude"));
        String latitude = String.valueOf(map2.get("latitude"));
        // 根据经纬度和距离返回救援机构信息
        HashMap<String, Object> second = new HashMap<>();
        second.put("key", "secondLevelDispatch");
        second.put("renderType", "table");
        second.put("columns", secondColumns);
        second.put("displayName", "二级调派");
        List<RescueStationDto> listByLatLonDistance = iRescueStationService.getListByLatLonDistance(latitude, longitude, 1000);
        second.put("dataList", listByLatLonDistance);
        second.put("rowKey", "sequenceNbr");
        // 力量调派
        String powerJson;
        try {
            powerJson = IOUtils.toString(dispatchRecordPower.getInputStream(), String.valueOf(StandardCharsets.UTF_8));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        List<Map> powerColumns = parseArray(powerJson, Map.class);
        LambdaQueryWrapper<DispatchTask> queryWrapper = new LambdaQueryWrapper<DispatchTask>();
        queryWrapper.eq(DispatchTask::getAlertId, id);
        HashMap<String, Object> power = new HashMap<>();
        ArrayList<Map> powerDatas = new ArrayList<>();
        power.put("key", "powerLevelDispatch");
        power.put("renderType", "table");
        power.put("columns", powerColumns);
        power.put("displayName", "使用单位");
        List<DispatchTask> powerList = dispatchTaskServiceImpl.list(queryWrapper);
        if (!ObjectUtils.isEmpty(powerList)) {
            powerList.forEach(p -> {
                Map<String, Object> objectMap = Bean.BeantoMap(p);
                if (!ObjectUtils.isEmpty(p.getDispatchTime())) {
                    objectMap.put("dispatchTime", simpleDateFormat.format(p.getDispatchTime()));
                }
                if (!ObjectUtils.isEmpty(p.getArriveTime())) {
                    objectMap.put("arriveTime", simpleDateFormat.format(p.getArriveTime()));
                }
                powerDatas.add(objectMap);
            });
        }
        power.put("dataList", powerDatas);
        power.put("rowKey", "sequenceNbr");
        group.add(power);
        group.add(first);
        group.add(second);
        result.put("subs", group);
        return result;
    }

    public Object getBasicDetail(Long id) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        HashMap<String, Object> map = new HashMap<>();
        List<FormValue> jsonData = getJsonData(emergencyBasic);
        RescueProcessDto dto = rescueProcessServiceImpl.getProcessByAlertId(id);
        Map<String, Object> objectMap = Bean.BeantoMap(dto);
        jsonData.forEach(f -> {
            Object o = objectMap.get(f.getKey());
            if (!ObjectUtils.isEmpty(o)) {
                f.setValue(o.toString());
            }
            // 派遣状态
            if ("dispatchStatus".equals(f.getKey())) {
                if (Boolean.TRUE.equals(dto.getDispatchStatus())){
                    f.setValue("已通知已派遣");
                }else {
                    f.setValue("未通知未派遣");
                }
            }
            // 到达状态
            if ("arriveStatus".equals(f.getKey())) {
                if (Boolean.TRUE.equals(dto.getArriveStatus())){
                    f.setValue("已到达");
                }else {
                    f.setValue("未到达");
                }
            }
            // 伤亡状态
            if ("casualtiesStatus".equals(f.getKey())) {
                if ( Boolean.TRUE.equals(dto.getCasualtiesStatus())){
                    f.setValue("出现伤亡");
                }else {
                    f.setValue("未出现伤亡");
                }
            }
            // 救援状态
            if ("rescueStatus".equals(f.getKey())) {
                if (Boolean.TRUE.equals(dto.getRescueStatus())){
                    f.setValue("救援成功");
                }else{
                    f.setValue("未救援成功");
                }
            }
            // 是否超时
            if ("isTimeout".equals(f.getKey())) {
                if (Boolean.TRUE.equals(dto.getIsTimeout())) {
                    f.setValue("是");
                } else {
                    f.setValue("否");
                }
            }
            // 派遣时间
            if ("dispatchTime".equals(f.getKey()) && !ObjectUtils.isEmpty(dto.getDispatchTime())) {
                f.setValue(simpleDateFormat.format(dto.getDispatchTime()));
            }
            // 到达时间
            if ("arriveTime".equals(f.getKey()) && !ObjectUtils.isEmpty(dto.getArriveTime())) {
                f.setValue(simpleDateFormat.format(dto.getArriveTime()));
            }
            // 完成时间
            if ("rescueTime".equals(f.getKey()) && !ObjectUtils.isEmpty(dto.getRescueTime())) {
                f.setValue(simpleDateFormat.format(dto.getRescueTime()));
            }

        });
        map.put("datas", jsonData);
        map.put("columns", 2);
        return map;
    }

    public Object getFollowRecords(Long id) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        HashMap<String, Object> result = new HashMap<>();
        ArrayList<Map<String, Object>> group = new ArrayList<>();
        DispatchSaveFeedbackDto dispatchSaveFeedbackDto = dispatchPaperServiceImpl.getDispatchSaveFeedbackDtoByAlertId(id);
        Map<String, Object> objectMap = Bean.BeantoMap(dispatchSaveFeedbackDto);
        // 救援回访
        HashMap<String, Object> rescueFollow = new HashMap<>();
        List<FormValue> jsonData = getJsonData(rescueFollowJson);
        jsonData.forEach(formValue -> {
            Object o = objectMap.get(formValue.getKey());
            if (!ObjectUtils.isEmpty(o)) {
                formValue.setValue(o.toString());
                if ("saveFeedbackTime".equals(formValue.getKey())) {
                    formValue.setValue(simpleDateFormat.format(dispatchSaveFeedbackDto.getSaveFeedbackTime()));
                }
            }
        });
        rescueFollow.put("columns", 2);
        rescueFollow.put("datas", jsonData);
        rescueFollow.put("renderType", "basic");
        rescueFollow.put("key", "rescueFollow");
        rescueFollow.put("displayName", "救援回访");
        group.add(rescueFollow);
        // 维修反馈
        HashMap<String, Object> repairFollow = new HashMap<>();
        List<FormValue> repairJson = getJsonData(repairFollowJson);
        repairJson.forEach(f -> {
            Object o = objectMap.get(f.getKey());
            if (!ObjectUtils.isEmpty(o)) {
                f.setValue(o.toString());
                if ("feedbackFinishTime".equals(f.getKey())) {
                    f.setValue(simpleDateFormat.format(dispatchSaveFeedbackDto.getFeedbackFinishTime()));
                }
                if ("fixResult".equals(f.getKey())) {
                    f.setValue(this.getBaseMapper().getDictName(dispatchSaveFeedbackDto.getFixResult()));
                }
                if ("errorResult".equals(f.getKey())) {
                    f.setValue(this.getBaseMapper().getDictName(dispatchSaveFeedbackDto.getErrorResult()));
                }
            }
        });
        repairFollow.put("columns", 2);
        repairFollow.put("datas", repairJson);
        repairFollow.put("renderType", "basic");
        repairFollow.put("key", "repairFollow");
        repairFollow.put("displayName", "维修反馈");
        group.add(repairFollow);
        result.put("subs", group);
        return result;
    }

    public Object getDetail(Long id) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        HashMap<String, Object> keyinfoData = new HashMap<>();
        // 基本信息
        List<FormValue> jsonData = getJsonData(emergencyInformation);
        AlertCalledFormDto alertCalledFormVo = getAlertCalledFormDto(id);
        Map<String, Object> objectMap = Bean.BeantoMap(alertCalledFormVo.getAlertCalledDto());
        List<FormValue> dynamicFormAlert = alertCalledFormVo.getDynamicFormAlert();
        jsonData.forEach(f -> {
            Object o = objectMap.get(f.getKey());
            if (!ObjectUtils.isEmpty(o)) {
                f.setValue(o.toString());
                if ("callTime".equals(f.getKey())){
                    f.setValue(simpleDateFormat.format(alertCalledFormVo.getAlertCalledDto().getCallTime()));
                }
            }
        });
        jsonData.addAll(dynamicFormAlert);
        // 使用单位信息
        // 获取根据警情获取电梯信息
        Map<String, Object> map = elevatorServiceImpl.selectByAlertId(id);
        // 根据设备id 获取使用单位信息
        Map<String, Object> useUnitMap = elevatorServiceImpl.selectUseUnitByAlertId(String.valueOf(map.get("sequenceNbr")));
        if (!ObjectUtils.isEmpty(useUnitMap)) {
            jsonData.forEach(f -> {
                // 单位名称
                if ("useUnitName".equals(f.getKey())) {
                    f.setValue(ObjectUtils.isEmpty(useUnitMap.get("useUnitName")) ? null : String.valueOf(useUnitMap.get("useUnitName")));
                }
                // 单位电话
//               if ("principalPhone".equals(f.getKey())){
//
//               }
                // 单位地址
                if ("unitAddress".equals(f.getKey())) {
                    f.setValue(ObjectUtils.isEmpty(useUnitMap.get("address")) ? null : String.valueOf(useUnitMap.get("address")));
                }
                // 安全管理员
                if ("securityAdministrator".equals(f.getKey())) {
                    f.setValue(ObjectUtils.isEmpty(useUnitMap.get("manager")) ? null : String.valueOf(useUnitMap.get("manager")));
                }
                // 安全管理员电话
                if ("securityAdministratorPhone".equals(f.getKey())) {
                    f.setValue(ObjectUtils.isEmpty(useUnitMap.get("managerPhone")) ? null : String.valueOf(useUnitMap.get("managerPhone")));
                }
            });
        }
        // 处置记录
        LambdaQueryWrapper<RepairConsult> queryWrapper = new LambdaQueryWrapper<RepairConsult>();
        queryWrapper.eq(RepairConsult::getParentId, id).orderByDesc(RepairConsult::getRecDate);
        List<RepairConsult> list = repairConsultServiceImpl.list(queryWrapper);
        HashMap<String, Object> datas = new HashMap<>();
        ArrayList<Map<String, Object>> records = new ArrayList<>();
        list.forEach(r -> {
            HashMap<String, Object> data = new HashMap<>();
            data.put("label", r.getAlertStatus());
            data.put("operatingTime", r.getRecDate());
            data.put("operater", r.getDescription());
            records.add(data);
        });
        // 96333码
        HashMap<String, Object> qrcode = new HashMap<>();
        if (!ObjectUtils.isEmpty(alertCalledFormVo.getAlertCalledDto())) {
            qrcode.put("title", "96333码");
            qrcode.put("value", alertCalledFormVo.getAlertCalledDto().getDeviceId());
            try {
                String problemTime = DateUtil.formatDate(new Date(), DateUtil.Y_M_D_HMS);
                qrcode.put("text", DateUtil.formatDate(DateUtil.smartFormat(problemTime), "yyyy-MM-dd"));
                qrcode.put("subtext", DateUtil.formatDate(DateUtil.smartFormat(problemTime), "HH:mm:ss"));
                String color;
                if (alertCalledFormVo.getAlertCalledDto().getAlertStatus()) {
                    color = "green";
                } else {
                    color = "red";
                }
                    qrcode.put("color", color);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        datas.put("datas", records);
        datas.put("title", "处置记录");
        datas.put("renderType", "timeline");
        keyinfoData.put("title", ObjectUtils.isEmpty(useUnitMap.get("useUnitName")) ? null : String.valueOf(useUnitMap.get("useUnitName")));
        keyinfoData.put("keyParams", jsonData);
        keyinfoData.put("infoRecords", datas);
        keyinfoData.put("qrcode", qrcode);
        return keyinfoData;
    }

    public Page<AlertCalledQueryDto> getAlertCalledRecords(Page<AlertCalledQueryDto> page, AlertCalledQueryDto alertCalledQueryDto, String cityCode){
        String orgCode = getAndSetOrgCode(cityCode);
        return alertCalledMapper.getAlertCalledRecords(page,alertCalledQueryDto, orgCode);
    }

    public String getAndSetOrgCode(String cityCode) {
        String orgCode = regionCodeOrgCodeMap.get(cityCode);
        if (orgCode == null) {
            orgCode = this.getBaseMapper().getOrgCodeByCompanyCode(cityCode);
            if (orgCode != null) {
                regionCodeOrgCodeMap.put(cityCode, orgCode);
            }
        }
        return orgCode;
    }


    private List<FormValue> getJsonData(Resource resource) {
        String json;
        try {
            json = IOUtils.toString(resource.getInputStream(), String.valueOf(StandardCharsets.UTF_8));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return parseArray(json, FormValue.class);
    }

}