package com.xhkjedu.suser.service.system;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xhkjedu.suser.config.ConfigKey;
import com.xhkjedu.suser.mapper.gradeclass.ClassMapper;
import com.xhkjedu.suser.mapper.subjectbook.TeacherPowersbMapper;
import com.xhkjedu.suser.mapper.system.MsgMapper;
import com.xhkjedu.suser.mapper.system.UserLogMapper;
import com.xhkjedu.suser.mapper.system.UserMapper;
import com.xhkjedu.suser.model.system.TMsg;
import com.xhkjedu.suser.model.system.TUser;
import com.xhkjedu.suser.model.system.TUserLog;
import com.xhkjedu.suser.vo.assess.SignParams;
import com.xhkjedu.suser.vo.gradeclass.ClassVo;
import com.xhkjedu.suser.vo.system.LoginParams;
import com.xhkjedu.utils.*;
import com.xhkjedu.vo.ResultVo;
import com.xhkjedu.vo.system.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * @Description：登录
 * @Author: WN
 * @Date: 2024/1/5 14:11:44
 **/
@Service
@Slf4j
public class LoginService extends JedisUtil{
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserLogService userLogService;
    @Resource
    private MsgMapper msgMapper;
    @Resource
    private TeacherPowersbMapper teacherPowersbMapper;
    @Resource
    private UserLogMapper userLogMapper;
    @Resource
    private ClassMapper classMapper;


    /**
     * 功能描述  根据登录名和密码获取用户信息
     *
     * @param * @param user
     * @return com.xhkjedu.vo.ResultVo
     * @author WN
     * @date 2020/6/1
     */
    public ResultVo getUserByLoginnameAndPwd(TUser user, HttpServletRequest request) {
        ResultVo resultVo = null;
        String loginpwd = user.getLoginpwd();
        setLoginPwd(user);

        //更加登录帐号获取用户信息
        UserVo userVo = userMapper.getUserByLoginname(user.getLoginname());

        if (userVo != null && userVo.getUserid() > 0) {
            user.setUsertype(userVo.getUsertype());
            user.setUserid(userVo.getUserid());
            user.setUsername(userVo.getUsername());
            user.setSchoolid(userVo.getSchoolid());

            //验证用户信息
            resultVo = this.checkLoginUser(user, userVo, 1);

        } else {
            resultVo = new ResultVo(1, "此账号不存在");
        }

        return getLogResultVo(user, resultVo, loginpwd, request);
    }

