package com.template.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.seewo.open.sdk.DefaultSeewoClient;
import com.seewo.open.sdk.SeewoClient;
import com.seewo.open.sdk.auth.Account;
import com.sun.org.apache.bcel.internal.generic.NEW;
import com.template.annotation.DESRespondSecret;
import com.template.annotation.PassToken;
import com.template.api.SmartVisitorControllerAPI;
import com.template.common.utils.*;
import com.template.config.ControlConfig;
import com.template.config.ParkConfig;
import com.template.config.SeewoConfig;
import com.template.model.dto.ParentsScreenDto;
import com.template.model.enumModel.*;
import com.template.model.pojo.*;
import com.template.model.request.otherAppointmentRequest;
import com.template.model.request.parentsAppointmentRequest;
import com.template.model.request.turnOnTheDeviceRequest;
import com.template.model.result.CommonResult;
import com.template.model.result.PageUtils;
import com.template.model.seewo.HomeSchoolServiceSendNoteToKidParam;
import com.template.model.seewo.HomeSchoolServiceSendNoteToKidRequest;
import com.template.model.seewo.HomeSchoolServiceSendNoteToKidResult;
import com.template.model.vo.*;
import com.template.services.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;

import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.template.common.utils.AesTestOne.decrypt;
import static com.template.common.utils.StrUtils.getUUIDBits;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author ceshi
 * @since 2023-12-04
 */
@RestController
//返回参数加密注解
@DESRespondSecret
public class SmartVisitorController implements SmartVisitorControllerAPI {

    private static Logger logger = LoggerFactory.getLogger(SmartVisitorController.class);
    @Autowired
    private SmartAuthorGroupService smartAuthorGroupService;

    @Autowired
    private SmartVisitorService smartVisitorService;

    @Autowired
    private SmartQrcodeService smartQrcodeService;

    @Autowired
    private SmartDeviceService smartDeviceService;

    @Autowired
    private SmartUserService smartUserService;

    @Resource
    private ControlConfig controlConfig;

    @Resource
    private SeewoConfig seewoConfig;

    @Resource
    private ParkConfig parkConfig;

    @Autowired
    SmartVisitorParentsConfigService smartVisitorParentsConfigService;

    @Autowired
    SmartVisitorRestsConfigService smartVisitorRestsConfigService;

    /**
     * 新增访客预约
     *
     * @param smartApply    访客预约数据
     * @param bindingResult
     * @return
     */
    @Override
    @DESRespondSecret(validated = true)
    public CommonResult insertSmartVisitor(SmartVisitor smartApply, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            String st = paramUtils.getParamError(bindingResult);
            return CommonResult.fail(st);
        }

        int result = smartVisitorService.insertSmartVisitor(smartApply);

