package com.inspur.thrid.impl;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.i18n.phonenumbers.PhoneNumberToCarrierMapper;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
import com.google.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder;
import com.inspur.common.config.InspurConfig;
import com.inspur.common.core.redis.RedisCache;
import com.inspur.common.utils.DateUtils;
import com.inspur.domain.ElevatorInfo;
import com.inspur.domain.ElevatorPersonInfo;
import com.inspur.domain.ElevatorWorkNode;
import com.inspur.domain.ElevatorWorkOrder;
import com.inspur.mapper.ElevatorInfoMapper;
import com.inspur.mapper.ElevatorPersonInfoMapper;
import com.inspur.mapper.ElevatorWorkNodeMapper;
import com.inspur.mapper.ElevatorWorkOrderMapper;
import com.inspur.system.service.ISysConfigService;
import com.inspur.thrid.IPBXService;
import com.inspur.thrid.PBXConstant;
import com.inspur.websoket.client.bean.ws.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * PBX API impl
 * @author lihao16
 */
@Service
@Slf4j
public class PBXServiceImpl implements IPBXService {

    /**
     * pbx url
     */
    @Value("${pbx.url}")
    private String pbxUrl;

    /**
     * 应用key
     */
    @Value("${pbx.clientId}")
    private String clientId;

    /**
     * 密钥
     */
    @Value("${pbx.secret}")
    private String secret;

    @Value("${pbx.active}")
    private String pbxActive;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private RedisCache redisCache;

    private static final String SUCCESS = "0";

    @Autowired
    private ElevatorWorkOrderMapper elevatorWorkOrderMapper;

    @Autowired
    private ElevatorWorkNodeMapper elevatorWorkNodeMapper;

    @Autowired
    private ElevatorInfoMapper elevatorInfoMapper;

    @Autowired
    private ElevatorPersonInfoMapper elevatorPersonInfoMapper;

    /**
     * 手机号基本工具类
     */
    private final static PhoneNumberUtil PHONE_NUMBER_UTIL = PhoneNumberUtil.getInstance();

    /**
     * 运营商
     */
    private final static PhoneNumberToCarrierMapper CARRIER_MAPPER = PhoneNumberToCarrierMapper.getInstance();

    /**
     *
     */
    private final static PhoneNumberOfflineGeocoder GEO_CODER = PhoneNumberOfflineGeocoder.getInstance();

    private final static String CHINA = "中国";

    private final static String WULUMUQI = "乌鲁木齐";

    @Override
    public String getAccessToken() {
        log.debug("getAccessToken start");
        // 从redis获取token
        String token  = (String) redisCache.getCacheObject(PBXConstant.PBX_TOKEN_KEY);
        if(!StringUtils.isEmpty(token)){
            return token;
        }
        Map<String, String> params = new HashMap<String, String>(6);
        // 应用key
        params.put("username", clientId);
        // 密钥
        params.put("password", secret);
        String url = pbxUrl + PBXConstant.GET_TOKEN;
        log.debug("getAccessToken,url：" + url + "；param：" + params);

        HttpRequest postRequest = HttpUtil.createPost(url);
        // 添加头部信息
        postRequest.header("Content-Type", "application/json");
        postRequest.header("User-Agent", "OpenAPI");
        //postRequest.header("Authorization", "Bearer your_token_here");
        // 设置请求体
        // String body = params.toString();
        JSONObject jsonMap = new JSONObject(params);
        String body = jsonMap.toJSONString();
        // 发送请求
        String res = postRequest.body(body).execute().body();

        log.debug("getAccessToken rsp: " + res);
        JSONObject jsonObject = JSONObject.parseObject(res);
        if(SUCCESS.equals(jsonObject.getString("errcode"))){
            // 获取token
            String tokenStr = jsonObject.getString("access_token");
            // 获取过期时间
            Integer expire_time = jsonObject.getInteger("access_token_expire_time");

            // 获取刷新token
            String refreshTokenStr = jsonObject.getString("refresh_token");
            // 获取刷新过期时间
            Integer refreshExpireTime = jsonObject.getInteger("refresh_token_expire_time");

            // 将获取的token放入redis，失效时间-1分钟
            redisCache.setCacheObject(PBXConstant.PBX_TOKEN_KEY, tokenStr, expire_time - 60, TimeUnit.SECONDS);
            redisCache.setCacheObject(PBXConstant.PBX_REFRESH_TOKEN_KEY, refreshTokenStr, refreshExpireTime, TimeUnit.SECONDS);

            log.debug("getAccessToken end");
            return tokenStr;
        }
        log.error("getAccessToken failed");
        return null;
    }

    @Scheduled(cron = "0 0/1 * * * ?")
    public void refreshTokenTask() {

        // redis中获取到refreshToken
        String refreshToken  = (String) redisCache.getCacheObject(PBXConstant.PBX_REFRESH_TOKEN_KEY);
        if(!StringUtils.isEmpty(refreshToken)){
            this.getRefreshToken(refreshToken);
            return;
        }
        Map<String, String> params = new HashMap<String, String>(6);
        // 应用key
        params.put("username", clientId);
        // 密钥
        params.put("password", secret);
        String url = pbxUrl + PBXConstant.GET_TOKEN;
        log.debug("getAccessToken,url：" + url + "param：" + params);

        HttpRequest postRequest = HttpUtil.createPost(url);
        // 添加头部信息
        postRequest.header("Content-Type", "application/json");
        postRequest.header("User-Agent", "OpenAPI");
        // 设置请求体
        JSONObject jsonMap = new JSONObject(params);
        String body = jsonMap.toJSONString();
        // 发送请求
        String res = postRequest.body(body).execute().body();

        log.debug("getAccessToken rsp: " + res);
        JSONObject jsonObject = JSONObject.parseObject(res);
        if (SUCCESS.equals(jsonObject.getString("errcode"))) {
            // 获取token
            String tokenStr = jsonObject.getString("access_token");
            // 获取过期时间
            Integer expire_time = jsonObject.getInteger("access_token_expire_time");
            // 获取刷新token
            String refreshTokenStr = jsonObject.getString("refresh_token");
            // 获取刷新过期时间
            Integer refreshExpireTime = jsonObject.getInteger("refresh_token_expire_time");
            // 将获取的token放入redis，失效时间-1分钟
            redisCache.setCacheObject(PBXConstant.PBX_TOKEN_KEY, tokenStr, expire_time - 60, TimeUnit.SECONDS);
            redisCache.setCacheObject(PBXConstant.PBX_REFRESH_TOKEN_KEY, refreshTokenStr ,refreshExpireTime, TimeUnit.SECONDS);
            log.debug("getAccessToken end");
        }
    }

