package com.yuchen.saas.park.service.service.pldoor.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.thinkunion.sdk.iot.bean.api.CallingDeviceServiceResponse;
import com.yuchen.saas.device.api.feign.IotFeignService;
import com.yuchen.saas.park.api.dto.pldoor.CallDeviceServiceDto;
import com.yuchen.saas.park.api.dto.pldoor.PlDoorAddFaceDTO;
import com.yuchen.saas.park.api.dto.pldoor.PlDoorFaceDeleteDTO;
import com.yuchen.saas.park.api.dto.pldoor.PlDoorUserPointSetDTO;
import com.yuchen.saas.park.api.entity.park.PmgBatParkInfo;
import com.yuchen.saas.park.api.entity.pldoor.PlDoorPoint;
import com.yuchen.saas.park.api.entity.pldoor.PlDoorPointGroup;
import com.yuchen.saas.park.api.entity.pldoor.PlDoorUserPointSet;
import com.yuchen.saas.park.api.entity.pldoor.PlDoorUserPointSetItem;
import com.yuchen.saas.park.api.entity.property.PropertyBuildingUnit;
import com.yuchen.saas.park.api.entity.property.PropertyBuildings;
import com.yuchen.saas.park.api.entity.property.PropertyBuildingsLevel;
import com.yuchen.saas.park.api.entity.property.PropertyHouses;
import com.yuchen.saas.park.api.vo.pldoor.PlDoorUserPointSetVO;
import com.yuchen.saas.park.api.vo.pldoor.PlResultVO;
import com.yuchen.saas.park.api.vo.request.PlDoorUserPointSetReq;
import com.yuchen.saas.park.service.iot.IoTRemoteService;
import com.yuchen.saas.park.service.mapper.pldoor.PlDoorUserPointSetMapper;
import com.yuchen.saas.park.service.service.PmgBatParkInfoService;
import com.yuchen.saas.park.service.service.pldoor.PlDoorPointGroupService;
import com.yuchen.saas.park.service.service.pldoor.PlDoorPointService;
import com.yuchen.saas.park.service.service.pldoor.PlDoorUserPointSetItemService;
import com.yuchen.saas.park.service.service.pldoor.PlDoorUserPointSetService;
import com.yuchen.saas.park.service.service.property.PropertyBuildingUnitService;
import com.yuchen.saas.park.service.service.property.PropertyBuildingsLevelService;
import com.yuchen.saas.park.service.service.property.PropertyBuildingsService;
import com.yuchen.saas.park.service.service.property.PropertyHousesService;
import com.yuchen.saas.park.service.util.EncryptUntil;
import com.yuchen.saas.park.service.util.PicToBase64Utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
import org.nest.springwrap.core.mp.base.BaseServiceImpl;
import org.nest.springwrap.core.tool.utils.BeanUtil;
import org.nest.springwrap.core.tool.utils.Func;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 人员登记配置 服务实现类
 * </p>
 *
 * @author miaoqs
 * @since 2024-04-08
 */
@Slf4j
@Service
public class PlDoorUserPointSetServiceImpl extends BaseServiceImpl<PlDoorUserPointSetMapper, PlDoorUserPointSet> implements PlDoorUserPointSetService {

    @Resource
    private PlDoorPointService plDoorPointService;
    @Resource
    private PlDoorUserPointSetItemService plDoorUserPointSetItemService;
    @Resource
    private PlDoorUserPointSetMapper plDoorUserPointSetMapper;
    @Resource
    private IoTRemoteService ioTRemoteService;
    @Resource
    private IotFeignService iotFeignService;
    @Resource
    private PmgBatParkInfoService pmgBatParkInfoService;
    @Resource
    private PropertyBuildingsService propertyBuildingsService;
    @Resource
    private PropertyBuildingUnitService propertyBuildingUnitService;
    @Resource
    private PropertyBuildingsLevelService propertyBuildingsLevelService;
    @Resource
    private PropertyHousesService propertyHousesService;
    @Resource
    private PlDoorPointGroupService plDoorPointGroupService;

    //添加人脸
    private final String ADDFACE = "addFace";
    //删除人脸
    private final String FACEDELETE = "faceDelete";
    //检测人脸
    private final String CHECKFACE = "checkFace";
    //开门
    private final String DOOROPERATION = "doorOperation";
    //发送二维码
    private final String SENTQRCODETODOOR = "sentQrCodeToDoor";
    //删除二维码
    private final String DELQRCODE = "delQrCode";
    //文本转语音
    private final String TEXTTOVOICE = "textToVoice";
    private final String STARTTIME = "2000-01-01 00:00:00";
    private final String ENDTIME = "3000-01-01 00:00:00";

    //麦驰智能门禁品牌型号
    private final String BRANDMODEL_MAICI = "麦驰/v1.1";
    //麦驰智能门禁品牌型号
    private final String BRANDMODEL_TIEJUN = "铁军/v1.1";