    //验证用户
    private ResultVo checkLoginUser(TUser user, UserVo userVo, Integer checkmethod) {
        //判断学校状态
        if (N_Utils.isTrueInteger(userVo.getSchoolstate()) && userVo.getSchoolstate() != 1) {
            return new ResultVo(1, "学校已锁定，请联系管理员", userVo);
        }

        //先判断帐号是否被锁定
        if (userVo.getUserlock() == 1) {
            String roleName="管理员";
            if(N_Utils.isTrueInteger(userVo.getUsertype()) && userVo.getUsertype() == 2){
                roleName = "老师";
            }
            return new ResultVo(1, "账号已锁定，请联系" + roleName, userVo);
        }

        if (checkmethod == 1 && !userVo.getLoginpwd().equals(user.getLoginpwd())) {
            int errornum = 1;
            if(N_Utils.isTrueInteger(userVo.getErrornum())){
                errornum = userVo.getErrornum() + 1;
            }

            //修改码连续出错次数
            userMapper.updateErrornum(userVo.getUserid(),errornum);

            Integer loginerrornum =  ConfigKey.loginerrornum;
            int synum = loginerrornum - errornum;//剩余次数
            if(synum <= 0){
                //如果密码连续出错次数超过等于或超过限制，锁定账号
                userMapper.updateUserLock(userVo.getUserid(),1);
            }

            String msg = "密码错误";
            if(synum>0 && synum <= 5){
                msg = msg + "，还可以尝试"+ synum +"次，账号将被锁定。";
            }else if(synum == 0){
                msg = msg + "，账号已被锁定。";
            }

            //帐号密码登录
            return new ResultVo(1, msg, userVo);
        } else {
            Integer usertype = userVo.getUsertype();
            if (usertype == 999) {
                return new ResultVo(0, "登录成功", userVo);
            }

            //判断用户状态
            if (userVo.getUserstate() != 1) {
                if (usertype == 2) {//学生
                    return new ResultVo(1, "此账号无权访问，请联系老师", userVo);
                } else {
                    return new ResultVo(1, "此账号无权访问，请联系管理员", userVo);
                }
            }

            //判断用户有效期
            String usertime = userVo.getUsertime();
            if (N_Utils.isNotEmpty(usertime)) {
                String dayBegin = DatesUtil.getDayBegin();
                if (usertime.compareTo(dayBegin) < 0) {
                    if (usertype == 2) {//学生
                        return new ResultVo(1, "账号已过有效期，请联系老师", userVo);
                    } else {
                        return new ResultVo(1, "账号已过有效期，请联系管理员", userVo);
                    }
                }
            }

            //进行角色判断
            if (usertype == 2) {
                Integer stuweb = userVo.getStuweb();
                if (stuweb != null && stuweb != 1) return new ResultVo(1, "学生账号无法登录", userVo);

                Integer sbindmac = userVo.getSbindmac();
                String mac = user.getMac();

                //获取学生绑定的设备和行政班信息
                UserVo binduser = userMapper.getStudentByuserIdMac(userVo.getUserid(), mac);
                if (sbindmac == 1 && N_Utils.isNotEmpty(mac)) {
                    if (N_Utils.isNotEmpty(binduser.getMac()) && !mac.equals(binduser.getMac())) {
                        return new ResultVo(1, "登录失败，此账号已被其他设备绑定", userVo);
                    } else {
                        //20211221添加注释，sql语句修改了，不绑定的情况下会出现一个mac可以绑定多个帐号，绑定情况下没问题
                        if (N_Utils.isNotEmpty(binduser.getMacname()) && !binduser.getMacname().equals(user.getLoginname())) {
                            String msg = "登录失败，此设备已被【" + userVo.getMacname() +"】绑定";
                            return new ResultVo(1, msg, userVo);
                        } else {
                            return new ResultVo(0, "登录成功", userVo);
                        }
                    }
                }
                //验证用户是否有行政班
                if (binduser.getXznum() == 0) {
                    return new ResultVo(1, "此账号未分配班级", userVo);
                }

                String device = user.getDevice();//只有学生
                if (device != null && "pad".equals(device)) {
                    //更新学生硬件绑定信息
                    userVo.setMac(mac);
                    userVo.setBindmac(sbindmac);
                    userMapper.updateBindMac(userVo);
                }

                return new ResultVo(0, "登录成功", userVo);
            } else {
                if(usertype == 0 || usertype == 1){
                    //如果是管理员或者教师，获取任教科目
                    String subjectid = teacherPowersbMapper.getSubjectidByUserid(userVo.getUserid());
                    userVo.setSubjectid(subjectid);
                }

                return new ResultVo(0, "登录成功", userVo);
            }
        }
    }


    //教师登录
    public ResultVo loginTeacher(TUser user, HttpServletRequest request) {
        ResultVo resultVo = null;
        String loginpwd = user.getLoginpwd();
        setLoginPwd(user);
        UserVo userVo = userMapper.getUserByLoginname(user.getLoginname());

        if (userVo != null && userVo.getUserid() > 0) {
            user.setUserid(userVo.getUserid());
            user.setUsername(userVo.getUsername());
            user.setSchoolid(userVo.getSchoolid());
            user.setUsertype(userVo.getUsertype());
            if (userVo.getUsertype() != 1) {
                resultVo = new ResultVo(1, "禁止非教师帐号登录", userVo);
            } else {
                //验证用户信息
                resultVo = this.checkLoginUser(user, userVo, 1);
            }
        } else {
            resultVo = new ResultVo(1, "此账号不存在");
        }
        return getLogResultVo(user, resultVo, loginpwd, request);
    }