    /**
     * 刷新访问 Token
     * @param refreshToken token信息
     * @return
     */
    @Override
    public String getRefreshToken(String refreshToken){
        log.debug("refreshToken start");
        Map<String, String> params = new HashMap<String, String>(6);
        // 应用key
        params.put("refresh_token", refreshToken);
        String url = pbxUrl + PBXConstant.REFRESH_TOKEN;
        log.info("refreshToken,url：" + url + "param：" + params);

        HttpRequest postRequest = HttpUtil.createPost(url);
        // 添加头部信息
        postRequest.header("Content-Type", "application/json");
        // 设置请求体
        JSONObject jsonMap = new JSONObject(params);
        String body = jsonMap.toJSONString();
        // 发送请求
        String res = postRequest.body(body).execute().body();

        log.debug("refreshToken rsp: " + res);
        JSONObject jsonObject = JSONObject.parseObject(res);
        if(SUCCESS.equals(jsonObject.getString("errcode"))){
            // 获取token
            String tokenStr = jsonObject.getString("access_token");
            // 获取过期时间
            Integer expire_time = jsonObject.getInteger("access_token_expire_time");
            // 获取刷新token
            String refreshTokenStr = jsonObject.getString("refresh_token");
            // 获取刷新过期时间
            Integer refreshExpireTime = jsonObject.getInteger("refresh_token_expire_time");

            // 将获取的token放入redis，失效时间-1分钟
            redisCache.setCacheObject(PBXConstant.PBX_TOKEN_KEY, tokenStr, expire_time - 60, TimeUnit.SECONDS);
            redisCache.setCacheObject(PBXConstant.PBX_REFRESH_TOKEN_KEY, refreshTokenStr,refreshExpireTime, TimeUnit.SECONDS);

            log.debug("refreshToken end");
            return tokenStr;
        }
        log.error("refreshToken failed");
        return null;
    }

    @Override
    public void dtmfEvent(JSONObject messageJson) {
        WsDtmfMessage wsDtmfMessage = JSON.toJavaObject(messageJson, WsDtmfMessage.class);
        // call_id
        String callId = wsDtmfMessage.getMsg().getCall_id();
        // 读取当用户输入的按键信息 直接通过infos获取
        String dtmf = wsDtmfMessage.getMsg().getInfos();

        // 如果为空直接返回，默认未按# 无法获取正常的安全码
        if (StringUtils.isEmpty(dtmf)) {
            log.info("=== dtmf is not end with # , return === ");
            return;
        }
        // bugfix 出现存在infos内容为IVR的情况 排除这类情况
        if (PBXConstant.IVR_CODE_SAFE_CODE.equals(dtmf) || PBXConstant.IVR_CODE_TRANSFER_CODE.equals(dtmf)
                || PBXConstant.IVR_CODE_ERROR_SAFE_CODE.equals(dtmf) || PBXConstant.IVR_CODE_ERROR_NO_PERSON_CODE.equals(dtmf)
                || PBXConstant.IVR_CODE_BUSY_CODE.equals(dtmf) || dtmf.length() > 6) {
            return;
        }
        log.info("dtmfEvent,callId:{}",callId);
        /** 以#结束 通过info获取 begin  */
        /*String dtmf = wsDtmfMessage.getMsg().getInfo();
        String dtmfValue = redisCache.getCacheObject(PBXConstant.DTMF_KEY + callId);
        if (StringUtils.isEmpty(dtmfValue)) {
            redisCache.setCacheObject(PBXConstant.DTMF_KEY + callId, dtmf, 300, TimeUnit.SECONDS);
        }else {
            dtmf = dtmfValue + dtmf;
        }
        // 获取当前按键信息如果为空或者不携带# return
        if (StringUtils.isEmpty(dtmf) || !dtmf.contains("#")) {
            log.info("dtmf is null or not contains # ,dtmf:{}",dtmf);
            return;
        }
        dtmf = dtmf.substring(dtmf.lastIndexOf("#") - 6, dtmf.lastIndexOf("#"));*/
        /** 以#结束 通过info获取 end  */
        // 根据call_id 查询是否已经存在工单
        ElevatorWorkOrder workOrder = elevatorWorkOrderMapper.selectElevatorWorkOrderByCallId(callId);
        if (workOrder == null) {
            // 生成工单信息
            workOrder = createWorkOrder(wsDtmfMessage);
        }
        // 根据安全码信息查询电梯信息
        ElevatorInfo elevatorInfo = elevatorInfoMapper.selectElevatorInfoBySafeCode(dtmf);
        // 根据电梯码未查询到电梯信息  转接新的ivr
        if (elevatorInfo == null) {
            Integer failNum = workOrder.getFailNum() + 1;
            // 如果输入错误次数小于3次 则提示继续输入
            if (failNum < 3) {
                transferIVR(wsDtmfMessage,PBXConstant.IVR_CODE_ERROR_SAFE_CODE);
            }else {
                // 如果输入错误次数大于3次 则提示输入错误，并结束工单
                // transferIVR(wsDtmfMessage,PBXConstant.IVR_CODE_ERROR_SAFE_CODE);
                // API挂断电话
                log.info("safe code put in fail num > 3 , hangup call");
                hangupCall(wsDtmfMessage);
            }
            createOrderNode_2(workOrder,wsDtmfMessage,0,dtmf);
            workOrder.setFailNum(failNum);
            elevatorWorkOrderMapper.updateElevatorWorkOrder(workOrder);
            return;
        }else {
            createOrderNode_2(workOrder,wsDtmfMessage,1,dtmf);
        }
        String lastCallCode = configService.selectConfigByKey("sys.pbx.lastCallCode");
        // 根据电梯信息 查询所有的维保人员
        List<ElevatorPersonInfo> personInfoList = elevatorPersonInfoMapper.selectElevatorPersonInfoByElevatorId(elevatorInfo.getDeviceId());
        if (CollectionUtils.isEmpty(personInfoList)) {
            // transferIVR(wsDtmfMessage,PBXConstant.IVR_CODE_ERROR_NO_PERSON_CODE);
            transferCall_v3(wsDtmfMessage,lastCallCode);
            return;
        }
        // 更新工单内电梯信息
        updateOrderInfo(workOrder,elevatorInfo,dtmf,personInfoList);
        // 维保人员
        List<ElevatorPersonInfo> wbPersonInfos = personInfoList.stream()
                .filter(elevatorPersonInfo -> elevatorPersonInfo.getPersonType() == 2L).collect(Collectors.toList());
        List<ElevatorPersonInfo> wyPersonInfos = personInfoList.stream()
                .filter(elevatorPersonInfo -> elevatorPersonInfo.getPersonType() == 1L).collect(Collectors.toList());
        // 启动线程，尝试拨打电话
        ElevatorWorkOrder finalWorkOrder = workOrder;
        Thread trasnferCallThread = new Thread(() -> {
            forEachCall(wbPersonInfos,wyPersonInfos,wsDtmfMessage, finalWorkOrder,elevatorWorkOrderMapper,elevatorWorkNodeMapper,lastCallCode);
        });
        trasnferCallThread.start();
    }