    @Override
    public boolean saveOrUpdateByParam(PlDoorUserPointSetDTO plDoorUserPointSetDTO) {
        PlDoorUserPointSet plDoorUserPointSet = new PlDoorUserPointSet();
        BeanUtil.copyProperties(plDoorUserPointSetDTO,plDoorUserPointSet);
        Long id = plDoorUserPointSet.getId();
        if(Func.isNotEmpty(plDoorUserPointSetDTO.getUserId()) && Func.isEmpty(id)){
            List<PlDoorUserPointSet> list = list(new LambdaQueryWrapper<PlDoorUserPointSet>().eq(PlDoorUserPointSet::getUserId, plDoorUserPointSetDTO.getUserId()));
            if(Func.isNotEmpty(list) && list.size()>0){
                throw new RuntimeException("该人员已存在,不能重复新增");
            }
        }
        //移除原有人脸权限和二维码权限
        if(Func.isNotEmpty(id)){
            removeFaceByPointSetId(id);
        }

        saveOrUpdate(plDoorUserPointSet);
        //移除原有子项
        if(Func.isNotEmpty(plDoorUserPointSet.getId())){
            plDoorUserPointSetItemService.remove(new LambdaQueryWrapper<PlDoorUserPointSetItem>()
                    .eq(PlDoorUserPointSetItem::getUserPointSetId, plDoorUserPointSet.getId()));
        }
        //新增子项
        if(Func.isNotEmpty(plDoorUserPointSetDTO.getPlDoorUserPointSetItemList())){
            List<PlDoorUserPointSetItem> plDoorUserPointSetItemList = plDoorUserPointSetDTO.getPlDoorUserPointSetItemList();
            for (PlDoorUserPointSetItem item : plDoorUserPointSetItemList) {
                item.setUserPointSetId(plDoorUserPointSet.getId());
                PlDoorPoint point = plDoorPointService.getById(item.getDoorPointId());
                item.setDeviceName(point.getDeviceNo());
            }
            plDoorUserPointSetItemService.saveBatch(plDoorUserPointSetItemList);
        }
        return true;


    }

    public IPage<PlDoorUserPointSetVO> pageByparam(Page<PlDoorUserPointSetReq> page, @Param("req") PlDoorUserPointSetReq req) {
        Page<PlDoorUserPointSetVO> pointSetVOPage = plDoorUserPointSetMapper.listByParam(page, req);
        if(Func.isNotEmpty(pointSetVOPage) && Func.isNotEmpty(pointSetVOPage.getRecords())){
            pointSetVOPage.getRecords().forEach(record -> {
                if(Func.isNotEmpty(record.getId())){
                    List<PlDoorUserPointSetItem> itemList = plDoorUserPointSetItemService.list(new LambdaQueryWrapper<PlDoorUserPointSetItem>().eq(PlDoorUserPointSetItem::getUserPointSetId, record.getId()));
                    if(Func.isNotEmpty(itemList)){
                        for (PlDoorUserPointSetItem pointSetItem : itemList) {
                            pointSetItem.setDoorPointNameStr(plDoorPointService.getById(pointSetItem.getDoorPointId()).getDoorName());
                            pointSetItem.setDoorGroupNameStr(plDoorPointGroupService.getById(pointSetItem.getDoorGroupId()).getPointGroupName());
                        }
                    }
                    record.setPlDoorUserPointSetItemList(itemList);
                    //下发失败个数
                    int failNum = 0;
                    for (PlDoorUserPointSetItem setItem : itemList) {
                        if (Func.isNotEmpty(setItem.getFaceSendState()) && setItem.getFaceSendState().equals("2")){
                            failNum ++;
                        }
                    }
                    record.setFailNum(failNum);
                    List<Long> pointIds = itemList.stream().map(PlDoorUserPointSetItem::getDoorPointId).collect(Collectors.toList());
                    if(Func.isNotEmpty(pointIds)) {
                        List<PlDoorPoint> list = plDoorPointService.list(new LambdaQueryWrapper<PlDoorPoint>().in(PlDoorPoint::getId, pointIds));
                        if(Func.isNotEmpty(list)){
                            record.setDoorName(list.stream().map(PlDoorPoint::getDoorName).reduce((a, b) -> a + "," + b).get());
                        }
                    }
                    //空间名称
                    PmgBatParkInfo parkInfo = pmgBatParkInfoService.getById(record.getParkId());
                    record.setParkName(null == parkInfo?"":parkInfo.getParkName());
                    PropertyBuildings buildings = propertyBuildingsService.getById(record.getBuildingId());
                    record.setBuildingName(null == buildings?"":buildings.getBuildingName());
                    PropertyBuildingUnit unit = propertyBuildingUnitService.getById(record.getElementId());
                    record.setElementName(null == unit?"":unit.getUnitName());
                    PropertyBuildingsLevel level = propertyBuildingsLevelService.getById(record.getFloorId());
                    record.setFloorName(null == level ? null : level.getLevelName());
                    PropertyHouses houses = propertyHousesService.getById(record.getRoomNumberId());
                    record.setRoomNumberName(null == houses?"":houses.getHouseName());
                }
            });
        }
        return pointSetVOPage;
    }


    @Override
    public PlDoorUserPointSetVO getDetailById(Long id) {
        PlDoorUserPointSetVO plDoorUserPointSetVO = new PlDoorUserPointSetVO();
        if(Func.isNotEmpty(id)){
            PlDoorUserPointSet plDoorUserPointSet = getById(id);
            BeanUtil.copyProperties(plDoorUserPointSet,plDoorUserPointSetVO);
            List<PlDoorUserPointSetItem> list = plDoorUserPointSetItemService.list(new LambdaQueryWrapper<PlDoorUserPointSetItem>()
                   .eq(PlDoorUserPointSetItem::getUserPointSetId, plDoorUserPointSet.getId()));
            list.forEach(item -> {
                PlDoorPoint doorPoint = plDoorPointService.getById(item.getDoorPointId());
                item.setDoorPointNameStr(null == doorPoint?"":doorPoint.getDoorName());
            });
            plDoorUserPointSetVO.setPlDoorUserPointSetItemList(list);
        }
        return plDoorUserPointSetVO;
    }