        return result > 0 ? CommonResult.ok("添加成功") : CommonResult.fail("添加失败");
    }

    /**
     * 更新访客预约
     *
     * @param sa            访客预约数据
     * @param bindingResult
     * @return
     */
    @Override
    @DESRespondSecret(validated = true)
    public CommonResult updateSmartVisitorById(SmartVisitor sa, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            String st = paramUtils.getParamError(bindingResult);
            return CommonResult.fail(st);
        }

        int result = smartVisitorService.updateSmartVisitor(sa);
        return result > 0 ? CommonResult.ok("修改成功") : CommonResult.fail("修改失败");
    }

    /**
     * 访客预约分页数据查询
     *
     * @param currentPage 当前页数
     * @param pageCount   一页数据条数
     * @param name        查询名称
     * @return
     */
    @Override
    @DESRespondSecret(validated = true)
    public CommonResult queryPageSmartVisitor(int currentPage, int pageCount, String name) {
        PageUtils<SmartVisitor> result = smartVisitorService.queryPageSmartVisitors(currentPage, pageCount, name);

        return CommonResult.ok(result);
    }


    @Override
    @DESRespondSecret(validated = true)
    public CommonResult deleteSmartVisitorById(int id) {

        SmartVisitor data = smartVisitorService.getSmartById(id);
        if (data == null) {
            return CommonResult.fail("当前数据不存在，删除失败！");
        }

        //审核通过就不能删除
        if (data.getStatu().intValue() == eApproveStatu.Pushed.getValue()) {
            return CommonResult.fail("无法删除已审核通过的访客数据");
        }

        //已审核通过的数据不能删除 那么就不需要进行下面这些操作
        //region 推送到希沃班牌，通知访客记录取消
        //endregion
        //region 删除百胜中的访客数据
        //endregion

        int result = smartVisitorService.deleteSmartVisitorById(id);

        return result > 0 ? CommonResult.ok("删除成功") : CommonResult.fail("删除失败");
    }

    @Override
    @DESRespondSecret(validated = true)
    public CommonResult parentsAppointment(parentsAppointmentRequest par, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            String st = paramUtils.getParamError(bindingResult);
            return CommonResult.fail(st);
        }

        //参数判断 判断受访学生信息是否为空
        if (par.getStudents() == null) {
            return CommonResult.fail("请选择受访学生");
        }

        if (par.getStudents().size() <= 0) {
            return CommonResult.fail("请选择受访学生");
        }

        //根据用户ID查询相关信息
        SmartUser su = smartUserService.getSmartById(par.getUserId());
        if (su == null) {
            return CommonResult.fail("当前用户信息不合法，无法进行预约！");
        }

        String startTime = par.getVisitorTime();
        String endTime = TimeExchange.AddTimeDesH(TimeExchange.StringToDate(startTime, "yyyy-MM-dd HH:mm:ss"),4);

        //要进行家长数据重复判断
        //那是不是第二次预约的时间不能在那个可访问的时间段内
        //例如：比如，第一次约了7：00-10：00；那第二次：6：00-7：30 或 8：11-13：00都不行
        Integer count = smartVisitorService.queryVisitorCount(su.getId(), startTime, endTime);
        if (count > 0) {
            return CommonResult.fail("该时间段已预约，请勿重复预约！");
        }

        List<SmartVisitor> svs = new ArrayList<>();
        for (AffiliateUserVo student : par.getStudents()) {
            SmartVisitor sv = new SmartVisitor();
            sv.setUserId(par.getUserId());
            sv.setUserName(su.getName());
            sv.setUserPhone(su.getPhone());
            sv.setUserNumber(su.getIdCard());
            sv.setPeerNum(par.getPeerNum());
            sv.setCarNum(par.getCarNum());
            sv.setVisitReason(par.getVisitReason());
//            sv.setStatu(eApproveStatu.Audit.getValue());
            sv.setVisitorTime(TimeExchange.StringToDate(par.getVisitorTime(), "yyyy-MM-dd HH:mm:ss"));
            sv.setVisitorDeadline(TimeExchange.StringToDate(TimeExchange.AddTimeDesH(sv.getVisitorTime(), 4), "yyyy-MM-dd HH:mm:ss"));
            sv.setRespondent(student.getId());
            sv.setResponcode(student.getCardNo());
            sv.setRespondentName(student.getName());
            //将第一个受访学生的部门ID带过去
            sv.setDepartmentId(student.getDepartmentId());
            sv.setVisitorType(eVisitorType.Parent.getValue());
//            图片
            sv.setImage(par.getImage());
//            来源
            sv.setSource(1);
            //        获取受访者id
            Integer respondent = sv.getRespondent();
            SmartUser smartUser = smartUserService.getById(respondent);
            Integer schoolClass = smartUser.getSchoolClass();
            SmartVisitorParentsConfig svpc = smartVisitorParentsConfigService.getById(schoolClass);
            Integer appAuditConfig = svpc.getAppAuditConfig();
            if (1 == appAuditConfig) {//需要审核
                sv.setStatu(1);
            } else {//不需要审核
                Integer appPushConfig = svpc.getAppPushConfig();
//                判断是否需要推送
                if (5 == appPushConfig) {//需要推送
                    String content = sv.getRespondentName() + "你的家长将于" + TimeExchange.chineseDateTime(sv.getVisitorTime()) + "到校！";
                    //将预约信息推送到希沃班牌
                    CommonResult seewo = pushInfo(sv.getUserPhone(), sv.getResponcode(), content);
                }
//                核销
                Integer appCancelConfig = svpc.getAppCancelConfig();
                if (6 == appCancelConfig) {//需要核销
                    sv.setStatu(7);
                } else {//不需要核销
                    sv.setStatu(9);
                }
//                门禁配置
                Integer accessConfig = svpc.getAccessConfig();
                if (0 == accessConfig) {
                    try {
                        if (!ObjectUtils.isEmpty(sv.getCarNum())) {
                            String appId = parkConfig.getAppId();
                            String carNo = sv.getCarNum();
                            String parkKey = parkConfig.getParkKey();
                            String rand = String.valueOf(Math.random());
                            String reserveTime = TimeExchange.DateToString(sv.getVisitorTime(), "yyyy-MM-dd HH:mm:ss");
                            String reserveEndTime = TimeExchange.DateToString(sv.getVisitorDeadline(), "yyyy-MM-dd HH:mm:ss");
                            String version = "v1.0";
                            String appSecret = parkConfig.getAppSecret();
                            String url = parkConfig.getUrl() + "Inform/Reservation";

                            JSONObject jsonobject = new JSONObject();
                            jsonobject.put("appid", appId);
                            jsonobject.put("carNo", carNo);
                            jsonobject.put("parkKey", parkKey);
                            jsonobject.put("rand", rand);
                            jsonobject.put("reserveEndTime", reserveEndTime);
                            jsonobject.put("reserveTime", reserveTime);
                            jsonobject.put("version", "v1.0");

                            //appid=ymdd36ed157ac423e2&carNo=赣U123659&parkKey=wdcmq9rc&rand=9.94995525689689966&reserveEndTime=2023-12-22 20:12:10&reserveTime=2023-12-21 18:12:10&version=v1.0&50596cd243dc4547b4c05f01f8ea02a4
                            String md5Str = "appid=" + appId + "&carNo=" + carNo + "&parkKey=" + parkKey + "&rand=" + rand + "&reserveEndTime=" + reserveEndTime + "&reserveTime=" + reserveTime + "&version=" + version + "&" + appSecret;
                            String sign = CommonUtil.MD5(md5Str);
                            //sign签名
                            jsonobject.put("sign", sign);

                            //返回的结果中 code为1表示成功
                            String result = RequestUtils.httpPost(url, jsonobject.toJSONString());

                            logger.info(result);

                            if (!result.contains("预约成功")) {
                                throw new Exception("审核失败");
                            }

                            ObjectMapper objectMapper = new ObjectMapper();
                            BsReservationVo reservation = objectMapper.readValue(result, BsReservationVo.class);
                            sv.setBsOrderNo(reservation.getData().getReOrderNo());
                        } else {
                            List<SmartDevice> devices = smartDeviceService.queryOnLineDevice();
                            String visitorNo = getUUIDBits(16);
                            //region 将访客数据下发到设备
                            for (SmartDevice device : devices) {
                                CommonResult<String> insertVisitor = bsInsertVisitor(su, TimeExchange.DateToString(sv.getVisitorTime()), TimeExchange.DateToString(sv.getVisitorDeadline()), device.getNum(), visitorNo);
                                if (!insertVisitor.isSuccess()) {
                                    throw new Exception(insertVisitor.getMessage());
                                }
                                sv.setVisitorsync(sv.getVisitorsync() == null ? insertVisitor.getData() : (sv.getVisitorsync() + "," + insertVisitor.getData()));
                                sv.setDeviceNum(sv.getDeviceNum() == null ? device.getNum() : (sv.getDeviceNum() + "," + device.getNum()));
                            }
                            String code = GetVertifyCode.getRandomNumCode(6);
                            sv.setVisitorCode(code);
                        }
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            }

            svs.add(sv);
        }


        boolean result = smartVisitorService.insertVisitorBatch(svs);

        return result ? CommonResult.ok("预约成功") : CommonResult.fail("预约失败");
    }


    @Override
    @DESRespondSecret(validated = true)
    public CommonResult otherAppointment(otherAppointmentRequest oar, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            String st = paramUtils.getParamError(bindingResult);
            return CommonResult.fail(st);
        }

        //根据用户ID查询相关信息
        SmartUser su = smartUserService.getSmartById(oar.getUserId());
        if (su == null) {
            return CommonResult.fail("当前用户信息不合法，无法进行预约！");
        }

        String startTime = oar.getVisitorTime();
        String endTime = TimeExchange.AddTimeDesH(TimeExchange.StringToDate(startTime, "yyyy-MM-dd HH:mm:ss"),4);

        //要进行访客数据重复判断
        //那是不是第二次预约的时间不能在那个可访问的时间段内
        //例如：比如，第一次约了7：00-10：00；那第二次：6：00-7：30 或 8：11-13：00都不行
//        Integer count = smartVisitorService.queryVisitorCount(su.getIdCard(), startTime, endTime);
//        if (count > 0) {
//            return CommonResult.fail("该时间段已预约，请勿重复预约！");
//        }

        SmartVisitor sv = new SmartVisitor();
        sv.setUserId(oar.getUserId());
        sv.setUserName(oar.getUserName());
        sv.setUserPhone(oar.getUserPhone());
        sv.setUserNumber(oar.getUserCard());
        sv.setPeerNum(oar.getPeerNum());
        sv.setCarNum(oar.getCarNum());
        sv.setVisitReason(oar.getVisitReason());
//        sv.setStatu(eApproveStatu.Audit.getValue());
        sv.setVisitorTime(TimeExchange.StringToDate(startTime, "yyyy-MM-dd HH:mm:ss"));
        sv.setVisitorDeadline(TimeExchange.StringToDate(endTime, "yyyy-MM-dd HH:mm:ss"));
        sv.setRespondentName(oar.getRespondentName());
        sv.setRespondentPhone(oar.getRespondentPhone());
        sv.setVisitorType(eVisitorType.Other.getValue());
        //            来源
        sv.setSource(1);
        List<SmartVisitorRestsConfig> list = smartVisitorRestsConfigService.list(new LambdaQueryWrapper<>());
        SmartVisitorRestsConfig smartVisitorRestsConfig = list.get(0);
        Integer auditConfig = smartVisitorRestsConfig.getAuditConfig();
        if (1 == auditConfig) {//需要审核
            sv.setStatu(1);
        } else if (9 == auditConfig) {
            sv.setStatu(9);
            Integer accessConfig = smartVisitorRestsConfig.getAccessConfig();
            if (0 == accessConfig) {//推送到门禁
                try {
                    if (!ObjectUtils.isEmpty(sv.getCarNum())) {
                        String appId = parkConfig.getAppId();
                        String carNo = sv.getCarNum();
                        String parkKey = parkConfig.getParkKey();
                        String rand = String.valueOf(Math.random());
                        String reserveTime = TimeExchange.DateToString(sv.getVisitorTime(), "yyyy-MM-dd HH:mm:ss");
                        String reserveEndTime = TimeExchange.DateToString(sv.getVisitorDeadline(), "yyyy-MM-dd HH:mm:ss");
                        String version = "v1.0";
                        String appSecret = parkConfig.getAppSecret();
                        String url = parkConfig.getUrl() + "Inform/Reservation";

                        JSONObject jsonobject = new JSONObject();
                        jsonobject.put("appid", appId);
                        jsonobject.put("carNo", carNo);
                        jsonobject.put("parkKey", parkKey);
                        jsonobject.put("rand", rand);
                        jsonobject.put("reserveEndTime", reserveEndTime);
                        jsonobject.put("reserveTime", reserveTime);
                        jsonobject.put("version", "v1.0");

                        //appid=ymdd36ed157ac423e2&carNo=赣U123659&parkKey=wdcmq9rc&rand=9.94995525689689966&reserveEndTime=2023-12-22 20:12:10&reserveTime=2023-12-21 18:12:10&version=v1.0&50596cd243dc4547b4c05f01f8ea02a4
                        String md5Str = "appid=" + appId + "&carNo=" + carNo + "&parkKey=" + parkKey + "&rand=" + rand + "&reserveEndTime=" + reserveEndTime + "&reserveTime=" + reserveTime + "&version=" + version + "&" + appSecret;
                        String sign = CommonUtil.MD5(md5Str);
                        //sign签名
                        jsonobject.put("sign", sign);

                        //返回的结果中 code为1表示成功
                        String result = RequestUtils.httpPost(url, jsonobject.toJSONString());

                        logger.info(result);

                        if (!result.contains("预约成功")) {
                            throw new Exception("审核失败");
                        }

                        ObjectMapper objectMapper = new ObjectMapper();
                        BsReservationVo reservation = objectMapper.readValue(result, BsReservationVo.class);
                        sv.setBsOrderNo(reservation.getData().getReOrderNo());
                    } else {
                        List<SmartDevice> devices = smartDeviceService.queryOnLineDevice();
                        String visitorNo = getUUIDBits(16);
                        //region 将访客数据下发到设备
                        for (SmartDevice device : devices) {
                            CommonResult<String> insertVisitor = bsInsertVisitor(su, TimeExchange.DateToString(sv.getVisitorTime()), TimeExchange.DateToString(sv.getVisitorDeadline()), device.getNum(), visitorNo);
                            if (!insertVisitor.isSuccess()) {
                                throw new Exception(insertVisitor.getMessage());
                            }
                            sv.setVisitorsync(sv.getVisitorsync() == null ? insertVisitor.getData() : (sv.getVisitorsync() + "," + insertVisitor.getData()));
                            sv.setDeviceNum(sv.getDeviceNum() == null ? device.getNum() : (sv.getDeviceNum() + "," + device.getNum()));
                        }
                        String code = GetVertifyCode.getRandomNumCode(6);
                        sv.setVisitorCode(code);
                    }

                    //发送短信给其他访客用户
                    if (!ObjectUtils.isEmpty(sv.getVisitorCode())) {
                        String message = SendSms.sendVisitorSms("+86" + sv.getUserPhone(), TimeExchange.getYear(sv.getVisitorTime()), TimeExchange.getMonth(sv.getVisitorTime()), TimeExchange.getDay(sv.getVisitorTime()), TimeExchange.getTime(sv.getVisitorTime()), TimeExchange.getTime(sv.getVisitorDeadline()), sv.getVisitorCode());
                        if (!message.contains("success")) {
                            throw new Exception("发送失败");
                        }
                    }

                } catch (Exception e) {
                    throw new RuntimeException(e);
                }

            }
        }

        int result = smartVisitorService.insertSmartVisitor(sv);

        return result > 0 ? CommonResult.ok("预约成功，等待审批通过") : CommonResult.ok("预约失败");
    }

    @Override
    @DESRespondSecret(validated = true)
    public CommonResult appointmentPageRecord(int currentPage, int pageCount, Integer userId, int type, String createStartTime, String createEndTime, String keyWord, String visitorStartTime, String visitorEndTime) {
        PageUtils<VisitorPageListVo> result = smartVisitorService.smartVisitorPageByUserId(currentPage, pageCount, userId, type, createStartTime, createEndTime, keyWord, visitorStartTime, visitorEndTime);

        return CommonResult.ok(result);
    }

    /**
     * 访客记录审核
     *
     * @param id   数据ID
     * @param type 操作类型：
     *             同意，并推送：1
     *             拒绝：2
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public CommonResult examineRecord(int id, int type) throws Exception {
        SmartVisitor visitor = smartVisitorService.getSmartById(id);
        if (visitor == null) {
            return CommonResult.fail("访客记录已失效，审核失败！");
        }

        //审核处理后的数据不能再处理判断
        if (visitor.getStatu().intValue() != eApproveStatu.Audit.getValue()) {
            return CommonResult.fail("该记录已被操作过，请勿重复操作");
        }

        try {
            if (type == eExamineStatu.Agree.getValue()) {
                visitor.setStatu(eApproveStatu.Pushed.getValue());

                //家长访客预约才需要将消息推送到希沃电子班牌
                if (visitor.getVisitorType().intValue() == eVisitorType.Parent.getValue()) {
                    String content = visitor.getRespondentName() + "你的家长将于" + TimeExchange.chineseDateTime(visitor.getVisitorTime()) + "到校！";
                    //将预约信息推送到希沃班牌
                    CommonResult seewo = pushInfo(visitor.getUserPhone(), visitor.getResponcode(), content);
                    if (!seewo.getCode().equals("200")) {
                        throw new Exception("审核失败");
                    }

                }
                //将数据写入门禁系统逻辑
                //家长不能使用车牌系统 其他的可以使用车牌逻辑
                if (!ObjectUtils.isEmpty(visitor.getCarNum())) {
                    String appId = parkConfig.getAppId();
                    String carNo = visitor.getCarNum();
                    String parkKey = parkConfig.getParkKey();
                    String rand = String.valueOf(Math.random());
                    String reserveTime = TimeExchange.DateToString(visitor.getVisitorTime(), "yyyy-MM-dd HH:mm:ss");
                    String reserveEndTime = TimeExchange.DateToString(visitor.getVisitorDeadline(), "yyyy-MM-dd HH:mm:ss");
                    String version = "v1.0";
                    String appSecret = parkConfig.getAppSecret();
                    String url = parkConfig.getUrl() + "Inform/Reservation";

                    JSONObject jsonobject = new JSONObject();
                    jsonobject.put("appid", appId);
                    jsonobject.put("carNo", carNo);
                    jsonobject.put("parkKey", parkKey);
                    jsonobject.put("rand", rand);
                    jsonobject.put("reserveEndTime", reserveEndTime);
                    jsonobject.put("reserveTime", reserveTime);
                    jsonobject.put("version", "v1.0");

                    //appid=ymdd36ed157ac423e2&carNo=赣U123659&parkKey=wdcmq9rc&rand=9.94995525689689966&reserveEndTime=2023-12-22 20:12:10&reserveTime=2023-12-21 18:12:10&version=v1.0&50596cd243dc4547b4c05f01f8ea02a4
                    String md5Str = "appid=" + appId + "&carNo=" + carNo + "&parkKey=" + parkKey + "&rand=" + rand + "&reserveEndTime=" + reserveEndTime + "&reserveTime=" + reserveTime + "&version=" + version + "&" + appSecret;
                    String sign = CommonUtil.MD5(md5Str);
                    //sign签名
                    jsonobject.put("sign", sign);

                    //返回的结果中 code为1表示成功
                    String result = RequestUtils.httpPost(url, jsonobject.toJSONString());

                    logger.info(result);

                    if (!result.contains("预约成功")) {
                        throw new Exception("审核失败");
                    }

                    ObjectMapper objectMapper = new ObjectMapper();
                    BsReservationVo reservation = objectMapper.readValue(result, BsReservationVo.class);
                    visitor.setBsOrderNo(reservation.getData().getReOrderNo());
                } else {
                    //查找用户是否存在
                    SmartUser user = smartUserService.getSmartById(visitor.getUserId());
                    if (user == null) {
                        throw new Exception("访客用户ID在系统中不存在，无法将访客信息下发到门禁设备！");
                    }

                    List<SmartDevice> devices = smartDeviceService.queryOnLineDevice();
                    String visitorNo = getUUIDBits(16);
                    //region 将访客数据下发到设备
                    for (SmartDevice device : devices) {
                        CommonResult<String> insertVisitor = bsInsertVisitor(user, TimeExchange.DateToString(visitor.getVisitorTime()), TimeExchange.DateToString(visitor.getVisitorDeadline()), device.getNum(), visitorNo);
                        if (!insertVisitor.isSuccess()) {
                            throw new Exception(insertVisitor.getMessage());
                        }
                        visitor.setVisitorsync(visitor.getVisitorsync() == null ? insertVisitor.getData() : (visitor.getVisitorsync() + "," + insertVisitor.getData()));
                        visitor.setDeviceNum(visitor.getDeviceNum() == null ? device.getNum() : (visitor.getDeviceNum() + "," + device.getNum()));
                    }

                    //endregion

                    String code = GetVertifyCode.getRandomNumCode(6);
                    visitor.setVisitorCode(code);
                }

            } else if (type == eExamineStatu.Refused.getValue()) {
                visitor.setStatu(eApproveStatu.Refused.getValue());
            }

            int result = smartVisitorService.updateSmartVisitor(visitor);
            if (result <= 0) {
                throw new Exception("审核失败");
            }

            //发送短信给其他访客用户
            if (!ObjectUtils.isEmpty(visitor.getVisitorCode()) && type == eExamineStatu.Agree.getValue()) {
                String message = SendSms.sendVisitorSms("+86" + visitor.getUserPhone(), TimeExchange.getYear(visitor.getVisitorTime()), TimeExchange.getMonth(visitor.getVisitorTime()), TimeExchange.getDay(visitor.getVisitorTime()), TimeExchange.getTime(visitor.getVisitorTime()), TimeExchange.getTime(visitor.getVisitorDeadline()), visitor.getVisitorCode());
                if (!message.contains("success")) {
                    throw new Exception("审核失败");
                }
            }

        } catch (Exception e) {
            throw new Exception("审核失败");
        }

        return CommonResult.ok("审核成功");
    }


    @Override
    public CommonResult testVisitorDevice(int id, String deviceNo) throws Exception {
        SmartUser user = smartUserService.getSmartById(id);
        if (user == null) {
            return CommonResult.fail("访客用户ID在系统中不存在，无法将访客信息下发到门禁设备！");
        }

        List<SmartDevice> devices = smartDeviceService.queryOnLineDevice();
        String visitorNo = getUUIDBits(16);
        //region 将访客数据下发到设备
        for (SmartDevice device : devices) {
            CommonResult<String> insertVisitor = bsInsertVisitor(user, "2024-03-28 10:00:00", "2024-03-28 11:00:00", device.getNum(), visitorNo);
            if (!insertVisitor.isSuccess()) {
                return CommonResult.fail(insertVisitor.getMessage());
            }
        }


        return CommonResult.ok("操作成功");
    }

    @Override
    @DESRespondSecret(validated = true)
    public CommonResult getPage(int currentPage, int pageCount, Integer type, String keyWord, Integer status, String startTime, String endTime, String visitorStartTime, String visitorEndTime) {
        PageUtils<SmartVisitorVo> page = smartVisitorService.getPage(currentPage, pageCount, type, keyWord, status, startTime, endTime, visitorStartTime, visitorEndTime);

        return CommonResult.ok(page);
    }

    @Override
    public CommonResult parentsAudit(int id, int type) {
        SmartVisitor sv = smartVisitorService.getSmartById(id);
        if (sv == null) {
            return CommonResult.fail("访客记录已失效，审核失败！");
        }

        //审核处理后的数据不能再处理判断
        if (sv.getStatu().intValue() != eApproveStatu.Audit.getValue()) {
            return CommonResult.fail("该记录已被操作过，请勿重复操作");
        }
        try {
//            同意
            if (type == 4) {
                //        获取受访者id
                Integer respondent = sv.getRespondent();
                SmartUser smartUser = smartUserService.getById(respondent);
                Integer schoolClass = smartUser.getSchoolClass();
                SmartVisitorParentsConfig svpc = smartVisitorParentsConfigService.getById(schoolClass);
                Integer appPushConfig = svpc.getAppPushConfig();
//                判断是否需要推送
                if (5 == appPushConfig) {//需要推送
                    String content = sv.getRespondentName() + "你的家长将于" + TimeExchange.chineseDateTime(sv.getVisitorTime()) + "到校！";
                    //将预约信息推送到希沃班牌
                    CommonResult seewo = pushInfo(sv.getUserPhone(), sv.getResponcode(), content);
                }
//                核销
                Integer appCancelConfig = svpc.getAppCancelConfig();
                if (6 == appCancelConfig) {//需要核销
                    sv.setStatu(7);
                } else {//不需要核销
                    sv.setStatu(9);
                }
//                门禁配置
                Integer accessConfig = svpc.getAccessConfig();
                if (0 == accessConfig) {

                    if (!ObjectUtils.isEmpty(sv.getCarNum())) {
                        String appId = parkConfig.getAppId();
                        String carNo = sv.getCarNum();
                        String parkKey = parkConfig.getParkKey();
                        String rand = String.valueOf(Math.random());
                        String reserveTime = TimeExchange.DateToString(sv.getVisitorTime(), "yyyy-MM-dd HH:mm:ss");
                        String reserveEndTime = TimeExchange.DateToString(sv.getVisitorDeadline(), "yyyy-MM-dd HH:mm:ss");
                        String version = "v1.0";
                        String appSecret = parkConfig.getAppSecret();
                        String url = parkConfig.getUrl() + "Inform/Reservation";

                        JSONObject jsonobject = new JSONObject();
                        jsonobject.put("appid", appId);
                        jsonobject.put("carNo", carNo);
                        jsonobject.put("parkKey", parkKey);
                        jsonobject.put("rand", rand);
                        jsonobject.put("reserveEndTime", reserveEndTime);
                        jsonobject.put("reserveTime", reserveTime);
                        jsonobject.put("version", "v1.0");

                        //appid=ymdd36ed157ac423e2&carNo=赣U123659&parkKey=wdcmq9rc&rand=9.94995525689689966&reserveEndTime=2023-12-22 20:12:10&reserveTime=2023-12-21 18:12:10&version=v1.0&50596cd243dc4547b4c05f01f8ea02a4
                        String md5Str = "appid=" + appId + "&carNo=" + carNo + "&parkKey=" + parkKey + "&rand=" + rand + "&reserveEndTime=" + reserveEndTime + "&reserveTime=" + reserveTime + "&version=" + version + "&" + appSecret;
                        String sign = CommonUtil.MD5(md5Str);
                        //sign签名
                        jsonobject.put("sign", sign);

                        //返回的结果中 code为1表示成功
                        String result = RequestUtils.httpPost(url, jsonobject.toJSONString());

                        logger.info(result);

                        if (!result.contains("预约成功")) {
                            throw new Exception("审核失败");
                        }

                        ObjectMapper objectMapper = new ObjectMapper();
                        BsReservationVo reservation = objectMapper.readValue(result, BsReservationVo.class);
                        sv.setBsOrderNo(reservation.getData().getReOrderNo());
                    } else {
                        //查找用户是否存在
                        SmartUser user = smartUserService.getSmartById(sv.getUserId());
                        if (user == null) {
                            throw new Exception("访客用户ID在系统中不存在，无法将访客信息下发到门禁设备！");
                        }
                        List<SmartDevice> devices = smartDeviceService.queryOnLineDevice();
                        String visitorNo = getUUIDBits(16);
                        //region 将访客数据下发到设备
                        for (SmartDevice device : devices) {
                            CommonResult<String> insertVisitor = bsInsertVisitor(user, TimeExchange.DateToString(sv.getVisitorTime()), TimeExchange.DateToString(sv.getVisitorDeadline()), device.getNum(), visitorNo);
                            if (!insertVisitor.isSuccess()) {
                                throw new Exception(insertVisitor.getMessage());
                            }
                            sv.setVisitorsync(sv.getVisitorsync() == null ? insertVisitor.getData() : (sv.getVisitorsync() + "," + insertVisitor.getData()));
                            sv.setDeviceNum(sv.getDeviceNum() == null ? device.getNum() : (sv.getDeviceNum() + "," + device.getNum()));
                        }
                        String code = GetVertifyCode.getRandomNumCode(6);
                        sv.setVisitorCode(code);
                    }

                }

            } else if (type == 2) {//拒绝
                sv.setStatu(2);
            }
            int result = smartVisitorService.updateSmartVisitor(sv);
            if (result <= 0) {
                throw new Exception("审核失败");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return CommonResult.ok("审核成功");
    }

    @Override
    public CommonResult restsAudit(int id, int type) {
        SmartVisitor sv = smartVisitorService.getSmartById(id);
        if (sv == null) {
            return CommonResult.fail("访客记录已失效，审核失败！");
        }

        //审核处理后的数据不能再处理判断
        if (sv.getStatu().intValue() != eApproveStatu.Audit.getValue()) {
            return CommonResult.fail("该记录已被操作过，请勿重复操作");
        }

        try {
            //            同意
            if (type == 4) {
                sv.setStatu(9);
                List<SmartVisitorRestsConfig> list = smartVisitorRestsConfigService.list(new LambdaQueryWrapper<>());
                SmartVisitorRestsConfig smartVisitorRestsConfig = list.get(0);
                Integer accessConfig = smartVisitorRestsConfig.getAccessConfig();
                if (0 == accessConfig) {
                    //推送到门禁
                    if (!ObjectUtils.isEmpty(sv.getCarNum())) {
                        String appId = parkConfig.getAppId();
                        String carNo = sv.getCarNum();
                        String parkKey = parkConfig.getParkKey();
                        String rand = String.valueOf(Math.random());
                        String reserveTime = TimeExchange.DateToString(sv.getVisitorTime(), "yyyy-MM-dd HH:mm:ss");
                        String reserveEndTime = TimeExchange.DateToString(sv.getVisitorDeadline(), "yyyy-MM-dd HH:mm:ss");
                        String version = "v1.0";
                        String appSecret = parkConfig.getAppSecret();
                        String url = parkConfig.getUrl() + "Inform/Reservation";

                        JSONObject jsonobject = new JSONObject();
                        jsonobject.put("appid", appId);
                        jsonobject.put("carNo", carNo);
                        jsonobject.put("parkKey", parkKey);
                        jsonobject.put("rand", rand);
                        jsonobject.put("reserveEndTime", reserveEndTime);
                        jsonobject.put("reserveTime", reserveTime);
                        jsonobject.put("version", "v1.0");

                        //appid=ymdd36ed157ac423e2&carNo=赣U123659&parkKey=wdcmq9rc&rand=9.94995525689689966&reserveEndTime=2023-12-22 20:12:10&reserveTime=2023-12-21 18:12:10&version=v1.0&50596cd243dc4547b4c05f01f8ea02a4
                        String md5Str = "appid=" + appId + "&carNo=" + carNo + "&parkKey=" + parkKey + "&rand=" + rand + "&reserveEndTime=" + reserveEndTime + "&reserveTime=" + reserveTime + "&version=" + version + "&" + appSecret;
                        String sign = CommonUtil.MD5(md5Str);
                        //sign签名
                        jsonobject.put("sign", sign);

                        //返回的结果中 code为1表示成功
                        String result = RequestUtils.httpPost(url, jsonobject.toJSONString());

                        logger.info(result);

                        if (!result.contains("预约成功")) {
                            throw new Exception("审核失败");
                        }

                        ObjectMapper objectMapper = new ObjectMapper();
                        BsReservationVo reservation = objectMapper.readValue(result, BsReservationVo.class);
                        sv.setBsOrderNo(reservation.getData().getReOrderNo());
                    } else {
                        List<SmartDevice> devices = smartDeviceService.queryOnLineDevice();
                        String visitorNo = getUUIDBits(16);
                        //region 将访客数据下发到设备
                        for (SmartDevice device : devices) {
                            //查找用户是否存在
                            SmartUser user = smartUserService.getSmartById(sv.getUserId());
                            if (user == null) {
                                throw new Exception("访客用户ID在系统中不存在，无法将访客信息下发到门禁设备！");
                            }
                            CommonResult<String> insertVisitor = bsInsertVisitor(user, TimeExchange.DateToString(sv.getVisitorTime()), TimeExchange.DateToString(sv.getVisitorDeadline()), device.getNum(), visitorNo);
                            if (!insertVisitor.isSuccess()) {
                                throw new Exception(insertVisitor.getMessage());
                            }
                            sv.setVisitorsync(sv.getVisitorsync() == null ? insertVisitor.getData() : (sv.getVisitorsync() + "," + insertVisitor.getData()));
                            sv.setDeviceNum(sv.getDeviceNum() == null ? device.getNum() : (sv.getDeviceNum() + "," + device.getNum()));
                        }
                        String code = GetVertifyCode.getRandomNumCode(6);
                        sv.setVisitorCode(code);
                    }

                    //发送短信给其他访客用户
                    if (!ObjectUtils.isEmpty(sv.getVisitorCode())) {
                        Date visitorTime = sv.getVisitorTime();
                        Date visitorDeadline = sv.getVisitorDeadline();
                        String start = TimeExchange.getTime(visitorTime);
                        String end = TimeExchange.getTime(visitorDeadline);
                        String message = SendSms.sendVisitorSms("+86" + sv.getUserPhone(), TimeExchange.getYear(sv.getVisitorTime()), TimeExchange.getMonth(sv.getVisitorTime()), TimeExchange.getDay(sv.getVisitorTime()), start, end, sv.getVisitorCode());
                        if (!message.contains("success")) {
                            throw new Exception("发送失败");
                        }
                    }

                }
            } else if (type == 2) {//拒绝
                sv.setStatu(2);
            }
            int result = smartVisitorService.updateSmartVisitor(sv);
            if (result <= 0) {
                throw new Exception("审核失败");
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return CommonResult.ok("审核成功");
    }

    @Override
    @PassToken
    public CommonResult parentsScreen(ParentsScreenDto par, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            String st = paramUtils.getParamError(bindingResult);
            return CommonResult.fail(st);
        }

        //参数判断 判断受访学生信息是否为空
        if (par.getStudents() == null) {
            return CommonResult.fail("请选择受访学生");
        }

        if (par.getStudents().size() <= 0) {
            return CommonResult.fail("请选择受访学生");
        }

        //根据用户ID查询相关信息
        SmartUser su = smartUserService.getSmartById(par.getUserId());
        if (su == null) {
            return CommonResult.fail("当前用户信息不合法，无法进行预约！");
        }
        DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime date = LocalDateTime.now();
        String startTime = date.format(dateTimeFormatter1);

        String endTime = TimeExchange.AddTimeDesH(TimeExchange.StringToDate(startTime, "yyyy-MM-dd HH:mm:ss"),4);

        //要进行家长数据重复判断
        //那是不是第二次预约的时间不能在那个可访问的时间段内
        //例如：比如，第一次约了7：00-10：00；那第二次：6：00-7：30 或 8：11-13：00都不行
        Integer count = smartVisitorService.queryVisitorCount(su.getId(), startTime, endTime);
        if (count > 0) {
            return CommonResult.fail("该时间段已预约，请勿重复预约！");
        }

        List<SmartVisitor> svs = new ArrayList<>();
        for (AffiliateUserVo student : par.getStudents()) {
            SmartVisitor sv = new SmartVisitor();
            sv.setUserId(par.getUserId());
            sv.setUserName(su.getName());
            sv.setUserPhone(su.getPhone());
            sv.setUserNumber(su.getIdCard());
            sv.setPeerNum(0);
            sv.setVisitReason(par.getVisitReason());
//            sv.setStatu(eApproveStatu.Audit.getValue());
            sv.setVisitorTime(TimeExchange.StringToDate(startTime, "yyyy-MM-dd HH:mm:ss"));
            sv.setVisitorDeadline(TimeExchange.StringToDate(TimeExchange.AddTimeDesH(sv.getVisitorTime(), 4), "yyyy-MM-dd HH:mm:ss"));
            sv.setRespondent(student.getId());
            sv.setResponcode(student.getCardNo());
            sv.setRespondentName(student.getName());
            //将第一个受访学生的部门ID带过去
            sv.setDepartmentId(student.getDepartmentId());
            sv.setVisitorType(eVisitorType.Parent.getValue());
//            来源
            sv.setSource(2);
            //        获取受访者id
            Integer respondent = sv.getRespondent();
            SmartUser smartUser = smartUserService.getById(respondent);
            Integer schoolClass = smartUser.getSchoolClass();
            SmartVisitorParentsConfig svpc = smartVisitorParentsConfigService.getById(schoolClass);
            Integer screenAuditConfig = svpc.getScreenAuditConfig();
            if (1 == screenAuditConfig) {//需要审核
                sv.setStatu(1);
            } else {//不需要审核
                Integer screenPushConfig = svpc.getScreenPushConfig();
//                判断是否需要推送
                if (5 == screenPushConfig) {//需要推送
                    String content = sv.getRespondentName() + "你的家长将于" + TimeExchange.chineseDateTime(sv.getVisitorTime()) + "到校！";
                    //将预约信息推送到希沃班牌
                    CommonResult seewo = pushInfo(sv.getUserPhone(), sv.getResponcode(), content);
                }
//                核销
                Integer screenCancelConfig = svpc.getScreenCancelConfig();
                if (6 == screenCancelConfig) {//需要核销
                    sv.setStatu(7);
                } else {//不需要核销
                    sv.setStatu(9);
                }
//                门禁配置
                Integer accessConfig = svpc.getAccessConfig();
                if (0 == accessConfig) {
                    try {
                        List<SmartDevice> devices = smartDeviceService.queryOnLineDevice();
                        String visitorNo = getUUIDBits(16);
                        //region 将访客数据下发到设备
                        for (SmartDevice device : devices) {
                            CommonResult<String> insertVisitor = bsInsertVisitor(su, TimeExchange.DateToString(sv.getVisitorTime()), TimeExchange.DateToString(sv.getVisitorDeadline()), device.getNum(), visitorNo);
                            if (!insertVisitor.isSuccess()) {
                                throw new Exception(insertVisitor.getMessage());
                            }
                            sv.setVisitorsync(sv.getVisitorsync() == null ? insertVisitor.getData() : (sv.getVisitorsync() + "," + insertVisitor.getData()));
                            sv.setDeviceNum(sv.getDeviceNum() == null ? device.getNum() : (sv.getDeviceNum() + "," + device.getNum()));
                        }
                        String code = GetVertifyCode.getRandomNumCode(6);
                        sv.setVisitorCode(code);

                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            }

            svs.add(sv);
        }


        boolean result = smartVisitorService.insertVisitorBatch(svs);

        return result ? CommonResult.ok("预约成功") : CommonResult.fail("预约失败");


    }

    @Override
    @DESRespondSecret(validated = true)
    @PassToken
    public CommonResult getScreenPage(int currentPage, int pageCount, String phone,String status) {
        PageUtils<SmartVisitorScreenListVo> page = smartVisitorService.getScreenPage(currentPage, pageCount,phone,status);

        return CommonResult.ok(page);
    }

    @Override
    @PassToken
    public CommonResult cancel(int id) {
        boolean b = smartVisitorService.removeById(id);
        if (b) {
            return CommonResult.ok();
        }
        return CommonResult.fail();
    }

    @Override
    @PassToken
    public CommonResult verification(int id) {
        SmartVisitor sv = smartVisitorService.getSmartById(id);
        if (sv == null) {
            return CommonResult.fail("访客记录已失效，审核失败！");
        }
        Integer statu = sv.getStatu();
        if (9==statu) {
            return CommonResult.fail("该记录已完成，请勿重复操作");
        }
        if (2==statu) {
            return CommonResult.fail("该记录未同意");
        }
        if (1==statu) {
            return CommonResult.fail("该记录还未通过审核");
        }
        if (7==statu) {
            sv.setStatu(8);
            int result = smartVisitorService.updateSmartVisitor(sv);
            if (result > 0) {
                return CommonResult.ok("进校核销成功");
            }
        }else if(8==statu){
            sv.setStatu(9);
            int result = smartVisitorService.updateSmartVisitor(sv);
            if (result > 0) {
                return CommonResult.ok("出校核销成功");
            }
        }

        return CommonResult.fail();
    }

    @Override
    @DESRespondSecret(validated = true)
    @PassToken
    public CommonResult parentsScreenPage(int currentPage, int pageCount, int userId, String status) {
        PageUtils<SmartVisitorScreenListVo> result = smartVisitorService.parentsScreenPage(currentPage, pageCount, userId, status);
        return CommonResult.ok(result);

    }

    /**
     * 1、学生请假：
     * 我们这边调用请假接口之后，把请假数据写到了百胜系统的"学生请假登记"页面中，那到时候学生是通过任意设备都能进出吗？
     * 即：万载三中有 A、B、C、D四台门禁设备，学生张三 2024-03-01 10:00:00 到 2024-03-01 12:00:00 请假，张三 2024-03-01 10:10:00的时候能否通过A、B、C、D四台门禁设备？
     * <p>
     * 注：如果要修改请假数据则要先修改系统中的学生编码，再去新增一条请假数据
     * 即：修改了这个学生编码之后再下发请假数据的话，原有的该学号的请假数据就会在设备中被清除
     * <p>
     * 2、访客设备：
     * 我们这边调用门禁访客设备接口，是把数据下发到系统还是到门禁设备？
     * 如果是写到门禁的话，后续添加访客数据是否会清除之前的所有已写入的访客数据？
     * <p>
     * <p>
     * 答：
     * 1、请假数据会自动会同步到设备
     * 2、访客数据是下发到门禁设备的，访客数据有效期到了之后会自动被清除掉；如果删除系统中的用户数据会自动把门禁中的用户数据也删掉，如果是已有的则进行更新操作；
     *
     * @param su
     * @param startTime
     * @param endTime
     * @param deviceNo
     * @param visitorNo
     * @return
     * @throws Exception
     */

    //region 百胜添加访客数据到设备
    public CommonResult<String> bsInsertVisitor(SmartUser su, String startTime, String endTime, String deviceNo, String visitorNo) throws Exception {
        //region 百胜添加教师数据
        String appId = controlConfig.getAppId();
        String schoolno = controlConfig.getSchoolCode();
        String timestamp = TimeExchange.DateNowTimeStamo();
        String appSecret = controlConfig.getAppSecret();
        String url = controlConfig.getUrl() + "visitor/sync";

        JSONObject jsonobject = new JSONObject();
        jsonobject.put("appid", appId);
        String str = "{\"device_no\":\"" + deviceNo + "\",\"visitor_begindate\":\"" + startTime + "\",\"visitor_enddate\":\"" + endTime + "\",\"visitor_idcard\":\"" + su.getIdCard() + "\",\"visitor_name\":\"" + su.getName() + "\",\"visitor_no\":\"" + visitorNo + "\",\"visitor_phone\":\"" + su.getPhone() + "\",\"visitor_photo\":\"" + su.getHeadImage() + "\",\"visitor_sex\":\"" + su.getSexId() + "\"}";
        String aesStr = URLEncoder.encode(AesTestOne.encrypt(str, controlConfig.getAppSecret()), "UTF-8");
        jsonobject.put("data", aesStr);
        jsonobject.put("schoolno", schoolno);
        jsonobject.put("timestamp", timestamp);

        String md5Str = "appid=" + appId + "&data={\"device_no\":\"" + deviceNo + "\",\"visitor_begindate\":\"" + startTime + "\",\"visitor_enddate\":\"" + endTime + "\",\"visitor_idcard\":\"" + su.getIdCard() + "\",\"visitor_name\":\"" + su.getName() + "\",\"visitor_no\":\"" + visitorNo + "\",\"visitor_phone\":\"" + su.getPhone() + "\",\"visitor_photo\":\"" + su.getHeadImage() + "\",\"visitor_sex\":\"" + su.getSexId() + "\"}" + "&schoolno=" + schoolno + "&timestamp=" + timestamp + "&key=" + appSecret;
        String sign = CommonUtil.MD5(md5Str);
        //sign签名
        jsonobject.put("sign", sign);

        //返回的结果中 code为1表示成功
        String bsResult = RequestUtils.httpPost(url, jsonobject.toJSONString());

        ObjectMapper objectMapper = new ObjectMapper();
        BsDeviceVo device = objectMapper.readValue(bsResult, BsDeviceVo.class);

        if (!bsResult.contains("添加成功")) {
            return CommonResult.fail(device.getMsg());
        }

        // URL解码
        String decodedUrl = URLDecoder.decode(device.getData(), "UTF-8");

        BsDeviceNoVo deviceNoData = objectMapper.readValue(decrypt(decodedUrl, controlConfig.getAppSecret()), BsDeviceNoVo.class);
        su.setBsStaffCode(deviceNoData.getVisitorsync_no());

        return CommonResult.ok("200", "新增成功", deviceNoData.getVisitorsync_no());
        //endregion
    }
    //endregion

    /**
     * 将预约信息推送到希沃电子班牌
     *
     * @param parentPhone 预约手机号（家长手机号 在希沃中学生会和家长手机号绑定 可以绑定多个家长）
     * @param studentCode 学生编号 希沃中的学生编号和万载系统中的一致
     * @param content     消息内容
     * @return
     */
    public CommonResult pushInfo(String parentPhone, String studentCode, String content) {
        //初始化客户端
        SeewoClient seewoClient = new DefaultSeewoClient(new Account(seewoConfig.getAppId(), seewoConfig.getAppSecret()));
        HomeSchoolServiceSendNoteToKidParam param = new HomeSchoolServiceSendNoteToKidParam();
        //响应体，MimeType为 application/json
        HomeSchoolServiceSendNoteToKidParam.RequestBody requestBody = HomeSchoolServiceSendNoteToKidParam.RequestBody.builder()
                .build();
        param.setRequestBody(requestBody);
        //query
        HomeSchoolServiceSendNoteToKidParam.Query query = HomeSchoolServiceSendNoteToKidParam.Query.builder()
                .appId(seewoConfig.getAppId())
                .schoolUid(seewoConfig.getSchoolId())
                .senderPhone(parentPhone)
                .studentCode(studentCode)
                .type(1)
                .content(content)
                .autoRegister(0)
                .build();
        requestBody.setQuery(query);
        param.setRequestBody(requestBody);
        HomeSchoolServiceSendNoteToKidRequest request = new HomeSchoolServiceSendNoteToKidRequest(param);
        logger.info("入参：" + request);
        //如果想要调用沙箱环境，请通过设置 request 对象的 serverUrl 属性，如：
        //request.setServerUrl("https://openapi.test.seewo.com")
        //执行请求，如果想获取到com.seewo.open.sdk.HttpResponse对象，请调用 seewoClient.execute 方法
        HomeSchoolServiceSendNoteToKidResult result = seewoClient.invoke(request);
        logger.info("出参：" + result);
        if (!result.getMessage().equals("success")) {
            CommonResult.fail();
        }

        return CommonResult.ok();
    }

    /**
     * 获取到访代办数据
     *
     * @param userId
     * @return
     */
    @Override
    @DESRespondSecret(validated = false)
    public CommonResult visitingAgencys(int currentPage, int pageCount, int userId, int type) {
        SmartUser user = smartUserService.getSmartById(userId);
        if (user == null) {
            return CommonResult.fail("当前用户数据无效，获取到访数据失败");
        }

        if (user.getIdentityId().intValue() != eIdentityStatu.Teacher.getValue()) {
            return CommonResult.fail("非教师身份无法获取到访数据");
        }

        //是否是管理员
        String whereSql = null;
        //获取的权限组数据
        List<SmartAuthorGroup> authorGroups = smartAuthorGroupService.smartAuthorGroup(user.getId());
        for (SmartAuthorGroup authorGroup : authorGroups) {
            List<String> applyIds = Arrays.asList(authorGroup.getApplyId().split(","));
            //菜单表中7是访客预约
            long appointCount = applyIds.stream().filter(e -> e.equals("7")).count();
            if (appointCount > 0) {
                whereSql = "visitor_type = 2";
                break;
            }
        }

        List<Integer> studentIds = null;
        //班主任
        if (user.getDuties().intValue() == eDuties.ClassTeacher.getValue()) {
            //班级ID
            Integer schoolClass = user.getSchoolClass();
            //获取该班级下的所有学生ID数据
            List<SmartUser> students = smartUserService.queryStudentBySchoolClass(user.getSchoolClass());

            if (students == null) {
                return CommonResult.fail("当前身份下不存在学生信息");
            }

            studentIds = students.stream().map(SmartUser::getId).collect(Collectors.toList());
        }

        PageUtils<SmartVisitor> result = new PageUtils<SmartVisitor>(null, 0, pageCount, currentPage);

        if (whereSql == null && studentIds == null) {
            return CommonResult.ok(result);
        }

        result = smartVisitorService.queryVisitorPageDatas(currentPage, pageCount, type, studentIds, studentIds != null && whereSql != null ? "or " + whereSql : whereSql);

        return CommonResult.ok(result);
    }

    /**
     * 扫码 分为 身份码 和 访客码
     * 1、身份码：
     * 1.1、如果是老师 任意通行
     * 1.2、如果是家长 找有没有访客数据
     * 1.3、如果是学生 不让通行
     * <p>
     * 2、访客码
     * 2.1、找下是否存在访客预约记录
     * <p>
     * 扫码记录增加是否已进 和 是否已出字段
     *
     * @param data
     * @return
     * @throws JsonProcessingException
     */
    @Override
    public TurnOnDeviceVo turnOnTheDevice(turnOnTheDeviceRequest data) throws JsonProcessingException {
        logger.info("进入扫码解析，参数：" + JSON.toJSON(data));

        TurnOnDeviceVo result = new TurnOnDeviceVo();
        logger.info("进入扫码解析1");
        //region 参数判断
        if (data == null) {
            result.setResultcode(2);
            result.setMessage("扫码参数不能为空");
            result.setActionName("qrCodePush");
            return result;
        }
        logger.info("进入扫码解析2");
        if (data.getActionName() == null) {
            result.setResultcode(2);
            result.setMessage("指令不能为空");
            result.setActionName("qrCodePush");
            return result;
        }
        logger.info("进入扫码解析3");
        if (!data.getActionName().equals("qrCodePush")) {
            result.setResultcode(2);
            result.setMessage("指令错误");
            result.setActionName("qrCodePush");
            return result;
        }
        logger.info("进入扫码解析4");
        if (data.getData() == null) {
            result.setResultcode(2);
            result.setMessage("二维码内容不能为空");
            result.setActionName("qrCodePush");
            return result;
        }
        logger.info("进入扫码解析5");
        ObjectMapper objectMapper = new ObjectMapper();
        qrCodeVo codeVo = objectMapper.readValue(data.getData(), qrCodeVo.class);
        if (codeVo == null) {
            result.setResultcode(2);
            result.setMessage("二维码内容不能为空");
            result.setActionName("qrCodePush");
            return result;
        }
        logger.info("进入扫码解析6");
        if (codeVo.getQrCode() == null) {
            result.setResultcode(2);
            result.setMessage("二维码内容不能为空");
            result.setActionName("qrCodePush");
            return result;
        }
        logger.info("进入扫码解析7");
        if (data.getDeviceno() == null) {
            result.setResultcode(2);
            result.setMessage("设备编号不能为空");
            result.setActionName("qrCodePush");
            return result;
        }
        logger.info("进入扫码解析8");
        if (data.getVersion() == null) {
            result.setResultcode(2);
            result.setMessage("版本不能为空");
            result.setActionName("qrCodePush");
            return result;
        }
        //endregion
        logger.info("进入扫码解析9");
        //解码逻辑
        QrcodeImageVo qiv = objectMapper.readValue(codeVo.getQrCode(), QrcodeImageVo.class);
        logger.info("进入扫码解析10");

        SmartDevice deviceData = smartDeviceService.queryDeviceByNum(data.getDeviceno());
        if (deviceData == null) {
            logger.info("进入扫码解析11");
            result.setResultcode(2);
            result.setMessage("设备不存在");
            result.setActionName("qrCodePush");
            return result;
        }

        if (qiv.getType().intValue() == eQrcodeType.Identity.getValue()) {//身份码
            //身份码中的ID是身份码ID
            logger.info("进入身份码扫码解析1");
            //目前二维码一分钟内有效
            //过期：（时间戳 + 有效期分钟数）<= 当前时间
            //时间戳转时间
            Date dateNow = TimeExchange.StringToDate(TimeExchange.TimeRangeMinute(qiv.getTimestamp(), 1), "yyyy-MM-dd HH:mm:ss");
            logger.info("dateNow参数：" + TimeExchange.DateToString(dateNow));
            logger.info("当前时间参数：" + TimeExchange.DateToString(new Date()));
            if (new Date().after(dateNow)) {
                logger.info("身份码过期");
                result.setResultcode(2);
                result.setMessage("身份码已过期");
                result.setActionName("qrCodePush");
                return result;
            }
            logger.info("进入身份码扫码解析2");

            SmartUser user = smartUserService.getSmartById(qiv.getId());
            if (user == null) {
                result.setResultcode(2);
                result.setMessage("用户身份无效，刷码失败");
                result.setActionName("qrCodePush");
                return result;
            }

            //成功后将刷码记录存储到数据表中
            SmartQrcode sq = new SmartQrcode();
            /**
             * 1、身份码逻辑
             * 1.1、如果是老师 任意通行
             * 1.2、如果是家长 找有没有访客数据
             * 1.3、如果是学生 不让通行
             */
            switch (user.getIdentityId().intValue()) {
                case 1://家长
                    //查找是否存在访客记录
                    SmartVisitor visitor = smartVisitorService.queryParentVisitor(user.getId());
                    if (visitor == null) {
                        logger.info("无访客数据，家长无法通行");
                        result.setResultcode(2);
                        result.setMessage("无访客数据，家长无法通行");
                        result.setActionName("qrCodePush");
                        return result;
                    }

                    sq.setUserId(qiv.getId());
                    sq.setQrcodeType(qiv.getType());
                    sq.setSourceCode(data.getData());
                    sq.setDataId(visitor.getId());
                    sq.setIsSuccess(1);
                    sq.setAccessState(deviceData.getEntrance());
                    break;
                case 2://学生
                    logger.info("学生无法使用身份码通行");
                    result.setResultcode(2);
                    result.setMessage("学生无法使用身份码通行");
                    result.setActionName("qrCodePush");
                    return result;
                case 3://老师
                    sq.setUserId(qiv.getId());
                    sq.setQrcodeType(qiv.getType());
                    sq.setSourceCode(data.getData());
                    sq.setDataId(0);
                    sq.setIsSuccess(1);
                    sq.setAccessState(deviceData.getEntrance());
                    break;
                default:
                    break;
            }

            logger.info("进入身份码扫码解析3");
            int insertResult = smartQrcodeService.insertSmartQrcode(sq);
            if (insertResult <= 0) {
                result.setResultcode(2);
                result.setMessage("新增刷码记录失败");
                result.setActionName("qrCodePush");
                return result;
            }
            logger.info("进入身份码扫码解析4");
            result.setResultcode(1);
            result.setMessage("成功");
            result.setActionName("qrCodePush");

            logger.info("进入身份码扫码解析，结果：" + JSON.toJSON(result));
        } else if (qiv.getType().intValue() == eQrcodeType.Visitor.getValue()) {//访客码
            //访客码中的ID是访客数据的ID
            //查找是否存在访客记录
            SmartVisitor visitor = smartVisitorService.getSmartById(qiv.getId());
            if (visitor == null) {
                logger.info("无访客数据，访客无法通行");
                result.setResultcode(2);
                result.setMessage("无访客数据，访客无法通行");
                result.setActionName("qrCodePush");
                return result;
            }
            //成功后将刷码记录存储到数据表中
            SmartQrcode sq = new SmartQrcode();
            sq.setUserId(visitor.getUserId());
            sq.setQrcodeType(qiv.getType());
            sq.setSourceCode(data.getData());
            sq.setDataId(visitor.getId());
            sq.setIsSuccess(1);
            sq.setAccessState(deviceData.getEntrance());

            logger.info("进入访客码扫码解析3");
            int insertResult = smartQrcodeService.insertSmartQrcode(sq);
            if (insertResult <= 0) {
                result.setResultcode(2);
                result.setMessage("新增刷码记录失败");
                result.setActionName("qrCodePush");
                return result;
            }
            logger.info("进入访客码扫码解析4");
            result.setResultcode(1);
            result.setMessage("成功");
            result.setActionName("qrCodePush");

            logger.info("进入访客码扫码解析，结果：" + JSON.toJSON(result));
        }

        return result;
    }

}