    private void hangupCall(WsDtmfMessage wsDtmfMessage) {
        String pbxToken = redisCache.getCacheObject(PBXConstant.PBX_TOKEN_KEY);
        Map<String, String> params = new HashMap<String, String>(6);
        // 主叫号码。
        String channelId = "";
        if (pbxActive.equals(PBXConstant.PBX_ACTIVE_DEV)) {
            ExtensionInfo extensionInfo = wsDtmfMessage.getMsg().getMembers().get(0).getExtension();
            channelId = extensionInfo.getChannel_id();
        }else if (pbxActive.equals(PBXConstant.PBX_ACTIVE_PROD)) {
            BoundInfo boundInfo = wsDtmfMessage.getMsg().getMembers().get(0).getInbound();
            channelId = boundInfo.getChannel_id();
        }else {
            log.error("pbxActive is not DEV or PROD");
            return;
        }
        params.put("channel_id", channelId);

        String url = pbxUrl + PBXConstant.CALL_HANGUP + pbxToken;
        log.info("hangupCall,url ：" + url + ",params ：" + params);
        HttpRequest postRequest = HttpUtil.createPost(url);
        // 添加头部信息
        postRequest.header("Content-Type", "application/json");
        // 设置请求体
        JSONObject jsonMap = new JSONObject(params);
        String body = jsonMap.toJSONString();
        // 发送请求
        String res = postRequest.body(body).execute().body();
        log.debug("hangupCall rsp: " + res);
        JSONObject jsonObject = JSONObject.parseObject(res);
        if(SUCCESS.equals(jsonObject.getString("errcode"))){
            log.info("hangupCall success,callId:{}",wsDtmfMessage.getMsg().getCall_id());
        }else {
            log.error("hangupCall failed");
        }
    }

    @SneakyThrows
    private void forEachCall(List<ElevatorPersonInfo> wbPersonInfos, List<ElevatorPersonInfo> wyPersonInfos,
                             WsDtmfMessage wsDtmfMessage, ElevatorWorkOrder workOrder,
                             ElevatorWorkOrderMapper workOrderMapper, ElevatorWorkNodeMapper workNodeMapper,String lastCallCode) {
        String callId = wsDtmfMessage.getMsg().getCall_id();
        if (!CollectionUtils.isEmpty(wbPersonInfos)) {
            log.info("开始呼叫维保人员：wbPersonInfos.size = " + wbPersonInfos.size());
            for (ElevatorPersonInfo wbPerson : wbPersonInfos) {
                // 查询是否已经存在电话结束的节点，如果有将跳出循环
                ElevatorWorkNode endNode = elevatorWorkNodeMapper.selectElevatorWorkNodeByCallIdAndType(callId, "4");
                if (endNode != null) {
                    return;
                }
                // 防止挂断，临时转接ivr
                transferIVR(wsDtmfMessage,PBXConstant.IVR_CODE_TRANSFER_CODE);
                Thread.sleep(3000);
                String callNumber = wbPerson.getPhoneNo();
                String personName = wbPerson.getPersonName();
                String unitName = wbPerson.getUnitName();
                log.info("开始呼叫维保人员，callNumber:{}", callNumber + ",personName : " + personName);
                createOrderNode_3("联系维保人员", workOrder,wsDtmfMessage,false,callNumber,personName);
                transferCall_v3(wsDtmfMessage, callNumber);
                // 接口调用成功，缓存数据，call_id  RING
                redisCache.setCacheObject(PBXConstant.PBX_TRANSFER_CODE_KEY + callNumber, callId, 60 * 5, TimeUnit.SECONDS);
                // 等待三十秒  读取当前call_id 的状态
                Thread.sleep(30000);
                String callState = redisCache.getCacheObject(PBXConstant.PBX_TRANSFER_CODE_KEY + callId);
                // 未应答，继续拨打电话 结束当前通话
                if (!PBXConstant.CALL_STATUS_ANSWER.equals(callState)) {
                    log.info("呼叫救援人员电话未接通，继续呼叫下一个救援人员，callNumber:{}",callNumber);
                    continue;
                }
                // 已成功接通
                workOrder.setHandler(personName);
                workOrder.setHandleContactTel(callNumber);
                workOrder.setHandleDepart(unitName);
                workOrder.setHandleTime(DateUtils.getNowDate());
                workOrder.setCallId(callId);
                workOrder.setStatus(1);
                workOrderMapper.updateElevatorWorkOrder(workOrder);
                workNodeMapper.updateNodeIsSuccessByCallIdAndPhoneNum(callId, callNumber,1);
                return;
            }
        }
        if (!CollectionUtils.isEmpty(wyPersonInfos)) {
            log.info("开始呼叫物业人员：wyPersonInfos.size = " + wyPersonInfos.size());
            for (ElevatorPersonInfo wyPerson : wyPersonInfos) {
                // 查询是否已经存在电话结束的节点，如果有将跳出循环
                ElevatorWorkNode endNode = elevatorWorkNodeMapper.selectElevatorWorkNodeByCallIdAndType(callId, "4");
                if (endNode != null) {
                    return;
                }
                transferIVR(wsDtmfMessage, PBXConstant.IVR_CODE_TRANSFER_CODE);
                Thread.sleep(3000);
                String callNumber = wyPerson.getPhoneNo();
                String personName = wyPerson.getPersonName();
                String unitName = wyPerson.getUnitName();
                createOrderNode_3("联系物业人员", workOrder, wsDtmfMessage, false, callNumber, personName);
                transferCall_v3(wsDtmfMessage, callNumber);
                // 接口调用成功，缓存数据，call_id  RING
                redisCache.setCacheObject(PBXConstant.PBX_TRANSFER_CODE_KEY + callNumber, callId, 60 * 5, TimeUnit.SECONDS);
                // 等待三十秒  读取当前call_id 的状态
                Thread.sleep(30000);
                String callState = redisCache.getCacheObject(PBXConstant.PBX_TRANSFER_CODE_KEY + callId);
                // 未应答，继续拨打电话 结束当前通话
                if (!PBXConstant.CALL_STATUS_ANSWER.equals(callState)) {
                    log.info("呼叫救援人员电话未接通，继续呼叫下一个救援人员，callNumber:{}", callNumber);
                    continue;
                }
                // 已成功接通
                workOrder.setHandler(personName);
                workOrder.setHandleContactTel(callNumber);
                workOrder.setHandleDepart(unitName);
                workOrder.setHandleTime(DateUtils.getNowDate());
                workOrder.setCallId(callId);
                workOrder.setStatus(1);
                workOrderMapper.updateElevatorWorkOrder(workOrder);
                workNodeMapper.updateNodeIsSuccessByCallIdAndPhoneNum(callId, callNumber, 1);
                return;
            }
        }
        // 查询是否已经存在电话结束的节点，如果有将跳出循环
        ElevatorWorkNode endNode = elevatorWorkNodeMapper.selectElevatorWorkNodeByCallIdAndType(callId, "4");
        if (endNode != null) {
            return;
        }
        transferIVR(wsDtmfMessage, PBXConstant.IVR_CODE_TRANSFER_CODE);
        Thread.sleep(3000);
        String personName = "应急保底救援";
        String unitName = "应急保底救援";
        createOrderNode_3("联系应急保底救援", workOrder, wsDtmfMessage, false, lastCallCode, personName);
        log.info("开始联系应急保底救援 : " + lastCallCode);
        transferCall_v3(wsDtmfMessage, lastCallCode);
        // 接口调用成功，缓存数据，call_id  RING
        redisCache.setCacheObject(PBXConstant.PBX_TRANSFER_CODE_KEY + lastCallCode, callId, 60 * 5, TimeUnit.SECONDS);
        // 等待三十秒  读取当前call_id 的状态
        Thread.sleep(30000);
        String callState = redisCache.getCacheObject(PBXConstant.PBX_TRANSFER_CODE_KEY + callId);
        // 未应答，继续拨打电话 结束当前通话
        if (!PBXConstant.CALL_STATUS_ANSWER.equals(callState)) {
            transferIVR(wsDtmfMessage,PBXConstant.IVR_CODE_BUSY_CODE);
            return;
        }
        // 已成功接通
        workOrder.setHandler(personName);
        workOrder.setHandleContactTel(lastCallCode);
        workOrder.setHandleDepart(unitName);
        workOrder.setHandleTime(DateUtils.getNowDate());
        workOrder.setCallId(callId);
        workOrder.setStatus(1);
        workOrderMapper.updateElevatorWorkOrder(workOrder);
        workNodeMapper.updateNodeIsSuccessByCallIdAndPhoneNum(callId, lastCallCode, 1);
    }