    /**
     * 学生登录
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [user]
     * @Author ywx
     * @Date 2020/6/2 11:14
     **/
    public ResultVo loginStudent(TUser user, HttpServletRequest request) {
        ResultVo resultVo = null;
        String loginpwd = user.getLoginpwd();
        setLoginPwd(user);
        String mac = "";
        if(N_Utils.isNotEmpty(user.getMac())){
            mac = user.getMac().toUpperCase();
        }

        user.setMac(mac);
        UserVo userVo = userMapper.getUserByLoginnameMac(user.getLoginname(), mac);

        if (userVo != null && userVo.getUserid() > 0) {
            user.setUserid(userVo.getUserid());
            user.setUsername(userVo.getUsername());
            user.setSchoolid(userVo.getSchoolid());
            user.setUsertype(userVo.getUsertype());
            if(N_Utils.isNotEmpty(userVo.getMac())){
                String userVoMac = userVo.getMac().toUpperCase();
                userVo.setMac(userVoMac);
            }

            //验证学生登录系列问题
            resultVo = checkLoginStudent(user, userVo);
        } else {
            resultVo = new ResultVo(1, "此账号不存在");
        }

        return getLogResultVo(user, resultVo, loginpwd, request);
    }

    //验证学生登录系列问题
    private ResultVo checkLoginStudent(TUser user, UserVo userVo) {
        //学生端禁止非学生帐号登录
        if (userVo.getUsertype() != 2) {
            return new ResultVo(1, "登录失败，仅允许学生登录", userVo);
        }

        //判断学校状态
        if (N_Utils.isTrueInteger(userVo.getSchoolstate()) && userVo.getSchoolstate() != 1) {
            return new ResultVo(1, "学校已锁定，请联系管理员", userVo);
        }

        if (userVo.getUserlock() == 1) {
            String roleName="管理员";
            if(N_Utils.isTrueInteger(userVo.getUsertype())){
                roleName = "老师";
            }
            return new ResultVo(1, "账号已锁定，请联系" + roleName, userVo);
        }

        if (!userVo.getLoginpwd().equals(user.getLoginpwd())) {
            int errornum = 1;
            if(N_Utils.isTrueInteger(userVo.getErrornum())){
                errornum = userVo.getErrornum() + 1;
            }

            //修改码连续出错次数
            userMapper.updateErrornum(userVo.getUserid(),errornum);

            Integer loginerrornum =  ConfigKey.loginerrornum;
            int synum = loginerrornum - errornum;//剩余次数
            if(synum <= 0){
                //如果密码连续出错次数超过等于或超过限制，锁定账号
                userMapper.updateUserLock(userVo.getUserid(),1);
            }

            String msg = "密码错误";
            if(synum>0 && synum <= 5){
                msg = msg + "，还可以尝试"+ synum +"次，账号将被锁定。";
            }else if(synum == 0){
                msg = msg + "，账号已被锁定。";
            }

            return new ResultVo(1, msg, userVo);
        } else {
            Integer sbindmac = userVo.getSbindmac();//学校是否绑定设备0未绑定1绑定
            String mac = user.getMac();
            String usertime = userVo.getUsertime();

            //判断用户状态
            if (userVo.getUserstate() != 1) {
                return new ResultVo(1, "此账号无权访问，请联系老师", userVo);
            }

            if (userVo.getXznum() == 0) {
                return new ResultVo(1, "此账号未分配班级", userVo);
            } else if (N_Utils.isNotEmpty(usertime)) {
                String dayBegin = DatesUtil.getDayBegin();
                if (usertime.compareTo(dayBegin) < 0) {
                    return new ResultVo(1, "账号已过有效期，请联系老师", userVo);
                }
            } else if (sbindmac == 1 && N_Utils.isNotEmpty(mac)) {
                if (N_Utils.isNotEmpty(userVo.getMac()) && !mac.equals(userVo.getMac())) {
                    return new ResultVo(1, "登录失败，此账号已被其他设备绑定", userVo);
                } else {
                    //20211221添加注释，sql语句修改了，不绑定的情况下会出现一个mac可以绑定多个帐号，绑定情况下没问题
                    if (N_Utils.isNotEmpty(userVo.getMacname()) && !userVo.getMacname().equals(user.getLoginname())) {
                        String msg = "登录失败，此设备已被【" + userVo.getMacname() +"】绑定";
                        return new ResultVo(1, msg, userVo);
                    }
                }
            }

            //更新学生硬件绑定信息
            userVo.setMac(mac);
            userVo.setBindmac(sbindmac);
            userMapper.updateBindMac(userVo);
            return new ResultVo(0, "登录成功", userVo);
        }
    }