    /**
     * 移除人员登记
     * @param id
     * @return
     */
    @Override
    public boolean removePointSetById(Long id) {
        if(Func.isNotEmpty(id)){
            PlDoorUserPointSet plDoorUserPointSet = getById(id);
            if(Func.isNotEmpty(plDoorUserPointSet)){
                //移除门禁设备人员权限
                PlDoorUserPointSet pointSet = getById(id);
                if(Func.isNotEmpty(pointSet)){
                    List<PlDoorUserPointSetItem> itemList = plDoorUserPointSetItemService.list(new LambdaQueryWrapper<PlDoorUserPointSetItem>()
                            .eq(PlDoorUserPointSetItem::getUserPointSetId, pointSet.getId()));
                    if(Func.isNotEmpty(itemList)){
                        List<Long> pointIds = itemList.stream().map(PlDoorUserPointSetItem::getDoorPointId).collect(Collectors.toList());
                        if(Func.isNotEmpty(pointIds)) {
                            List<PlDoorPoint> pointList = plDoorPointService.list(new LambdaQueryWrapper<PlDoorPoint>().in(PlDoorPoint::getId, pointIds));
                            if(Func.isNotEmpty(pointList)){
                                //多设备
                                pointList.forEach(item -> {
                                    //人员权限下发，调用iot接口注册人脸
                                    CallDeviceServiceDto callDeviceServiceDto = new CallDeviceServiceDto();
                                    callDeviceServiceDto.setIdentify(FACEDELETE);
                                    callDeviceServiceDto.setProductKey(item.getProductKey());
                                    callDeviceServiceDto.setDeviceName(item.getDeviceNo());
                                    PlDoorFaceDeleteDTO faceDeleteDTO = new PlDoorFaceDeleteDTO();
                                    //组装参数
                                    List<PlDoorFaceDeleteDTO.Face> listFace = new ArrayList<>();
                                    if(Func.isNotEmpty(item.getTerminalNumber())){
                                        PlDoorFaceDeleteDTO.Face face = new PlDoorFaceDeleteDTO.Face();
                                        //人员登记唯一标识
                                        face.setUserId(pointSet.getUserId().toString());
                                        listFace.add(face);
                                    }
                                    //移除人脸
                                    faceDeleteDTO.setListFace(listFace);
                                    boolean resulta = faceDelete(callDeviceServiceDto, pointSet, faceDeleteDTO);
                                    if(!resulta){
                                        throw new RuntimeException("移除门禁设备人脸失败");
                                    }
                                    //移除二维码
                                    boolean resultb = delQrCode(pointSet, item);
                                    if(!resultb){
                                        throw new RuntimeException("移除门禁设备二维码失败");
                                    }
                                });
                            }
                        }
                    }
                }

                //逻辑删除
                removeById(id);
                plDoorUserPointSetItemService.remove(new LambdaQueryWrapper<PlDoorUserPointSetItem>()
                        .eq(PlDoorUserPointSetItem::getUserPointSetId, plDoorUserPointSet.getId()));
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean removeFaceByPointSetId(Long id) {
        if(Func.isNotEmpty(id)){
            PlDoorUserPointSet plDoorUserPointSet = getById(id);
            if(Func.isNotEmpty(plDoorUserPointSet)){
                //移除门禁设备人员权限
                PlDoorUserPointSet pointSet = getById(id);
                if(Func.isNotEmpty(pointSet)){
                    List<PlDoorUserPointSetItem> itemList = plDoorUserPointSetItemService.list(new LambdaQueryWrapper<PlDoorUserPointSetItem>()
                            .eq(PlDoorUserPointSetItem::getUserPointSetId, pointSet.getId()));
                    if(Func.isNotEmpty(itemList)){
                        List<Long> pointIds = itemList.stream().map(PlDoorUserPointSetItem::getDoorPointId).collect(Collectors.toList());
                        if(Func.isNotEmpty(pointIds)) {
                            List<PlDoorPoint> pointList = plDoorPointService.list(new LambdaQueryWrapper<PlDoorPoint>().in(PlDoorPoint::getId, pointIds));
                            if(Func.isNotEmpty(pointList)){
                                //多设备
                                pointList.forEach(item -> {
                                    //人员权限下发，调用iot接口注册人脸
                                    CallDeviceServiceDto callDeviceServiceDto = new CallDeviceServiceDto();
                                    callDeviceServiceDto.setIdentify(FACEDELETE);
                                    callDeviceServiceDto.setProductKey(item.getProductKey());
                                    callDeviceServiceDto.setDeviceName(item.getDeviceNo());
                                    PlDoorFaceDeleteDTO faceDeleteDTO = new PlDoorFaceDeleteDTO();
                                    //组装参数
                                    List<PlDoorFaceDeleteDTO.Face> listFace = new ArrayList<>();
                                    if(Func.isNotEmpty(item.getTerminalNumber())){
                                        PlDoorFaceDeleteDTO.Face face = new PlDoorFaceDeleteDTO.Face();
                                        //人员登记唯一标识
                                        face.setUserId(pointSet.getUserId().toString());
                                        listFace.add(face);
                                    }
                                    //移除人脸
                                    faceDeleteDTO.setListFace(listFace);
                                    boolean resulta = faceDelete(callDeviceServiceDto, pointSet, faceDeleteDTO);
                                    if(!resulta){
                                        throw new RuntimeException("移除门禁设备人脸失败");
                                    }
                                    //移除二维码
                                    boolean resultb = delQrCode(pointSet, item);
                                    if(!resultb){
                                        throw new RuntimeException("移除门禁设备二维码失败");
                                    }
                                });
                            }
                        }
                    }
                }
            }
        }
        return false;
    }

    /**
     * 分页 综合权限查询
     * @param page
     * @param req
     * @return
     */
    @Override
    public IPage<PlDoorUserPointSetVO> pageByPower(Page<PlDoorUserPointSetReq> page, PlDoorUserPointSetReq req) {
        Page<PlDoorUserPointSetVO> pointSetVOPage = plDoorUserPointSetMapper.pageByPower(page, req);
        if(Func.isNotEmpty(pointSetVOPage) && Func.isNotEmpty(pointSetVOPage.getRecords())){
            pointSetVOPage.getRecords().forEach(record -> {
                if(Func.isNotEmpty(record.getId())){
                    String pointGroupName = "";
                    String doorPointName = "";
                    List<PlDoorUserPointSetItem> itemList = plDoorUserPointSetItemService.list(new LambdaQueryWrapper<PlDoorUserPointSetItem>()
                            .eq(PlDoorUserPointSetItem::getUserPointSetId, record.getId()));
                    if(Func.isNotEmpty(itemList)){
                        for (PlDoorUserPointSetItem setItem : itemList) {
                            PlDoorPoint point = plDoorPointService.getById(setItem.getDoorPointId());
                            setItem.setDoorPointNameStr(point==null?"":point.getDoorName());

                            doorPointName += point==null?"":point.getDoorName() + ";";
                            PlDoorPointGroup pointGroup = point == null?null:plDoorPointGroupService.getById(point.getDoorGroupId());
                            pointGroupName += pointGroup==null?"":pointGroup.getPointGroupName() + ";";
                        }
                    }
                    record.setPlDoorUserPointSetItemList(itemList);
                    record.setDoorName(doorPointName);
                    record.setPointGroupName(pointGroupName);
                    /* if(Func.isNotEmpty(record.getDoorPointId())) {
                        PlDoorPoint one = plDoorPointService.getOne(new LambdaQueryWrapper<PlDoorPoint>().eq(PlDoorPoint::getId, record.getDoorPointId()));
                        record.setDoorName(null == one?"":one.getDoorName());
                    } */
                }

                //空间名称
                PmgBatParkInfo parkInfo = pmgBatParkInfoService.getById(record.getParkId());
                record.setParkName(null == parkInfo?"":parkInfo.getParkName());
                PropertyBuildings buildings = propertyBuildingsService.getById(record.getBuildingId());
                record.setBuildingName(null == buildings?"":buildings.getBuildingName());
                PropertyBuildingUnit unit = propertyBuildingUnitService.getById(record.getElementId());
                record.setElementName(null == unit?"":unit.getUnitNum());
                PropertyBuildingsLevel level = propertyBuildingsLevelService.getById(record.getFloorId());
                record.setFloorName(null == level ? null : level.getLevelName());
                PropertyHouses houses = propertyHousesService.getById(record.getRoomNumberId());
                record.setRoomNumberName(null == houses?"":houses.getHouseName());
            });
        }
        return pointSetVOPage;
    }


    @Override
    public boolean sendUserPower(Long id) {
        PlResultVO plResultVO = new PlResultVO();
        plResultVO.setResulta(true);
        PlDoorUserPointSet pointSet = getById(id);
        if(Func.isNotEmpty(pointSet)){
            List<PlDoorUserPointSetItem> itemList = plDoorUserPointSetItemService.list(new LambdaQueryWrapper<PlDoorUserPointSetItem>()
                    .eq(PlDoorUserPointSetItem::getUserPointSetId, pointSet.getId()));
            if(Func.isNotEmpty(itemList)){
                List<Long> pointIds = itemList.stream().map(PlDoorUserPointSetItem::getDoorPointId).collect(Collectors.toList());
                Map<Long, Long> itemIdMap = itemList.stream().collect(Collectors.toMap(PlDoorUserPointSetItem::getDoorPointId, PlDoorUserPointSetItem::getId));
                if(Func.isNotEmpty(pointIds)) {
                    List<PlDoorPoint> pointList = plDoorPointService.list(new LambdaQueryWrapper<PlDoorPoint>().in(PlDoorPoint::getId, pointIds));
                    if(Func.isNotEmpty(pointList)){
                        //多设备
                        pointList.forEach(item -> {
                            Long setItemId = itemIdMap.get(item.getId());
                            //组装参数
                            List<PlDoorAddFaceDTO.Face> listFace = new ArrayList<>();
                            //人员权限下发，调用iot接口注册人脸
                            CallDeviceServiceDto callDeviceServiceDto = new CallDeviceServiceDto();
                            callDeviceServiceDto.setIdentify(ADDFACE);
                            PlDoorAddFaceDTO addFace = new PlDoorAddFaceDTO();
                            if(Func.isNotEmpty(item.getTerminalNumber())){
                                //String terminalNumber = item.getTerminalNumber();
                                //if(Func.isNotEmpty(terminalNumber)){
                                    PlDoorAddFaceDTO.Face face = new PlDoorAddFaceDTO.Face();
                                    //人员登记唯一标识
                                    face.setUserId(pointSet.getUserId().toString());
                                    face.setUserName(pointSet.getUserName());
                                    if(Func.isNotEmpty(pointSet.getUserFaceUrl())) {
                                        face.setFaceUrl(pointSet.getUserFaceUrl());
                                        try {
                                            URL url = new URL(pointSet.getUserFaceUrl());
                                            // 压缩图片50k
                                            //String base64Encoded = ImageUrlToBase64Util.imageUrlToBase64(url.toString());
                                            String base64Encoded = PicToBase64Utils.imgChangeStrLimitSize50L(pointSet.getUserFaceUrl());
                                            face.setFaceImgBase64(base64Encoded);
                                        } catch (MalformedURLException e) {
                                            throw new RuntimeException(e);
                                        } catch (IOException e) {
                                            throw new RuntimeException(e);
                                        }
                                    }
                                    //face.setTerminalNumber(terminalNumber);
                                    //face.setRole(1);
                                    //face.setCardNo(1);
                                    //face.setPlanId(1);
                                    if(Func.isNotEmpty(pointSet.getValidStartTime())){
                                        face.setStartTime(DateUtil.format(pointSet.getValidStartTime(), "yyyy-MM-dd HH:mm:ss"));
                                    }else{
                                        face.setStartTime(STARTTIME);
                                    }
                                    if(Func.isNotEmpty(pointSet.getValidEndTime())){
                                        face.setEndTime(DateUtil.format(pointSet.getValidEndTime(), "yyyy-MM-dd HH:mm:ss"));
                                    }else{
                                        face.setEndTime(ENDTIME);
                                    }
                                    listFace.add(face);
                                //}
                            }
                            callDeviceServiceDto.setProductKey(item.getProductKey());
                            callDeviceServiceDto.setDeviceName(item.getDeviceNo());

                            //下发人脸
                            addFace.setListFace(listFace);
                            if(Func.isNotEmpty(pointSet.getUserFaceUrl())){
                                log.info("====== 人脸图片存在支持下发");
                                boolean resulta = sendFace(callDeviceServiceDto, pointSet, addFace, setItemId);
                                if(!resulta){
                                    throw new RuntimeException("下发人脸失败");
                                }
                            }else{
                                log.info("====== 下发人脸图片为空，不支持下发");
                                PlDoorUserPointSetItem setItem = plDoorUserPointSetItemService.getById(setItemId);
                                setItem.setIzFaceSupportSend("2");
                                plDoorUserPointSetItemService.updateById(setItem);
                            }

                            //下发二维码
                            if(Func.isNotEmpty(item.getBrandModel()) && item.getBrandModel().equals(BRANDMODEL_MAICI)){
                                log.info("====== 下发麦驰二维码");
                                boolean resultb = sendQRCode(pointSet, item,setItemId);
                                if(!resultb){
                                    throw new RuntimeException("下发二维码失败");
                                }
                            }
                        });
                    }
                }
            }

        }
        return true;
    }

    /**
     * 下发人脸
     * @param callDeviceServiceDto
     * @param pointSet
     * @param addFace
     * @return
     */
    private boolean sendFace(CallDeviceServiceDto callDeviceServiceDto, PlDoorUserPointSet pointSet, PlDoorAddFaceDTO addFace, Long setItemId) {
        String addFaceJson = JSONObject.toJSONString(addFace);
        Map params = JSONObject.parseObject(addFaceJson, Map.class);
        callDeviceServiceDto.setParams(params);
        String json = JSONObject.toJSONString(callDeviceServiceDto);
        Map map = JSONObject.parseObject(json, Map.class);
        //调用接口
        log.info("====== 调用iot下发人脸参数：{}",json);
        CallingDeviceServiceResponse response = ioTRemoteService.callServiceReturn(map);
        if(Func.isNotEmpty(response)){
            String resultJson = JSONObject.toJSONString(response);
            log.info("====== 调用iot下发人脸返回：{}",resultJson);
            String code = "";
            String msg = "";
            JSONObject jsonObject = JSONObject.parseObject(resultJson);
            if(Func.isNotEmpty(jsonObject)){
                JSONObject data1 = jsonObject.getJSONObject("Data");
                if(Func.isNotEmpty(data1) ){
                    JSONObject data2 = data1.getJSONObject("Data");
                    if(Func.isNotEmpty(data2)){
                        code = data2.get("Code").toString();
                        msg = data2.get("Msg").toString();
                        log.info("====== 调用iot下发人脸返回code：{}",code);
                    }
                }
            }

            PlDoorUserPointSetItem setItem = plDoorUserPointSetItemService.getById(setItemId);
            setItem.setIzFaceSupportSend("1");
            if(Func.isNotEmpty(code)){
                if(code.equals("0")){
                    log.info("====== 调用iot下发人脸成功");
                    pointSet.setSendState("1");
                    if(Func.isNotEmpty(setItem)){
                        setItem.setFaceSendState("1");
                        setItem.setFaceErrorMsg(msg);
                    }
                }else{
                    log.info("====== 调用iot下发人脸失败：{}",msg);
                    pointSet.setSendState("2");
                    pointSet.setSendFailMsg(msg);
                    if(Func.isNotEmpty(setItem)){
                        setItem.setFaceSendState("2");
                        setItem.setFaceErrorMsg(msg);
                    }
                }
            }
            plDoorUserPointSetItemService.updateById(setItem);
            this.updateById(pointSet);
            return true;
        }
        return false;
    }

    private boolean faceDelete(CallDeviceServiceDto callDeviceServiceDto, PlDoorUserPointSet pointSet, PlDoorFaceDeleteDTO faceDelete) {
        String addFaceJson = JSONObject.toJSONString(faceDelete);
        Map params = JSONObject.parseObject(addFaceJson, Map.class);
        callDeviceServiceDto.setParams(params);
        String json = JSONObject.toJSONString(callDeviceServiceDto);
        Map map = JSONObject.parseObject(json, Map.class);
        //调用接口
        log.info("====== 调用iot删除人脸参数：{}",json);
        CallingDeviceServiceResponse response = ioTRemoteService.callServiceReturn(map);
        if(Func.isNotEmpty(response)){
            boolean result = false;
            String resultJson = JSONObject.toJSONString(response);
            log.info("====== 调用iot删除人脸返回：{}",resultJson);
            if(response.getCode().equals("200")){
                pointSet.setDeleteFailMsg(response.getMessage());
                result = true;
            }else{
                log.info("删除人脸失败,返回信息：{}",response.getMessage());
                pointSet.setDeleteFailMsg(response.getMessage());
                this.updateById(pointSet);
            }
            return result;
        }
        return false;
    }

    private boolean sendQRCode(PlDoorUserPointSet pointSet, PlDoorPoint point, Long setItemId){
        CallDeviceServiceDto callDeviceServiceDto = new CallDeviceServiceDto();
        callDeviceServiceDto.setIdentify(SENTQRCODETODOOR);
        callDeviceServiceDto.setProductKey(point.getProductKey());
        callDeviceServiceDto.setDeviceName(point.getDeviceNo());
        Map<String, Object> in = new HashMap<>();
        in.put("userName", pointSet.getUserName());
        //人员登记唯一标识
        in.put("userId", pointSet.getId());
        try {
            in.put("qrCode", cn.hutool.core.codec.Base64.encode(EncryptUntil.encrypt((pointSet.getId().toString()).getBytes("utf-8"))));
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        in.put("startTime", DateUtil.format(pointSet.getValidStartTime(), "yyyy-MM-dd HH:mm:ss"));
        in.put("endTime", DateUtil.format(pointSet.getValidEndTime(), "yyyy-MM-dd HH:mm:ss"));
        in.put("terminalNumber", point.getTerminalNumber());
        callDeviceServiceDto.setParams(in);
        String json = JSONObject.toJSONString(callDeviceServiceDto);
        Map map = JSONObject.parseObject(json, Map.class);

        //调用接口
        PlDoorUserPointSetItem setItem = plDoorUserPointSetItemService.getById(setItemId);
        setItem.setIzQrcodeSupportSend("1");
        log.info("====== 下发麦驰二维码参数：{}",json);
        CallingDeviceServiceResponse response = ioTRemoteService.callServiceReturn(map);
        if(Func.isNotEmpty(response)){
            String resultJson = JSONObject.toJSONString(response);
            log.info("====== 下发麦驰二维码返回数据：{}",resultJson);
            String code = "";
            String msg = "";
            JSONObject jsonObject = JSONObject.parseObject(resultJson);
            if(Func.isNotEmpty(jsonObject)){
                JSONObject data1 = jsonObject.getJSONObject("Data");
                if(Func.isNotEmpty(data1) ){
                    JSONObject data2 = data1.getJSONObject("Data");
                    if(Func.isNotEmpty(data2)){
                        code = data2.get("Code").toString();
                        msg = data2.get("Msg").toString();
                        log.info("====== 调用iot下发麦驰二维码返回code：{}",code);
                    }
                    if(Func.isNotEmpty(code)){
                        if(code.equals("0")){
                            log.info("====== 调用iot下发麦驰二维码成功");
                            pointSet.setSendState("1");
                            if(Func.isNotEmpty(setItem)){
                                setItem.setQrcodeSendState("1");
                                setItem.setQrcodeErrorMsg(msg);
                            }
                        }else{
                            log.info("====== 调用iot下发麦驰二维码失败：{}",msg);
                            pointSet.setSendState("2");
                            pointSet.setSendFailMsg(msg);
                            if(Func.isNotEmpty(setItem)){
                                setItem.setQrcodeSendState("2");
                                setItem.setQrcodeErrorMsg(msg);
                            }
                        }
                        plDoorUserPointSetItemService.updateById(setItem);
                    }
                }
            }
            return true;
        }
        return false;
    }

    private boolean delQrCode(PlDoorUserPointSet pointSet, PlDoorPoint point){
        CallDeviceServiceDto callDeviceServiceDto = new CallDeviceServiceDto();
        callDeviceServiceDto.setIdentify(DELQRCODE);
        callDeviceServiceDto.setProductKey(point.getProductKey());
        callDeviceServiceDto.setDeviceName(point.getDeviceNo());
        Map<String, Object> in = new HashMap<>();
        try {
            in.put("qrCode", cn.hutool.core.codec.Base64.encode(EncryptUntil.encrypt((pointSet.getId().toString()).getBytes("utf-8"))));
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        in.put("terminalNumber", point.getTerminalNumber());
        callDeviceServiceDto.setParams(in);
        String json = JSONObject.toJSONString(callDeviceServiceDto);
        Map map = JSONObject.parseObject(json, Map.class);

        //调用接口
        log.info("====== 删除麦驰二维码参数：{}",json);
        CallingDeviceServiceResponse response = ioTRemoteService.callServiceReturn(map);
        if(Func.isNotEmpty(response)){
            boolean result = false;
            String resultJson = JSONObject.toJSONString(response);
            log.info("====== 删除麦驰二维码返回数据：{}",resultJson);
            if(response.getCode().equals("200")){
                result = true;
            }
            return result;
        }
        return false;
    }

    @Override
    public boolean chenkFace(Long pointId, String faceUrl) {
        PlDoorPoint point = plDoorPointService.getById(pointId);
        CallDeviceServiceDto callDeviceServiceDto = new CallDeviceServiceDto();
        callDeviceServiceDto.setIdentify(CHECKFACE);
        callDeviceServiceDto.setProductKey(point.getProductKey());
        callDeviceServiceDto.setDeviceName(point.getDeviceNo());
        Map<String, Object> in = new HashMap<>();
        in.put("faceUrl", faceUrl);
        callDeviceServiceDto.setParams(in);
        String json = JSONObject.toJSONString(callDeviceServiceDto);
        Map map = JSONObject.parseObject(json, Map.class);

        //调用接口
        log.info("====== 调用iot检测人脸图片是否合格参数：{}",json);
        CallingDeviceServiceResponse response = ioTRemoteService.callServiceReturn(map);
        if(Func.isNotEmpty(response)){
            boolean result = false;
            String resultJson = JSONObject.toJSONString(response);
            log.info("====== 调用iot检测人脸图片返回数据：{}",resultJson);
            if(response.getCode().equals("200")){
                result = true;
            }
            return result;
        }
        return false;
    }

    @Override
    public boolean doorOperation(Long userId, Long pointId) {
        if(Func.isNotEmpty(userId) && Func.isNotEmpty(pointId)){
            PlDoorPoint point = plDoorPointService.getById(pointId);
            if(Func.isEmpty(point)){
                return false;
            }
            //NetDeviceWalk netDeviceWalk = iotFeignService.getByDeviceName(point.getDeviceNo()).getData();
            CallDeviceServiceDto callDeviceServiceDto = new CallDeviceServiceDto();
            callDeviceServiceDto.setIdentify(DOOROPERATION);
            callDeviceServiceDto.setProductKey(point.getProductKey());
            callDeviceServiceDto.setDeviceName(point.getDeviceNo());
            Map<String, Object> in = new HashMap<>();
            in.put("userId", userId);
            in.put("terminalNumber", point.getTerminalNumber());
            callDeviceServiceDto.setParams(in);
            String json = JSONObject.toJSONString(callDeviceServiceDto);
            Map map = JSONObject.parseObject(json, Map.class);

            //调用接口
            log.info("====== 调用iot远程开门参数：{}",json);
            CallingDeviceServiceResponse response = ioTRemoteService.callServiceReturn(map);
           if(Func.isNotEmpty(response)){
                boolean result = false;
                String resultJson = JSONObject.toJSONString(response);
                log.info("====== 调用iot远程开门参数返回数据：{}",resultJson);
                if(response.getCode().equals("200")){
                    result = true;
                }
                return result;
            }
            return false;
        }
        return false;
    }

    @Override
    public boolean openDoorForMcRobot(String robotSn, Long parkId, Long pointId) {
        if(Func.isNotEmpty(robotSn) && Func.isNotEmpty(parkId) && Func.isNotEmpty(pointId)){
            PlDoorPoint point = plDoorPointService.getOne(new LambdaQueryWrapper<PlDoorPoint>()
                    .eq(PlDoorPoint::getDoorId, pointId)
                    .eq(PlDoorPoint::getParkId, parkId));
            if(Func.isEmpty(point)){
                log.info("====== 麦驰调用iot远程开门，门禁点不存在");
                return false;
            }
            CallDeviceServiceDto callDeviceServiceDto = new CallDeviceServiceDto();
            callDeviceServiceDto.setIdentify(DOOROPERATION);
            callDeviceServiceDto.setProductKey(point.getProductKey());
            callDeviceServiceDto.setDeviceName(point.getDeviceNo());
            Map<String, Object> in = new HashMap<>();
            in.put("userId", robotSn);
            callDeviceServiceDto.setParams(in);
            String json = JSONObject.toJSONString(callDeviceServiceDto);
            Map map = JSONObject.parseObject(json, Map.class);

            //调用接口
            log.info("====== 麦驰调用iot远程开门参数：{}",json);
            CallingDeviceServiceResponse response = ioTRemoteService.callServiceReturn(map);
            if(Func.isNotEmpty(response)){
                boolean result = false;
                String resultJson = JSONObject.toJSONString(response);
                log.info("====== 麦驰调用iot远程开门参数：{}",resultJson);
                if(response.getCode().equals("200")){
                    result = true;
                }
                return result;
            }
            return false;
        }
        return false;
    }

    @Override
    public List<PlDoorPoint> getUserPointList(Long userId) {
        if(Func.isNotEmpty(userId)) {
            PlDoorUserPointSet pointSet = this.getOne(new LambdaQueryWrapper<PlDoorUserPointSet>().eq(PlDoorUserPointSet::getUserId, userId).last("limit 1"));
            if (Func.isNotEmpty(pointSet) && Func.isNotEmpty(pointSet.getId())) {
                List<PlDoorUserPointSetItem> itemList = plDoorUserPointSetItemService.list(new LambdaQueryWrapper<PlDoorUserPointSetItem>().eq(PlDoorUserPointSetItem::getUserPointSetId, pointSet.getId()));
                if (Func.isNotEmpty(itemList)) {
                    List<Long> pointIdList = itemList.stream().map(PlDoorUserPointSetItem::getDoorPointId).collect(Collectors.toList());
                    return plDoorPointService.list(new LambdaQueryWrapper<PlDoorPoint>().in(PlDoorPoint::getId, pointIdList));
                }
            }
        }
        return null;
    }

    @Override
    public String getUserQrcode(Long userId) throws UnsupportedEncodingException {
        if(Func.isNotEmpty(userId)){
            PlDoorUserPointSet pointSet = this.getOne(new LambdaQueryWrapper<PlDoorUserPointSet>()
                    .eq(PlDoorUserPointSet::getUserId, userId).last("limit 1"));
            if(Func.isNotEmpty(pointSet.getId())){
                return cn.hutool.core.codec.Base64.encode(EncryptUntil.encrypt((pointSet.getId().toString()).getBytes("utf-8")));
            }
        }
        return null;
    }

    @Override
    public boolean testUserQrcode() {
        CallDeviceServiceDto callDeviceServiceDto = new CallDeviceServiceDto();
        callDeviceServiceDto.setIdentify(SENTQRCODETODOOR);
        callDeviceServiceDto.setProductKey("ARZueO1QNfnv5lEe");
        callDeviceServiceDto.setDeviceName("FBkYjrJdzLBvJ0c0");
        Map<String, Object> in = new HashMap<>();
        in.put("userName", "小行星");
        in.put("userId", "1234567891234567890");
        in.put("qrCode", "1234567891234567890");
        in.put("startTime", "2000-10-10 00:00:01");
        in.put("endTime", "3000-10-10 00:00:01");
        in.put("terminalNumber", "M00010101000");
        callDeviceServiceDto.setParams(in);
        String json = JSONObject.toJSONString(callDeviceServiceDto);
        Map map = JSONObject.parseObject(json, Map.class);

        //调用接口
        log.info("====== test下发二维码参数：{}",json);
        CallingDeviceServiceResponse response = ioTRemoteService.callServiceReturn(map);
        if(Func.isNotEmpty(response)){
            boolean result = false;
            String resultJson = JSONObject.toJSONString(response);
            log.info("====== test下发二维码返回数据：{}",resultJson);
            if(response.getCode().equals("200")){
                result = true;
            }
            return result;
        }
        return false;
    }

    @Override
    public List<PlDoorPoint> getUserPowerList(Long parkId, Long userId) {
        PlDoorUserPointSet pointSet = this.getOne(new LambdaQueryWrapper<PlDoorUserPointSet>()
                .eq(PlDoorUserPointSet::getParkId, parkId).eq(PlDoorUserPointSet::getUserId, userId)
                .last("limit 1"));
        if(Func.isNotEmpty(pointSet)){
            List<PlDoorUserPointSetItem> itemList = plDoorUserPointSetItemService.list(new LambdaQueryWrapper<PlDoorUserPointSetItem>()
                    .eq(PlDoorUserPointSetItem::getUserPointSetId, pointSet.getId()));
            if(Func.isNotEmpty(itemList)){
                List<Long> pointIds = itemList.stream().map(PlDoorUserPointSetItem::getDoorPointId).collect(Collectors.toList());
                return plDoorPointService.listByIds(pointIds);
            }
        }
        return null;
    }

    @Override
    public void checkPointPermission() {
        plDoorUserPointSetMapper.checkInOfDate();
        plDoorUserPointSetMapper.checkOutOfDate();
    }

    @Override
    public boolean tiejunVoice(String voiceStr, Long parkId, Long pointId) {
        if(Func.isNotEmpty(parkId) && Func.isNotEmpty(pointId)){
            PlDoorPoint point = plDoorPointService.getOne(new LambdaQueryWrapper<PlDoorPoint>()
                    .eq(PlDoorPoint::getDoorId, pointId)
                    .eq(PlDoorPoint::getParkId, parkId));
            if(Func.isEmpty(point)){
                log.info("====== 铁军语音播报，门禁点不存在");
                return false;
            }
            CallDeviceServiceDto callDeviceServiceDto = new CallDeviceServiceDto();
            callDeviceServiceDto.setIdentify(TEXTTOVOICE);
            callDeviceServiceDto.setProductKey(point.getProductKey());
            callDeviceServiceDto.setDeviceName(point.getDeviceNo());
            Map<String, Object> in = new HashMap<>();
            in.put("voice", voiceStr);
            callDeviceServiceDto.setParams(in);
            String json = JSONObject.toJSONString(callDeviceServiceDto);
            Map map = JSONObject.parseObject(json, Map.class);

            //调用接口
            log.info("====== 铁军调用iot语音播报参数：{}",json);
            CallingDeviceServiceResponse response = ioTRemoteService.callServiceReturn(map);
            if(Func.isNotEmpty(response)){
                boolean result = false;
                String resultJson = JSONObject.toJSONString(response);
                log.info("====== 铁军调用iot语音播报参数：{}",resultJson);
                if(response.getCode().equals("200")){
                    result = true;
                }
                return result;
            }
            return false;
        }
        return false;
    }

}