    private boolean transferIVR(WsDtmfMessage wsDtmfMessage, String ivrCodeTransferCode) {
        String pbxToken = redisCache.getCacheObject(PBXConstant.PBX_TOKEN_KEY);
        Map<String, String> params = new HashMap<String, String>(6);
        // 主叫号码。
        String channelId = "";
        if (pbxActive.equals(PBXConstant.PBX_ACTIVE_DEV)) {
            ExtensionInfo extensionInfo = wsDtmfMessage.getMsg().getMembers().get(0).getExtension();
            channelId = extensionInfo.getChannel_id();
        }else if (pbxActive.equals(PBXConstant.PBX_ACTIVE_PROD)) {
            BoundInfo boundInfo = wsDtmfMessage.getMsg().getMembers().get(0).getInbound();
            channelId = boundInfo.getChannel_id();
        }else {
            log.error("pbxActive is not DEV or PROD");
            return false;
        }
        params.put("type", PBXConstant.CALL_TRANSFER_TYPE_BIND);
        params.put("channel_id", channelId);
        params.put("number", ivrCodeTransferCode);
        params.put("dial_permission","1001");

        String url = pbxUrl + PBXConstant.CALL_TRANSFER + pbxToken;
        log.info("transferIVR,url ：" + url + ",params ：" + params);
        HttpRequest postRequest = HttpUtil.createPost(url);
        // 添加头部信息
        postRequest.header("Content-Type", "application/json");
        // 设置请求体
        JSONObject jsonMap = new JSONObject(params);
        String body = jsonMap.toJSONString();
        // 发送请求
        String res = postRequest.body(body).execute().body();
        log.debug("transferIVR rsp: " + res);
        JSONObject jsonObject = JSONObject.parseObject(res);
        if(SUCCESS.equals(jsonObject.getString("errcode"))){
            log.info("transferIVR success,callId:{}",wsDtmfMessage.getMsg().getCall_id());
            return true;
        }else {
            log.error("transferIVR failed");
            return false;
        }
    }