    /**
     * 验证码登录
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [user]
     * @Author ywx
     * @Date 2020/10/13 15:36
     **/
    public ResultVo loginByCode(TUser user, HttpServletRequest request) {
        ResultVo resultVo = getCodeResultVo(user.getUserphone(), user.getMsgcode());
        if (resultVo != null) return resultVo;
        UserVo userVo = userMapper.getUserByPhone(user.getUserphone());

        if (userVo != null && userVo.getUserid() > 0) {
            Integer usertype = user.getUsertype();
            Integer utype = userVo.getUsertype();
            if (usertype != null && usertype == 1 && utype != 0 & utype != 1) {//教师端只能管理员、教师登录
                return new ResultVo(1, "禁止非教师帐号登录", userVo);
            }
            user.setUserid(userVo.getUserid());
            user.setUsername(userVo.getUsername());
            user.setSchoolid(userVo.getSchoolid());
            user.setLoginname(userVo.getLoginname());
            user.setUsertype(userVo.getUsertype());

            resultVo = checkLoginUser(user, userVo, 2);
        } else {
            resultVo = new ResultVo(1, "此账号不存在");
        }

        return getLogResultVo(user, resultVo, user.getMsgcode() + "", request);
    }

    /**
     * @Description 扫码登录：二维码登录时根据用户id获取用户
     * @Date 2023/2/2 14:11
     * @Author wn
     * @param user
     * @param request
     * @return ResultVo
     **/
    public ResultVo loginByErcodeSave(TUser user, HttpServletRequest request) {
        UserVo userVo = userMapper.findById(user.getUserid());
        if (userVo != null && userVo.getUserid() > 0) {
            //成功获取用户，把二维码唯一标识对应用户信息存入缓存中
            String erkey_value = JSON.toJSONString(userVo);
            Boolean redis_rtn = set(user.getQrkey(), erkey_value, ConfigKey.ercodredistime);
            if (!redis_rtn) {
                return new ResultVo(1,"加入缓存出错!");
            }
            return new ResultVo(0,"获取成功");
        }else{
            return new ResultVo(1,"获取用户失败");
        }
    }


    /**
     * @Description 扫码登录：获取二维码对应用户信息
     * @Date 2023/2/2 14:09
     * @Author wn
     * * @param user
     * @param request
     * * @return ResultVo
     **/
    public ResultVo loginByErcodeGet(TUser user, HttpServletRequest request) {
        ResultVo result = new ResultVo();
        //根据二维码唯一值key获取缓存中用户
        UserVo userVo = get(user.getQrkey(), UserVo.class);
        if(userVo != null && userVo.getUserid() > 0){
            result.setCode(0);
            result.setObj(userVo);
            //获取到用户信息后保存登录日志
            return getLogResultVo(user,result,"扫码登录",request);

        }else{
            result.setCode(1);
            result.setMsg("登录失败");
            return result;
        }
    }

    /**
     * 登录日志
     *
     * @return com.xhkjedu.vo.ResultVo
     * @Param [loginname, device, user, result]
     * @Author ywx
     * @Date 2020/6/2 11:08
     **/
    private ResultVo getLogResultVo(TUser user, ResultVo result, String loginpwd, HttpServletRequest request) {
        String loginname = user.getLoginname();
        TUserLog userLog = new TUserLog();
        userLog.setLoginname(loginname);
        userLog.setMac(user.getMac());
        UserVo userVo = null;
        if (result.getCode() == 0) {
            userVo = (UserVo) result.getObj();
            //redis
            String ticketKey = UUID.randomUUID().toString().replace("-", "");
            String token = DESUtils.encrypt(ticketKey, ConfigKey.secretKey);//加密
            String key = userVo.getCloudcode() + "_" + userVo.getUserid() + "_" + user.getUltype();
            Boolean redis_rtn = set(key, token, ConfigKey.redisdatatime);
            if (!redis_rtn) {
                result.setCode(1);
                result.setMsg("加入缓存出错!");
                userLog.setLoginstate(2);
                userLog.setLogtxt("登录失败，" + result.getMsg());
                // return result;
            } else {
                userLog.setLoginstate(1);
                userLog.setLogtxt("登录成功");
                userVo.setToken_key(key);
                userVo.setToken_value(token);
                result.setObj(userVo);
            }

            //登录成功，清空连续密码出错次数
            if(N_Utils.isTrueInteger(userVo.getErrornum())){
                userMapper.updateErrornum(userVo.getUserid(),0);
            }
        } else {
            if(N_Utils.isNotEmpty(result.getObj())){
                userVo = (UserVo) result.getObj();
            } else {
                userVo = new UserVo();
                userVo.setLoginname(user.getLoginname());
                userVo.setLoginpwd(loginpwd);
            }
            userLog.setLoginstate(2);
            if(result.getMsg().contains("密码错误")){
                userLog.setLogtxt("登录失败，" + result.getMsg() + "，密码：" + loginpwd);
            }else{
                userLog.setLogtxt("登录失败，" + result.getMsg());
            }
        }

        //保存登录日志
        saveSyncLoginLog(userLog,user,userVo,request);

        if(result.getCode() == 1){
            result.setObj(null);
        }

        return result;
    }