    private void updateOrderInfo(ElevatorWorkOrder workOrder, ElevatorInfo elevatorInfo, String dtmf,List<ElevatorPersonInfo> personInfoList) {
        // 社区信息
        workOrder.setRegion(elevatorInfo.getInArea());
        workOrder.setRegionCode(elevatorInfo.getAreaCode());
        workOrder.setCommunity(elevatorInfo.getInVillage());
        workOrder.setBuilding(elevatorInfo.getInBuild());
        workOrder.setElevatorName(elevatorInfo.getName());
        workOrder.setSecurityCode(dtmf);
        workOrder.setDeviceNo(elevatorInfo.getDeviceNo());
        workOrder.setDeviceSn(elevatorInfo.getDeviceSn());
        workOrder.setMaintCompany(elevatorInfo.getUnitName());
        // 人员信息
        if (!CollectionUtils.isEmpty(personInfoList)) {
            // 维保人员
            List<ElevatorPersonInfo> wbPersonInfos = personInfoList.stream()
                    .filter(elevatorPersonInfo -> elevatorPersonInfo.getPersonType() == 2L).collect(Collectors.toList());
            // 物业人员
            List<ElevatorPersonInfo> wyPersonInfos = personInfoList.stream()
                    .filter(elevatorPersonInfo -> elevatorPersonInfo.getPersonType() == 1L).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(wbPersonInfos)) {
                ElevatorPersonInfo wbFirst = wbPersonInfos.get(0);
                if (wbFirst != null) {
                    workOrder.setMaintFristPerson(wbFirst.getPersonName());
                    workOrder.setMaintfristTel(wbFirst.getPhoneNo());
                }
                if (wbPersonInfos.size() > 1) {
                    ElevatorPersonInfo wbSecond = wbPersonInfos.get(1);
                    if (wbSecond != null) {
                        workOrder.setMaintSecondPerson(wbSecond.getPersonName());
                        workOrder.setMaintSecondTel(wbSecond.getPhoneNo());
                    }
                }
            }
            if (!CollectionUtils.isEmpty(wyPersonInfos)) {
                ElevatorPersonInfo wyFirst = wyPersonInfos.get(0);
                if (wyFirst != null) {
                    workOrder.setTenementPerson(wyFirst.getPersonName());
                    workOrder.setTenementTel(wyFirst.getPhoneNo());
                }
            }
        }
        elevatorWorkOrderMapper.updateElevatorWorkOrder(workOrder);
    }

    private boolean transferCall_v3(WsDtmfMessage wsDtmfMessage,String callNumber) {
        String pbxToken = redisCache.getCacheObject(PBXConstant.PBX_TOKEN_KEY);
        Map<String, String> params = new HashMap<String, String>(6);
        // 主叫号码。
        String channelId = "";
        if (pbxActive.equals(PBXConstant.PBX_ACTIVE_DEV)) {
            ExtensionInfo extensionInfo = wsDtmfMessage.getMsg().getMembers().get(0).getExtension();
            channelId = extensionInfo.getChannel_id();
        }else if (pbxActive.equals(PBXConstant.PBX_ACTIVE_PROD)) {
            BoundInfo boundInfo = wsDtmfMessage.getMsg().getMembers().get(0).getInbound();
            channelId = boundInfo.getChannel_id();
        }else {
            log.error("pbxActive is not DEV or PROD");
            return false;
        }
        params.put("type", PBXConstant.CALL_TRANSFER_TYPE_BIND);
        params.put("channel_id", channelId);
        // params.put("number", callNumber);
        // params.put("number", "0" + callNumber);
        if (isLocalCall(callNumber)) {
            params.put("number", callNumber);
        }else {
            params.put("number", "0" + callNumber);
        }
        params.put("dial_permission","1000");

        String url = pbxUrl + PBXConstant.CALL_TRANSFER + pbxToken;
        log.info("transferCall,url ：" + url + ",params ：" + params);
        HttpRequest postRequest = HttpUtil.createPost(url);
        // 添加头部信息
        postRequest.header("Content-Type", "application/json");
        // 设置请求体
        JSONObject jsonMap = new JSONObject(params);
        String body = jsonMap.toJSONString();
        // 发送请求
        String res = postRequest.body(body).execute().body();
        log.debug("transferCall rsp: " + res);
        JSONObject jsonObject = JSONObject.parseObject(res);
        if(SUCCESS.equals(jsonObject.getString("errcode"))){
            log.info("transferCall success,callId:{}",wsDtmfMessage.getMsg().getCall_id());
            return true;
        }else {
            log.error("transferCall failed");
            return false;
        }
    }

    private boolean isLocalCall(String callNumber) {
        /*if (callNumber.startsWith("1999")) {
            return true;
        }*/
        // String region = getRegionInfoByPhone(callNumber);
        String region = getRegionInfoByPhoneAPI(callNumber);
        log.info(" === get region info by phoneNumber : {}, region is  : {}",callNumber,region);
        if (StringUtils.isEmpty(region)) {
            return true;
        }
        if (region.equals(WULUMUQI)) {
            return true;
        }
        return false;
    }

    private boolean transferCall_v2(WsCallInMessage wsCallInMessage,String callNumber) {
        String pbxToken = redisCache.getCacheObject(PBXConstant.PBX_TOKEN_KEY);
        Map<String, String> params = new HashMap<String, String>(6);
        // 主叫号码。
        String channelId = "";
        if (pbxActive.equals(PBXConstant.PBX_ACTIVE_DEV)) {
            ExtensionInfo extensionInfo = wsCallInMessage.getMsg().getMembers().get(0).getExtension();
            channelId = extensionInfo.getChannel_id();
        }else if (pbxActive.equals(PBXConstant.PBX_ACTIVE_PROD)) {
            BoundInfo boundInfo = wsCallInMessage.getMsg().getMembers().get(0).getInbound();
            channelId = boundInfo.getChannel_id();
        }else {
            log.error("pbxActive is not DEV or PROD");
            return false;
        }
        params.put("type", PBXConstant.CALL_TRANSFER_TYPE_BIND);
        params.put("channel_id", channelId);
        params.put("number", callNumber);
        params.put("dial_permission","1000");

        String url = pbxUrl + PBXConstant.CALL_TRANSFER + pbxToken;
        log.info("transferCall,url ：" + url + ",params ：" + params);
        HttpRequest postRequest = HttpUtil.createPost(url);
        // 添加头部信息
        postRequest.header("Content-Type", "application/json");
        // 设置请求体
        JSONObject jsonMap = new JSONObject(params);
        String body = jsonMap.toJSONString();
        // 发送请求
        String res = postRequest.body(body).execute().body();
        log.debug("transferCall rsp: " + res);
        JSONObject jsonObject = JSONObject.parseObject(res);
        if(SUCCESS.equals(jsonObject.getString("errcode"))){
            log.info("transferCall success,callId:{}",wsCallInMessage.getMsg().getCall_id());
            return true;
        }else {
            log.error("transferCall failed");
            return false;
        }
    }

    private String transferCall(WsDtmfMessage wsDtmfMessage, String callNumber) {
        String pbxToken = redisCache.getCacheObject(PBXConstant.PBX_TOKEN_KEY);
        Map<String, String> params = new HashMap<String, String>(6);
        // 主叫号码。
        params.put("caller", PBXConstant.IVR_CODE_TRANSFER_CODE);
        params.put("callee", callNumber);

        String url = pbxUrl + PBXConstant.CALL_DIAL + pbxToken;
        log.info("transferCall dial ,url ：" + url + ",params ：" + params);
        HttpRequest postRequest = HttpUtil.createPost(url);
        // 添加头部信息
        postRequest.header("Content-Type", "application/json");
        // 设置请求体
        JSONObject jsonMap = new JSONObject(params);
        String body = jsonMap.toJSONString();
        // 发送请求
        String res = postRequest.body(body).execute().body();
        log.debug("transferCall dial rsp: " + res);
        JSONObject jsonObject = JSONObject.parseObject(res);
        if(SUCCESS.equals(jsonObject.getString("errcode"))){
            log.info("transferCall dial success,callId:{}",wsDtmfMessage.getMsg().getCall_id());
            return jsonObject.getString("call_id");
        }else {
            log.error("transferCall failed");
            return "";
        }
    }

    /**
     * 创建工单节点—2 提供安全码
     * @param workOrder
     * @param wsDtmfMessage
     * @param isSuccess
     * @param dtmf
     */
    private void createOrderNode_2(ElevatorWorkOrder workOrder,WsDtmfMessage wsDtmfMessage, int isSuccess,String dtmf) {
        // 创建工单节点
        ElevatorWorkNode workNode = new ElevatorWorkNode();
        workNode.setCallId(wsDtmfMessage.getMsg().getCall_id());
        workNode.setWorkOrderId(workOrder.getId());
        workNode.setNodeName("提供安全码");
        workNode.setNodeTime(DateUtils.getNowDate());
        workNode.setContentName("电梯安全码：" + dtmf);
        workNode.setType("2");
        workNode.setIsSuccess(String.valueOf(isSuccess));
        workNode.setCreateTime(DateUtils.getNowDate());
        elevatorWorkNodeMapper.insertElevatorWorkNode(workNode);
    }

    /**
     * 创建工单节点-3 联系人员
     * @param workOrder
     * @param wsDtmfMessage
     * @param isSuccess
     * @param phoneNo
     * @param nodeName
     * @param personName
     */
    private void createOrderNode_3(String nodeName,ElevatorWorkOrder workOrder,WsDtmfMessage wsDtmfMessage,
                                   boolean isSuccess,String phoneNo,String personName) {
        // 创建工单节点
        ElevatorWorkNode workNode = new ElevatorWorkNode();
        workNode.setCallId(wsDtmfMessage.getMsg().getCall_id());
        workNode.setWorkOrderId(workOrder.getId());
        workNode.setNodeName(nodeName);
        workNode.setNodeTime(DateUtils.getNowDate());
        workNode.setContentName(personName);
        workNode.setContentRemark("电话：" + phoneNo);
        workNode.setPhoneNum(phoneNo);
        workNode.setType("3");
        workNode.setIsSuccess(isSuccess ? "1" : "0");
        workNode.setCreateTime(DateUtils.getNowDate());
        elevatorWorkNodeMapper.insertElevatorWorkNode(workNode);
    }

    /**
     * 创建工单节点-4 电话结束
     * @param callId
     * @param workOrder
     */
    private void createOrderNode_4(ElevatorWorkOrder workOrder,String callId) {
        // 防止出现重复数据
        ElevatorWorkNode dbWorkNode = elevatorWorkNodeMapper.selectElevatorWorkNodeByCallIdAndType(callId, "4");
        if (dbWorkNode != null) {
            return;
        }
        // 创建工单节点
        ElevatorWorkNode workNode = new ElevatorWorkNode();
        workNode.setCallId(callId);
        workNode.setWorkOrderId(workOrder.getId());
        workNode.setNodeName("电话结束");
        workNode.setNodeTime(DateUtils.getNowDate());
        workNode.setType("4");
        workNode.setIsSuccess("1");
        workNode.setCreateTime(DateUtils.getNowDate());
        elevatorWorkNodeMapper.insertElevatorWorkNode(workNode);
    }

    private ElevatorWorkOrder createWorkOrder(WsDtmfMessage wsDtmfMessage) {
        log.info("begin create new work order");
        String callId = wsDtmfMessage.getMsg().getCall_id();
        String fromPhone = "";
        // 通话状态
        if (PBXConstant.PBX_ACTIVE_DEV.equals(pbxActive)) {
            ExtensionInfo extensionInfo = wsDtmfMessage.getMsg().getMembers().get(0).getExtension();
            fromPhone = extensionInfo.getNumber();
        }else if (PBXConstant.PBX_ACTIVE_PROD.equals(pbxActive)) {
            BoundInfo boundInfo = wsDtmfMessage.getMsg().getMembers().get(0).getInbound();
            fromPhone = boundInfo.getFrom();
        }else {
            log.error("pbxActive is null");
            return null;
        }
        // 查询工单记录中是否存在了call_id
        ElevatorWorkOrder dbWorkOrder = elevatorWorkOrderMapper.selectElevatorWorkOrderByCallId(callId);
        if (dbWorkOrder != null) {
            return dbWorkOrder;
        }
        // 新电话呼入 创建工单
        ElevatorWorkOrder workOrder = new ElevatorWorkOrder();
        workOrder.setTrappedPersonTel(fromPhone);
        workOrder.setStatus(0);
        workOrder.setCreateDate(DateUtils.getNowDate());
        workOrder.setDelFlag("0");
        workOrder.setCreateTime(DateUtils.getNowDate());
        workOrder.setCallId(callId);
        workOrder.setFailNum(0);
        elevatorWorkOrderMapper.insertElevatorWorkOrder(workOrder);
        // 创建工单节点
        ElevatorWorkNode workNode = new ElevatorWorkNode();
        workNode.setCallId(callId);
        workNode.setWorkOrderId(workOrder.getId());
        workNode.setNodeName("发起申请");
        workNode.setNodeTime(DateUtils.getNowDate());
        workNode.setContentName("被困用户" + fromPhone);
        workNode.setType("1");
        workNode.setIsSuccess("1");
        workNode.setCreateTime(DateUtils.getNowDate());
        elevatorWorkNodeMapper.insertElevatorWorkNode(workNode);
        return workOrder;
    }

    @Override
    public void callStateChange(JSONObject messageJson) {
        WsCallInMessage wsCallInMessage = JSON.toJavaObject(messageJson, WsCallInMessage.class);
        String memberStatus = "";
        String toPhone = "";
        String channelId = "";
        List<Members> members = wsCallInMessage.getMsg().getMembers();
        if (members.size() < 2) {
            log.info("member size is less than 2, no need to transfer");
            return;
        }
        for (Members member : members) {
            // 通话状态
            if (PBXConstant.PBX_ACTIVE_DEV.equals(pbxActive)) {
                ExtensionInfo extensionInfo = member.getExtension();
                memberStatus = extensionInfo.getMember_status();
                toPhone = extensionInfo.getNumber();
                channelId = extensionInfo.getChannel_id();
            }else if (PBXConstant.PBX_ACTIVE_PROD.equals(pbxActive)) {
                BoundInfo boundInfo = member.getOutbound();
                if (null == boundInfo) {
                    continue;
                }
                memberStatus = boundInfo.getMember_status();
                toPhone = boundInfo.getTo();
                channelId = boundInfo.getChannel_id();
                log.info("memberStatus : " + memberStatus + ",toPhone : " + toPhone + ",channelId = " + channelId);
            }else {
                log.error("pbxActive is null");
                return;
            }
            // bugfix toPhone 存在出现IVR号码的情况，这时不处理
            if (StringUtils.isEmpty(toPhone) || toPhone.length() == 4) {
                continue;
            }
            String callId = redisCache.getCacheObject(PBXConstant.PBX_TRANSFER_CODE_KEY + toPhone);
            if (StringUtils.isEmpty(callId)) {
                log.info("no cache transferToValue,key : {}",PBXConstant.PBX_TRANSFER_CODE_KEY + toPhone);
                continue;
            }
            // 救援人员接听电话
            if (PBXConstant.CALL_STATUS_ANSWER.equals(memberStatus)) {
                redisCache.setCacheObject(PBXConstant.PBX_TRANSFER_CODE_KEY + callId, PBXConstant.CALL_STATUS_ANSWER, 60 * 5, TimeUnit.SECONDS);
                // 根据callId 查询被困人员电话，进行转接
                // ElevatorWorkOrder workOrder = elevatorWorkOrderMapper.selectElevatorWorkOrderByCallId(callId);
                log.info("救援人员接听电话，转接至被困人员电话：{}",toPhone);
                // 开启通话录音
                startRecordVoice(channelId);
            }
        }


    }

    private void startRecordVoice(String channelId) {
        String pbxToken = redisCache.getCacheObject(PBXConstant.PBX_TOKEN_KEY);
        Map<String, String> params = new HashMap<String, String>(6);
        // 主叫号码。
        params.put("channel_id", channelId);

        String url = pbxUrl + PBXConstant.CALL_VOICE_RECORD + pbxToken;
        log.info("startRecordVoice ,url ：" + url + ",params ：" + params);
        HttpRequest postRequest = HttpUtil.createPost(url);
        // 添加头部信息
        postRequest.header("Content-Type", "application/json");
        // 设置请求体
        JSONObject jsonMap = new JSONObject(params);
        String body = jsonMap.toJSONString();
        // 发送请求
        String res = postRequest.body(body).execute().body();
        log.debug("startRecordVoice rsp: " + res);
        JSONObject jsonObject = JSONObject.parseObject(res);
        if(SUCCESS.equals(jsonObject.getString("errcode"))){
            log.info("startRecordVoice success,channelId:{}",channelId);
        }else {
            log.error("startRecordVoice failed");
        }
    }

    private String addMember(WsCallInMessage wsCallInMessage, ElevatorWorkOrder workOrder) {
        // 主叫号码。
        String channelId = "";
        if (pbxActive.equals(PBXConstant.PBX_ACTIVE_DEV)) {
            ExtensionInfo extensionInfo = wsCallInMessage.getMsg().getMembers().get(0).getExtension();
            channelId = extensionInfo.getChannel_id();
        }else if (pbxActive.equals(PBXConstant.PBX_ACTIVE_PROD)) {
            BoundInfo boundInfo = wsCallInMessage.getMsg().getMembers().get(0).getInbound();
            channelId = boundInfo.getChannel_id();
        }else {
            log.error("pbxActive is not DEV or PROD");
            return "";
        }
        String pbxToken = redisCache.getCacheObject(PBXConstant.PBX_TOKEN_KEY);
        Map<String, String> params = new HashMap<String, String>(6);
        // 主叫号码。
        params.put("channel_id", channelId);
        params.put("number", workOrder.getTrappedPersonTel());
        params.put("dial_permission", "1000");

        String url = pbxUrl + PBXConstant.CALL_ADD_MEMBER + pbxToken;
        log.info("addMember ,url ：" + url + ",params ：" + params);
        HttpRequest postRequest = HttpUtil.createPost(url);
        // 添加头部信息
        postRequest.header("Content-Type", "application/json");
        // 设置请求体
        JSONObject jsonMap = new JSONObject(params);
        String body = jsonMap.toJSONString();
        // 发送请求
        String res = postRequest.body(body).execute().body();
        log.debug("addMember rsp: " + res);
        JSONObject jsonObject = JSONObject.parseObject(res);
        if(SUCCESS.equals(jsonObject.getString("errcode"))){
            log.info("addMember success,number:{}",workOrder.getTrappedPersonTel());
            return jsonObject.getString("call_id");
        }else {
            log.error("transferCall failed");
            return "";
        }
    }

    @Override
    public void callInEvent(JSONObject messageJson) {
        WsCallInMessage wsCallInMessage = JSON.toJavaObject(messageJson, WsCallInMessage.class);
        String callId = wsCallInMessage.getMsg().getCall_id();
        String memberStatus = "";
        String fromPhone = "";
        // 通话状态
        if (PBXConstant.PBX_ACTIVE_DEV.equals(pbxActive)) {
            ExtensionInfo extensionInfo = wsCallInMessage.getMsg().getMembers().get(0).getExtension();
            memberStatus = extensionInfo.getMember_status();
            fromPhone = extensionInfo.getNumber();
        }else if (PBXConstant.PBX_ACTIVE_PROD.equals(pbxActive)) {
            BoundInfo boundInfo = wsCallInMessage.getMsg().getMembers().get(0).getInbound();
            memberStatus = boundInfo.getMember_status();
            fromPhone = boundInfo.getFrom();
        }else {
            log.error("pbxActive is null");
            return;
        }
        if (PBXConstant.CALL_STATUS_ANSWER.equals(memberStatus)) {
            // 查询工单记录中是否存在了call_id
            ElevatorWorkOrder dbWorkOrder = elevatorWorkOrderMapper.selectElevatorWorkOrderByCallId(callId);
            if (dbWorkOrder != null) {
                return;
            }
            // 新电话呼入 创建工单
            ElevatorWorkOrder workOrder = new ElevatorWorkOrder();
            workOrder.setTrappedPersonTel(fromPhone);
            workOrder.setStatus(0);
            workOrder.setCreateDate(DateUtils.getNowDate());
            workOrder.setDelFlag("0");
            workOrder.setCreateTime(DateUtils.getNowDate());
            workOrder.setCallId(callId);
            elevatorWorkOrderMapper.insertElevatorWorkOrder(workOrder);
            // 创建工单节点
            ElevatorWorkNode workNode = new ElevatorWorkNode();
            workNode.setCallId(callId);
            workNode.setWorkOrderId(workOrder.getId());
            workNode.setNodeName("发起申请");
            workNode.setNodeTime(DateUtils.getNowDate());
            workNode.setContentName("被困用户" + fromPhone);
            workNode.setType("1");
            workNode.setIsSuccess("1");
            workNode.setCreateTime(DateUtils.getNowDate());
            elevatorWorkNodeMapper.insertElevatorWorkNode(workNode);
        } else if (PBXConstant.CALL_STATUS_BYE.equals(memberStatus)) {
            // 通话结束
            log.info("通话结束: {}",fromPhone);
        }
    }

    @Override
    public void newCallDetails(JSONObject messageJson) {
        WsNewCallDetailsMessage wsCallDetailsMessage = JSON.toJavaObject(messageJson, WsNewCallDetailsMessage.class);
        String callId = wsCallDetailsMessage.getMsg().getCall_id();
        // 根据callId查询工单记录
        ElevatorWorkOrder dbWorkOrder = elevatorWorkOrderMapper.selectElevatorWorkOrderByCallId(callId);
        if (null == dbWorkOrder) {
            return;
        }
        createOrderNode_4(dbWorkOrder,callId);
        // 录音文件
        String recording = wsCallDetailsMessage.getMsg().getRecording();
        if (StringUtils.isEmpty(recording)) {
            return;
        }
        Integer recordFileId = null;
        // 查询录音文件列表
        String pbxToken = redisCache.getCacheObject(PBXConstant.PBX_TOKEN_KEY);
        StringBuffer urlSb = new StringBuffer(pbxUrl);
        urlSb.append(PBXConstant.CALL_VOICE_RECORD_LIST).append(pbxToken);
        urlSb.append("&page=").append(1).append("&page_size=").append(100);
        urlSb.append("&sort_by=time");
        urlSb.append("&order_by=desc");
        String url = urlSb.toString();
        log.info("voice record list ,url ：" + url);
        HttpRequest getRequest = HttpUtil.createGet(url);
        // 添加头部信息
        getRequest.header("Content-Type", "application/json");
        // 发送请求
        String res = getRequest.execute().body();
        log.debug("voice record list rsp: " + res);
        JSONObject jsonObject = JSONObject.parseObject(res);
        if(SUCCESS.equals(jsonObject.getString("errcode"))){
            log.info("voice record list success, total number:{}",jsonObject.getInteger("total_number"));
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            for (int i = 0; i < jsonArray.size(); i++) {
                if (recording.equals(jsonArray.getJSONObject(i).getString("file"))) {
                    recordFileId = jsonArray.getJSONObject(i).getInteger("id");
                    break;
                }
            }
            // 进行录音文件下载
            if (null != recordFileId) {
                downloadRecordFile(recordFileId,recording,dbWorkOrder);
            }
        }else {
            log.error("voice record list failed");
        }

    }

    private void downloadRecordFile(Integer recordFileId,String recording, ElevatorWorkOrder dbWorkOrder) {
        // 查询录音文件Url
        String pbxToken = redisCache.getCacheObject(PBXConstant.PBX_TOKEN_KEY);
        StringBuffer urlSb = new StringBuffer(pbxUrl);
        urlSb.append(PBXConstant.CALL_VOICE_RECORD_DOWNLOAD).append(pbxToken).append("&id=").append(recordFileId)
                .append("&file=").append(recording);
        String url = urlSb.toString();
        log.info("voice record download ,url ：" + url);
        HttpRequest getRequest = HttpUtil.createGet(url);
        // 添加头部信息
        getRequest.header("Content-Type", "application/json");
        // 发送请求
        String res = getRequest.execute().body();
        log.debug("voice record download rsp: " + res);
        JSONObject jsonObject = JSONObject.parseObject(res);
        if(SUCCESS.equals(jsonObject.getString("errcode"))){
            // 获取下载文件路径
            String downloadUrl = jsonObject.getString("download_resource_url");
            downloadUrl = pbxUrl + downloadUrl + "?access_token=" + pbxToken;
            log.info("downloadUrl recording url : " + downloadUrl);
            if (StringUtils.isNotEmpty(downloadUrl)) {
                // 本地文件路径  手动创建路径吧
                String filePath = InspurConfig.getProfile() + "/record/voice/" + recording;
                log.info("filePath recording url : " + filePath);
                // 下载录音文件
                HttpUtil.downloadFile(downloadUrl, new File(filePath));
                // 保存录音文件路径
                dbWorkOrder.setCallRecording(filePath.replace(InspurConfig.getProfile(), "/profile"));
                elevatorWorkOrderMapper.updateElevatorWorkOrder(dbWorkOrder);
            }
        }else {
            log.error("voice record download failed");
        }
    }

    /**
     * 获取手机号归属地
     * @param phoneNum 手机号
     * @return 归属地
     */
    public static String getRegionInfoByPhoneAPI(String phoneNum){
        // 360提供的一个接口 能返回省份和城市
        try {
            String url = "https://cx.shouji.360.cn/phonearea.php?number=" + phoneNum;
            String responseBody = HttpUtil.createGet(url).execute().body();
            JSONObject jsonObject = JSONObject.parseObject(responseBody);
            if (!SUCCESS.equals(jsonObject.getInteger("code").toString())) {
                return "";
            }
            String city = jsonObject.getJSONObject("data").getString("city");
            log.info("getRegionInfoByPhoneAPI success, city:{}",city);
            return city;
        }catch (Exception e){
            log.error("getRegionInfoByPhoneAPI error:{}",e.getMessage());
            return "";
        }

    }

    /**
     * 获取手机号归属地
     * @param phoneNum 手机号
     * @return 归属地
     */
    public static String getRegionInfoByPhone(String phoneNum){
        return isValidNumber(phoneNum) ? GEO_CODER.getDescriptionForNumber(getPhoneNumber(phoneNum), Locale.CHINESE) : "";
    }

    /**
     * 验证当前手机号是否有效
     * @param phone 手机号
     * @return 校验结果
     */
    public static boolean isValidNumber(String phone){
        return PHONE_NUMBER_UTIL.isValidNumber(getPhoneNumber(phone));
    }

    /**
     * 生成PhoneNumber
     * @param phone 手机号
     * @return PhoneNumber
     */
    private static Phonenumber.PhoneNumber getPhoneNumber(String phone){
        Phonenumber.PhoneNumber phoneNumber = new Phonenumber.PhoneNumber();
        // 国际长途电话区号  国内 86
        phoneNumber.setCountryCode(86);
        phoneNumber.setNationalNumber(Long.parseLong(phone));
        return phoneNumber;
    }

    public static void main(String[] args) {

        String phoneNum = "19909918878";
        System.out.println(getRegionInfoByPhoneAPI(phoneNum));

    }
}