    //保存登录日志
    @Async("asyncPoolTaskExecutor")
    public void saveSyncLoginLog(TUserLog userLog, TUser user,UserVo userVo, HttpServletRequest request) {
        try {

            userLog.setUserid(userVo.getUserid());
            userLog.setUsername(userVo.getUsername());
            userLog.setSchoolid(userVo.getSchoolid());
            userLog.setLoginname(userVo.getLoginname());
            userLog.setSystemversion(user.getSystemversion());
            userLog.setUltypeband(user.getUltypeband());
            userLog.setUltypemodel(user.getUltypemodel());
            userLog.setSystembit(user.getSystembit());
            Integer usertype = userVo.getUsertype();
            userLog.setUsertype(usertype);
            userLog.setYear(userVo.getYear());
            String ultype = user.getUltype();
            if (N_Utils.isNotEmpty(ultype) && (ultype.equals("p_web") || ultype.equals("live_pc")) && usertype != null) {
                //网页端学生和教师合并登录，前端传p_web,拼接完整的ultype
                if (usertype == 2) {
                    userLog.setUltype(user.getUltype() + "_s");
                } else {
                    userLog.setUltype(user.getUltype() + "_t");
                }
            } else {
                userLog.setUltype(user.getUltype());
            }

            userLog.setVersionnum(user.getVersionnum());
            int logintime = N_Utils.getSecondTimestamp();
            userLog.setLogtime(logintime);

            //获取请求ip并解析区域
            String ip = N_Utils.getIpAddress(request);
            String region = null;
            if (N_Utils.isNotEmpty(ip)) {
                IpRegionUtil ipRegionUtil = new IpRegionUtil();
                region = ipRegionUtil.getIpForAddress(ip,ConfigKey.ipregiondb);
            }
            userLog.setLogip(ip);
            userLog.setLogaddress(region);

            boolean cloudsynclogin = ConfigKey.cloudsynclogin;//为true时代表同步云平台
            if(cloudsynclogin && userLog.getLoginstate() !=null){
                userLogService.saveSyncUserLogin(userVo, user, userLog);
            }

            userLogMapper.insertSelective(userLog);

        } catch (Exception e) {
            log.error("添加登录日志失败:" + e.getMessage());
        }
    }

    /**
     * 判断验证码是否有效
     *
     * @return com.xhkjedu.model.baseinfo.ResultVo
     * @Param [userphone, messageCode]
     * @Author ywx
     * @Date 2020/5/8 10:21
     **/
    private ResultVo getCodeResultVo(String userphone, String messageCode) {
        TMsg msg = msgMapper.findByUserPhoneAndCode(userphone, messageCode);//根据手机号和验证码获取短信信息
        if (msg == null) return new ResultVo(1, "验证码有误");
        int secondTimestamp = N_Utils.getSecondTimestamp() - 300;//验证码有效时间为5分钟
        if (msg.getCreatetime() < secondTimestamp) return new ResultVo(1, "验证码失效");
        return null;
    }

    private void setLoginPwd(TUser user) {
        MD5 m = new MD5();
        String loginpwd = m.getMD5ofStr(m.getMD5ofStr(m.getMD5ofStr(user.getLoginpwd())));
        user.setLoginpwd(loginpwd);
    }

    public ResultVo loginByName(TUser user, HttpServletRequest request) {
        ResultVo resultVo = null;
        UserVo userVo = userMapper.getUserByLoginname(user.getLoginname());

        if (userVo != null && userVo.getUserid() > 0) {
            user.setUserid(userVo.getUserid());
            user.setUsername(userVo.getUsername());
            user.setSchoolid(userVo.getSchoolid());
            user.setUltype("p_web_t");
            if (userVo.getUsertype() == 999) {
                resultVo = new ResultVo(0, "登录成功", userVo);
            } else if (userVo.getUsertype() == 2) {
                resultVo = new ResultVo(1, "禁止学生登录");
            } else if (userVo.getSchoolstate() != 1) {
                resultVo = new ResultVo(1, "账号所在学校暂无权限");
            } else {
                if (userVo.getUserstate() != 1) {
                    resultVo = new ResultVo(1, "此账号无权访问，请联系管理员");
                } else {
                    resultVo = new ResultVo(0, "登录成功", userVo);
                }
            }
        } else {
            resultVo = new ResultVo(1, "此账号不存在");
        }

        return getLogResultVo(user, resultVo, "", request);
    }

    /*
     * @Description 对接三方登录校验
     * @Date 2024/1/5 11:12:36
     * @Author WN
     * @Param [signParams, request]
     * @Return com.xhkjedu.vo.ResultVo
     **/
    public ResultVo signCheck(SignParams signParams, HttpServletRequest request){
        String loginType = signParams.getLoginType();
        if(N_Utils.isEmpty(loginType) || "3".equals(loginType)){
            return new ResultVo(1,"认证失败！");
        }

        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("loginType", signParams.getLoginType());
        paramMap.put("loginName", signParams.getLoginName());
        paramMap.put("successURL", signParams.getSuccessURL());
        paramMap.put("timestamp", signParams.getTimestamp());
        paramMap.put("thirdSystemId", signParams.getThirdSystemId());
        // 获取排序整理后的字符串
        String sortStr = getSortStr(paramMap);
        // System.out.println("sortStr="+ sortStr);
        //loginName=STXX&loginType=1&successURL=http://zhxy2.zzstxx.com&thirdSystemId=ff80808189107806018919a8a4480105&timestamp=1675319629762
        // 开始签名
        String signValue = sign(ConfigKey.secretKey, sortStr);
        // System.out.println("signValue=" + signValue);
        // 设置签名key
        paramMap.put("sign", signValue);

        if(!signValue.equals(signParams.getSign())){
            return new ResultVo(1,"认证失败！");
        }

        UserVo userVo = null;
        if("1".equals(loginType)){
            //帐号登录
            userVo = userMapper.getUserByLoginname(signParams.getLoginName());
        }
        if("2".equals(loginType)){
            //手机号登录
            userVo = userMapper.getUserByPhone(signParams.getLoginName());
        }

        ResultVo resultVo;
        TUser user = new TUser();
        user.setUltype(signParams.getUltype());
        user.setSystembit(signParams.getSystembit());
        user.setSystemversion(signParams.getSystemversion());
        user.setUltypeband(signParams.getUltypeband());
        user.setUltypemodel(signParams.getUltypemodel());
        user.setVersionnum(signParams.getVersionnum());

        if (userVo != null && userVo.getUserid() > 0) {
            user.setUsertype(userVo.getUsertype());
            user.setUserid(userVo.getUserid());
            user.setUsername(userVo.getUsername());
            user.setSchoolid(userVo.getSchoolid());

            //验证用户信息
            resultVo = checkLoginUser(user, userVo, 2);

        } else {
            resultVo = new ResultVo(1, "此账号不存在");
        }

        return getLogResultVo(user, resultVo, "", request);
    }

    /**
     * 获取排序整理后的字符串
     * @param paramMap map
     * @return 排序整理后的字符串
     */
    private static String getSortStr(Map<String, String> paramMap) {
        TreeMap<String, String> treeMap = new TreeMap<>(paramMap);
        StringBuilder signSb = new StringBuilder();
        for (Map.Entry<String, String> entry : treeMap.entrySet()) {
            signSb.append("&").append(entry.getKey()).append("=").append(entry.getValue());
        }
        return signSb.substring(1);
    }

    /**
     * 数据签名
     * @param secret 秘钥
     * @param data   待签名的数据
     * @return 签名结果
     */
    private static String sign(String secret, String data) {
        try {
            javax.crypto.Mac mac = javax.crypto.Mac.getInstance("HmacSHA1");
            mac.init(new javax.crypto.spec.SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA1"));
            byte[] signData = mac.doFinal(data.getBytes("UTF-8"));
            return java.util.Base64.getEncoder().encodeToString(signData);
        } catch (Exception e) {
            return null;
        }
    }

    /*
     * @Description 对接管控处理内容
     * @Date 2024/7/13 18:04:50
     * @Author WN
     * @Param [params, request]
     * @Return com.xhkjedu.vo.ResultVo
     **/
    public ResultVo singleLogin(LoginParams params,HttpServletRequest request){
        Integer authType = params.getAuthType(); //1账号2学号3手机号码4身份证号
        String loginname = params.getLoginname();
        Map<String,String> mapParam = new HashMap<>();
        mapParam.put("authKey",params.getAuthKey());
        mapParam.put("authType",authType+"");
        mapParam.put("loginname",params.getLoginname());
        mapParam.put("timestamp",params.getTimestamp()+"");

        String paramSign = sign(ConfigKey.secretKey,getSortStr(mapParam));
        if(!paramSign.equals(params.getSign())){
            return new ResultVo(1,"认证失败！");
        }
        String mac = params.getMac();
        if(N_Utils.isNotEmpty(params.getMac())){
            mac = params.getMac().toUpperCase();
        }

        UserVo userVo = null;
        if(authType == 1){
            //帐号登录
            userVo = userMapper.getUserByLoginnameMac(loginname,mac);
        }

        if(authType == 2){
            //学号登录
            userVo = userMapper.getUserByStudentnoForStu(loginname, mac);
        }

        if(authType == 3){
            //手机号登录
            userVo = userMapper.getUserByPhoneForStu(loginname, mac);
        }
        if(authType == 4){
            //身份证号
            userVo = userMapper.getUserByCardidForStu(loginname, mac);
        }

        TUser user = new TUser();
        user.setLoginname(loginname);
        String loginpwd = params.getLoginpwd();
        user.setLoginpwd(loginpwd);
        setLoginPwd(user);
        ResultVo resultVo = null;
        if (userVo != null && userVo.getUserid() > 0) {
            user.setUserid(userVo.getUserid());
            user.setUsername(userVo.getUsername());
            user.setSchoolid(userVo.getSchoolid());
            user.setUsertype(userVo.getUsertype());
            if(N_Utils.isNotEmpty(userVo.getMac())){
                String userVoMac = userVo.getMac().toUpperCase();
                userVo.setMac(userVoMac);
            }

            //验证学生登录系列问题
            resultVo = checkLoginStudent(user, userVo);
        } else {
            resultVo = new ResultVo(1, "此账号不存在");
        }

        resultVo = getLogResultVo(user, resultVo, loginpwd, request);
        if(resultVo.getCode() == 0){
            //把区域码作为额外参数
            Map<String,Object> rtnMap = JSONObject.parseObject(JSONObject.toJSONString(userVo));
            rtnMap.put("schoolName",userVo.getSchoolname());
            rtnMap.put("extendParams",userVo.getCloudcode());

            //获取学生当前所在行政班
            ClassVo classVo = classMapper.getXzClassByUserid(userVo.getUserid());
            rtnMap.put("classid",classVo.getClassid());
            String gradeName = N_Utils.getGradeName(classVo.getGradeid());
            rtnMap.put("classname",gradeName + classVo.getClassname());
            resultVo.setObj(rtnMap);
        }

        return resultVo;
    }

    /*
     * @Description 单点登录信息--学生平板
     * @Date 2024/7/13 18:05:01
     * @Author WN
     * @Param [tUser, request]
     * @Return com.xhkjedu.vo.ResultVo
     **/
    public ResultVo autoLogin(TUser tUser,HttpServletRequest request){
        UserVo userVo = userMapper.getUserByLoginnameMac(tUser.getLoginname(), tUser.getMac());
        ResultVo resultVo = new ResultVo(0,userVo);
        return getLogResultVo(tUser, resultVo, null, request);
    }
}
