package com.ruoyi.hezhi.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.ServiceResponseEnum;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.common.weixin.config.WeiXinConfig;
import com.ruoyi.common.weixin.config.WeiXinXcxMemberConfig;
import com.ruoyi.common.weixin.utils.WeiXinXcxMemberUtils;
import com.ruoyi.hezhi.domain.TbStudent;
import com.ruoyi.hezhi.domain.dto.ImportStudentDTO;
import com.ruoyi.hezhi.domain.dto.MemberUserLoginDTO;
import com.ruoyi.hezhi.domain.dto.StudentDTO;
import com.ruoyi.hezhi.mapper.TbStudentMapper;
import com.ruoyi.hezhi.service.ITbSmsCodeService;
import com.ruoyi.hezhi.service.ITbStudentService;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.awt.*;
import java.io.BufferedInputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static java.util.concurrent.TimeUnit.SECONDS;

/**
 * 学员Service业务层处理
 *
 * @author ruoyi
 * @date 2024-10-21
 */
@Service
public class TbStudentServiceImpl implements ITbStudentService {
    @Autowired
    private TbStudentMapper tbStudentMapper;
    @Resource
    private RedisCache redisCache;
    @Resource
    private ITbSmsCodeService smsCodeService;
    @Resource
    private WeiXinXcxMemberUtils weiXinXcxMemberUtils;
    @Resource
    private WeiXinXcxMemberConfig weiXinXcxMemberConfig;
    @Resource
    private SqlSessionFactory sqlSessionFactory;
    @Resource
    private WeiXinConfig weiXinConfig;

    /**
     * 查询学员
     *
     * @param studentId 学员主键
     * @return 学员
     */
    @Override
    public TbStudent selectTbStudentByStudentId(Long studentId) {
        return tbStudentMapper.selectTbStudentByStudentId(studentId);
    }

    /**
     * 查询学员列表
     *
     * @param tbStudent 学员
     * @return 学员
     */
    @Override
    public List<TbStudent> selectTbStudentList(TbStudent tbStudent) {
        return tbStudentMapper.selectTbStudentList(tbStudent);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String importUser(List<ImportStudentDTO> list){
        if (list.isEmpty()) {
            throw new ServiceException("Excel数据为空");
        }
        // 去重
        list = list.stream().distinct().collect(Collectors.toList());

        // 存放失败信息
        Map<String, String> errorList = new HashMap<>();
        int successRow = 0;
        List<TbStudent> insertList = new ArrayList<>();
        // 转换为 TbStudent 对象
        List<TbStudent> tbStudents = BeanUtil.copyToList(list, TbStudent.class);

        // 批量查询数据库中已存在的手机号和身份证号
        Set<String> phoneSet = tbStudents.stream().map(TbStudent::getPhone).collect(Collectors.toSet());
        Set<String> idCardSet = tbStudents.stream()
                .map(TbStudent::getIdentityCard)
                .filter(ObjectUtils::isNotEmpty)
                .collect(Collectors.toSet());

        // 查询数据库已存在的手机号和身份证号
        List<TbStudent> existingPhoneList = tbStudentMapper.selectTbStudentByPhones(phoneSet);
        List<TbStudent> existingIdCardList = tbStudentMapper.selectTbStudentByIdCards(idCardSet);

        // 将数据库查询结果转换为可查询的集合
        Set<String> existingPhones = existingPhoneList.stream().map(TbStudent::getPhone).collect(Collectors.toSet());
        Set<String> existingIdCards = existingIdCardList.stream().map(TbStudent::getIdentityCard).collect(Collectors.toSet());

        // 校验并准备插入数据
        for (TbStudent tbStudent : tbStudents) {
            try{
                checkImportStudent(tbStudent);
            }catch (ServiceException e){
                errorList.put(tbStudent.getPhone(), e.getMessage());
                continue;
            }
            if (existingPhones.contains(tbStudent.getPhone())) {
                errorList.put(tbStudent.getPhone(), "手机号已存在");
                continue;
            }

            if (ObjectUtils.isNotEmpty(tbStudent.getIdentityCard()) && existingIdCards.contains(tbStudent.getIdentityCard())) {
                errorList.put(tbStudent.getPhone(), "身份证号码已存在");
                continue;
            }
            // 填充其他字段
            tbStudent.setStudentNumber(IdUtil.fastSimpleUUID());
            tbStudent.setCreateTime(DateUtils.getNowDate());
            tbStudent.setExamineStatus(1);
            tbStudent.setFrozenStatus(0);
            tbStudent.setHeadPortrait("https://image.xnszz.com/IMG_1280_1280@FuvEKIdCm5NN36gZN9gJhk2Ei0-p.jpg");
            tbStudent.setNickName("学员_" + IdUtils.fastSimpleUUID().substring(1, 8));
            tbStudent.setPasswordUnencrypted("Aa123456");
            tbStudent.setPassword(SecurityUtils.encryptPassword("Aa123456"));
            insertList.add(tbStudent);
        }

        if (!insertList.isEmpty()){
            try {
                int insertCount = tbStudentMapper.batchInsertStudents(insertList);
                successRow = insertCount;
            } catch (DuplicateKeyException e) {
                // 这里如果数据库唯一约束报错，需要拆开单条插入处理
                for (TbStudent student : insertList) {
                    try {
                        tbStudentMapper.insertTbStudent(student);
                        successRow++;
                    } catch (DuplicateKeyException ex) {
                        if (ex.getMessage().contains("identity_card")) {
                            errorList.put(student.getPhone(), "手机号或身份证号码已存在，导入Excel中可能有重复数据");
                        }
                        if (ex.getMessage().contains("phone")) {
                            errorList.put(student.getPhone(), "手机号或身份证号码已存在，导入Excel中可能有重复数据");
                        }
                    } catch (Exception ex) {
                        errorList.put(student.getPhone(), "导入数据库失败");
                    }
                }
            }
        }
        if (successRow>0) {
            String baseMessage = "导入成功" + successRow + "条数据, 失败" + errorList.size() + "条数据";
            if (!errorList.isEmpty()) {
                List<String> failedInfoStrings = new ArrayList<>();
                for (Map.Entry<String, String> entry : errorList.entrySet()) {
                    failedInfoStrings.add("联系方式："+entry.getKey() + "（原因：" + entry.getValue() + "）<br>");
                }
                baseMessage += ", 失败信息：<br>" + String.join(" ", failedInfoStrings);
            }
            return baseMessage;
        } else {
            String message = "无数据导入, 失败" + errorList.size() + "条数据";
            if (!errorList.isEmpty()) {
                List<String> failedInfoStrings = new ArrayList<>();
                for (Map.Entry<String, String> entry : errorList.entrySet()) {
                    failedInfoStrings.add("联系方式："+entry.getKey() + "（原因：" + entry.getValue() + "）<br>");
                }
                message += ", 失败信息：<br>" + String.join(" ", failedInfoStrings);
            }
            return message;
        }
    }

    /**
     * 新增学员
     *
     * @param tbStudent 学员
     * @return 结果
     */
    @Override
    public int insertTbStudent(TbStudent tbStudent) {
        checkStudent(tbStudent);
        tbStudent.setCreateTime(DateUtils.getNowDate());
        tbStudent.setDelFlag(0);
        tbStudent.setExamineStatus(1);
        tbStudent.setStudentNumber(IdUtils.fastSimpleUUID());
        if (StringUtils.isEmpty(tbStudent.getHeadPortrait())){
            tbStudent.setHeadPortrait("https://image.xnszz.com/IMG_1280_1280@FuvEKIdCm5NN36gZN9gJhk2Ei0-p.jpg");
        }
        if (StringUtils.isEmpty(tbStudent.getNickName())){
            tbStudent.setNickName("学员_" + IdUtils.fastSimpleUUID().substring(1, 8));
        }

        TbStudent studentPhone = tbStudentMapper.selectTbStudentBy(tbStudent.getPhone(), null);
        if (ObjectUtils.isNotEmpty(studentPhone)){
            throw new ServiceException("新增失败，手机号码已存在。");
        }
        //身份证号不是必填，有了再校验
        if (ObjectUtils.isNotEmpty(tbStudent.getIdentityCard())){
            TbStudent studentId = tbStudentMapper.selectTbStudentBy(null, tbStudent.getIdentityCard());
            if (ObjectUtils.isNotEmpty(studentId)){
                throw new ServiceException("新增失败，身份证号码已存在。");
            }
        }
        if (tbStudent.getExamineStatus()==1&&StringUtils.isNotEmpty(tbStudent.getIdentityCard())){
            //审核通过并且身份证号不为空,设置默认密码
            tbStudent.setPasswordUnencrypted("Aa123456");
            tbStudent.setPassword(SecurityUtils.encryptPassword("Aa123456"));
        }
        return tbStudentMapper.insertTbStudent(tbStudent);

    }

    private void checkStudent(TbStudent tbStudent) {
        //校验姓名、性别、出生日期、手机电话、身份证号、身份证国徽面、身份证人像面、毕业证书不能为空
        if (StringUtils.isEmpty(tbStudent.getStudentName())||tbStudent.getSex()==null||StringUtils.isEmpty(tbStudent.getBirthday())||StringUtils.isEmpty(tbStudent.getPhone())||StringUtils.isEmpty(tbStudent.getIdentityCard())||StringUtils.isEmpty(tbStudent.getIdentityCardBadge())||StringUtils.isEmpty(tbStudent.getIdentityCardPortrait())||StringUtils.isEmpty(tbStudent.getGraduationCertificate())){
            throw new ServiceException("学员信息不完整，请填写完整。");
        }
    }

    private void checkImportStudent(TbStudent tbStudent) {
        //校验姓名、性别、出生日期、手机电话、身份证号、身份证国徽面、身份证人像面、毕业证书不能为空
        if (StringUtils.isEmpty(tbStudent.getStudentName())||tbStudent.getSex()==null||StringUtils.isEmpty(tbStudent.getBirthday())||StringUtils.isEmpty(tbStudent.getPhone())||StringUtils.isEmpty(tbStudent.getIdentityCard())){
            throw new ServiceException("学员信息不完整，请填写完整。");
        }
        //校验出生日期、毕业时间格式是否是2021-01-01格式
        if (!DateUtils.isValidDate(tbStudent.getBirthday())){
            throw new ServiceException("出生日期格式错误，请填写2025-01-01格式。");
        }
        if (StringUtils.isNotEmpty(tbStudent.getGraduationTime())){
            if (!DateUtils.isValidDate(tbStudent.getGraduationTime())){
                throw new ServiceException("毕业时间格式错误，请填写2025-01-01格式。");
            }
        }
    }

    /**
     * 修改学员
     *
     * @param tbStudent 学员
     * @return 结果
     */
    @Override
    public int updateTbStudent(TbStudent tbStudent) {
        checkStudent(tbStudent);
        tbStudent.setUpdateTime(DateUtils.getNowDate());
        TbStudent tbStudent1 = tbStudentMapper.selectTbStudentByStudentId(tbStudent.getStudentId());
        if (ObjectUtils.isNotEmpty(tbStudent1)&&!tbStudent1.getPhone().equals(tbStudent.getPhone())){
            //手机号改变了，校验手机号是否已存在
            TbStudent studentPhone = tbStudentMapper.selectTbStudentBy(tbStudent.getPhone(), null);
            if (ObjectUtils.isNotEmpty(studentPhone)){
                throw new ServiceException("修改失败，您修改的手机号码已存在。");
            }
        }
        //身份证号不是必填，有了再校验
        if (ObjectUtils.isNotEmpty(tbStudent.getIdentityCard())){
            if (ObjectUtils.isNotEmpty(tbStudent1)&&!tbStudent.getIdentityCard().equals(tbStudent1.getIdentityCard())){
                TbStudent studentId = tbStudentMapper.selectTbStudentBy(null, tbStudent.getIdentityCard());
                if (ObjectUtils.isNotEmpty(studentId)){
                    throw new ServiceException("修改失败，您修改的身份证号码已存在。");
                }
            }
        }
        if (tbStudent.getExamineStatus()==1&&StringUtils.isEmpty(tbStudent.getPassword())){
            //审核通过并且没有密码,设置默认密码
            tbStudent.setPasswordUnencrypted("Aa123456");
            tbStudent.setPassword(SecurityUtils.encryptPassword("Aa123456"));
        }
        return tbStudentMapper.updateTbStudent(tbStudent);
    }

    /**
     * 批量删除学员
     *
     * @param studentIds 需要删除的学员主键
     * @return 结果
     */
    @Override
    public int deleteTbStudentByStudentIds(Long[] studentIds) {
        return tbStudentMapper.deleteTbStudentByStudentIds(studentIds);
    }

    /**
     * 删除学员信息
     *
     * @param studentId 学员主键
     * @return 结果
     */
    @Override
    public int deleteTbStudentByStudentId(Long studentId) {
        return tbStudentMapper.deleteTbStudentByStudentId(studentId);
    }

    /**
     * 学员认证
     *
     * @param studentDTO
     * @return ok
     */
    @Override
    public AjaxResult authenticationStudent(StudentDTO studentDTO) {
        TbStudent phone = tbStudentMapper.selectTbStudentBy(studentDTO.getPhone(), null);
        if (phone == null) {
            return AjaxResult.error("手机号：" + studentDTO.getPhone() + "未注册，请输入正确的手机号");
        }
        if (Objects.equals(phone.getExamineStatus(), 1)){
            return AjaxResult.error("手机号：" + studentDTO.getPhone() + "已认证，请勿重复认证");
        }
        TbStudent tbStudent = new TbStudent();
        tbStudent.setStudentId(studentDTO.getStudentId());
        tbStudent.setStudentName(studentDTO.getStudentName());
        tbStudent.setSex(studentDTO.getSex());
        tbStudent.setBirthday(DateUtil.parse(studentDTO.getBirthday(), "yyyy-MM-dd").toString("yyyy-MM-dd"));
        tbStudent.setPhone(studentDTO.getPhone());
        tbStudent.setIdentityCard(studentDTO.getIdentityCard());
        tbStudent.setIdentityCardBadge(studentDTO.getIdentityCardBadge());
        tbStudent.setIdentityCardPortrait(studentDTO.getIdentityCardPortrait());
        tbStudent.setGraduationCertificate(studentDTO.getGraduationCertificate());

        tbStudent.setExamineStatus(0);
        tbStudentMapper.updateTbStudent(tbStudent);
        return AjaxResult.success();
    }

    /**
     * 扫码登陆轮询
     *
     * @param studentDTO 参数
     * @return 结果
     */
    @Override
    public AjaxResult userCodeLogin(StudentDTO studentDTO) {
        String loginUuid = studentDTO.getScanUuid();

        String redisKey = CacheConstants.CODE_LOGIN_TOKEN_KEY + loginUuid;
        if (!redisCache.hasKey(redisKey)) {
            throw new ServiceException("扫码未授权");
        }

        String gzhOpenId = redisCache.getCacheObject(redisKey).toString();

        // 查询用户信息
        TbStudent tbStudent = tbStudentMapper.selectTbStudentByGzhOpenId(gzhOpenId);
        if (ObjectUtils.isEmpty(tbStudent)) {
            // 新增用户
            TbStudent insertStudent = new TbStudent();
            insertStudent.setGzhOpenId(gzhOpenId);
            insertStudent.setSex(2);
            insertStudent.setStudentNumber(IdUtils.fastSimpleUUID());
            insertStudent.setCreateTime(DateUtils.getNowDate());
            insertStudent.setExamineStatus(3);
            insertStudent.setFrozenStatus(0);
            insertStudent.setHeadPortrait("https://image.xnszz.com/IMG_1280_1280@FuvEKIdCm5NN36gZN9gJhk2Ei0-p.jpg");
            insertStudent.setNickName("学员_" + IdUtils.fastSimpleUUID().substring(1, 8));

            tbStudentMapper.insertTbStudent(insertStudent);
        } else {
            if (tbStudent.getFrozenStatus() == 1) {
                return AjaxResult.error("用户已被冻结，请联系管理员！！！");
            }
            // 登录成功
            userLoginSuccess(tbStudent, 4);
        }
        redisCache.deleteObject(redisKey);
        return AjaxResult.success(tbStudentMapper.selectTbStudentByGzhOpenId(gzhOpenId));

    }

    /**
     * 手机号登录
     *
     * @param studentDTO 参数
     * @return 结果
     */
    @Override
    public AjaxResult userPhoneLogin(StudentDTO studentDTO) {
        String phone = studentDTO.getPhone();
        String smsCode = studentDTO.getSmsCode();
        String uuid = studentDTO.getUuid();
        String code = studentDTO.getCode();

        // 校验验证码
        // if (StringUtils.isNotBlank(uuid)) {
        //     // redis缓存key
        //     String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
        //     // 验证码值
        //     String captcha = redisCache.getCacheObject(verifyKey);
        //     // 移除
        //     redisCache.deleteObject(verifyKey);
        //     if (captcha == null) {
        //         // throw new ServiceException(ServiceResponseEnum.CAPTCHA_EXPIRE);
        //         return AjaxResult.error("图形验证码失效");
        //     }
        //
        //     if (!code.equalsIgnoreCase(captcha)) {
        //         // throw new ServiceException(ServiceResponseEnum.CAPTCHA_ERROR);
        //         return AjaxResult.error("图形验证码错误");
        //     }
        // }

        // 校验短信验证码
        // if (StringUtils.isNotBlank(smsCode)) {
        //     String checkSmsCode = smsCodeService.checkSmsCode(phone, smsCode, 1);
        //     if (!"SUCCESS".equals(checkSmsCode)) {
        //         // throw new ServiceException(ServiceResponseEnum.SMSCODE_ERROR);
        //         return AjaxResult.error(checkSmsCode);
        //     }
        // }

        // 查询用户信息
        TbStudent student = tbStudentMapper.selectTbStudentBy(phone, null);
        if (ObjectUtils.isEmpty(student)) {
            // 新增用户
            TbStudent insertStudent = new TbStudent();
            insertStudent.setPhone(phone);
            insertStudent.setSex(2);// 默认为未知，也就是空
            insertStudent.setStudentNumber(IdUtils.fastSimpleUUID());
            insertStudent.setCreateTime(DateUtils.getNowDate());
            insertStudent.setExamineStatus(3);
            insertStudent.setFrozenStatus(0);
            insertStudent.setHeadPortrait("https://image.xnszz.com/IMG_1280_1280@FuvEKIdCm5NN36gZN9gJhk2Ei0-p.jpg");
            insertStudent.setNickName("学员_" + IdUtils.fastSimpleUUID().substring(1, 8));

            tbStudentMapper.insertTbStudent(insertStudent);
        } else {
            if (student.getFrozenStatus() == 1) {
                return AjaxResult.error("用户已被冻结，请联系管理员！！！");
            }
            // 登录成功
            userLoginSuccess(student, 1);
        }
        return AjaxResult.success(tbStudentMapper.selectTbStudentBy(phone, null));
    }

    /**
     * 身份证号码登录
     *
     * @param studentDTO 参数
     * @return 结果
     */
    @Override
    public AjaxResult userIdentityCardLogin(StudentDTO studentDTO) {
        String identityCard = studentDTO.getIdentityCard();
        String passwordUnencrypted = studentDTO.getPasswordUnencrypted();

        // 查询用户信息
        TbStudent student = tbStudentMapper.selectTbStudentBy(null, identityCard);
        if (ObjectUtils.isEmpty(student)) {
            return AjaxResult.error("用户不存在，请用手机号登录后填写身份证号");
        } else {
            //查看账号是否审核，没审核通过是没有密码的，提示未审核
            if (student.getExamineStatus() != 1) {
                return AjaxResult.error("用户未审核通过，请联系管理员！！！");
            }
            // 账号是否设置密码，密码校验
            if (StringUtils.isBlank(student.getPassword()) || !SecurityUtils.matchesPassword(passwordUnencrypted, student.getPassword())) {
                return AjaxResult.error("账号或密码错误");
            } else {
                if (student.getFrozenStatus() == 1) {
                    return AjaxResult.error("用户已被冻结，请联系管理员！！！");
                }
                // 登录成功
                userLoginSuccess(student, 3);
            }

        }
        return AjaxResult.success(tbStudentMapper.selectTbStudentBy(null, identityCard));
    }

    /**
     * 用户登录成功
     *
     * @param userInfo  用户
     * @param loginType （0-默认，1-手机号，2-微信，3-身份证号，4-公众号扫码）
     */
    public void userLoginSuccess(TbStudent userInfo, Integer loginType) {
        // 登录标识
        String loginToken = IdUtils.getUserLoginToken();
        userInfo.setLoginToken(loginToken);
        userInfo.setLoginType(loginType);


        String redisKey = CacheConstants.PC_LOGIN_TOKEN_KEY + loginToken;
        String redisValue = RSAUtils.publicEncrypt(userInfo.getStudentNumber());

        redisCache.setCacheObject(redisKey, redisValue, 3, TimeUnit.DAYS);

        userInfo.setLoginTokenEncrypt(RSAUtils.publicEncrypt(loginToken));

        tbStudentMapper.updateTbStudent(userInfo);
    }

    /**
     * 找回密码
     *
     * @param studentDTO 参数
     * @return 结果
     */
    @Override
    public AjaxResult userRetrievePassword(StudentDTO studentDTO) {
        String phone = studentDTO.getPhone();
        String uuid = studentDTO.getUuid();
        String code = studentDTO.getCode();
        String identityCard = studentDTO.getIdentityCard();
        String passwordUnencrypted = studentDTO.getPasswordUnencrypted();
        String passwordUnencryptedConfirm = studentDTO.getPasswordUnencryptedConfirm();

        if (!passwordUnencrypted.equals(passwordUnencryptedConfirm)) {
            return AjaxResult.error("两次密码输入不正确");
        }

        // 校验验证码
        // if (StringUtils.isNotBlank(uuid)) {
        //     // redis缓存key
        //     String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
        //     // 验证码值
        //     String captcha = redisCache.getCacheObject(verifyKey);
        //     // 移除
        //     redisCache.deleteObject(verifyKey);
        //     if (captcha == null) {
        //         return AjaxResult.error("图形验证码失效");
        //     }
        //
        //     if (!code.equalsIgnoreCase(captcha)) {
        //         return AjaxResult.error("图形验证码错误");
        //     }
        // }

        // 查询用户信息
        TbStudent student = tbStudentMapper.selectTbStudentBy(phone, identityCard);
        if (ObjectUtils.isEmpty(student)) {
            return AjaxResult.error("用户不存在，请用手机号登录后填写身份证号");
        } else {
            if (student.getFrozenStatus() == 1) {
                return AjaxResult.error("用户已被冻结，请联系管理员！！！");
            }
            // 修改
            TbStudent updateStudent = new TbStudent();
            updateStudent.setStudentId(student.getStudentId());
            updateStudent.setPassword(SecurityUtils.encryptPassword(passwordUnencrypted));
            updateStudent.setPasswordUnencrypted(passwordUnencrypted);
            tbStudentMapper.updateTbStudent(updateStudent);
        }
        return AjaxResult.success();
    }

    /**
     * 查询学员
     *
     * @param openId openId
     * @return 学员
     */
    @Override
    public TbStudent selectTbStudentByGzhOpenId(String openId) {
        return tbStudentMapper.selectTbStudentByGzhOpenId(openId);
    }

    /**
     * 用户修改个人资料
     *
     * @param studentDTO
     * @return ok
     */
    @Override
    public AjaxResult updateMemberInfo(StudentDTO studentDTO) {
        String phone = studentDTO.getPhone();
        String smsCode = studentDTO.getSmsCode();

        // 校验短信验证码
        // if (StringUtils.isNotBlank(smsCode)) {
        //     String checkSmsCode = smsCodeService.checkSmsCode(phone, smsCode, 2);
        //     if (!"SUCCESS".equals(checkSmsCode)) {
        //         // throw new ServiceException(ServiceResponseEnum.SMSCODE_ERROR);
        //         return AjaxResult.error(checkSmsCode);
        //     }
        // }

        TbStudent student = new TbStudent();
        student.setStudentId(studentDTO.getMemberUserId());
        student.setStudentName(studentDTO.getStudentName());
        student.setHeadPortrait(studentDTO.getHeadPortrait());
        student.setIdentityCard(studentDTO.getIdentityCard());
        student.setSex(studentDTO.getSex());
        student.setEducation(studentDTO.getEducation());
        student.setGraduationSchool(studentDTO.getGraduationSchool());
        student.setGraduationTime(studentDTO.getGraduationTime());
        student.setNickName(studentDTO.getNickName());
        student.setPhone(studentDTO.getPhone());
        student.setUpdateTime(DateUtils.getNowDate());
        tbStudentMapper.updateTbStudent(student);
        return AjaxResult.success();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JSONObject memberUserLogin(MemberUserLoginDTO memberUserLoginDTO) {
        JSONObject result = new JSONObject();

        String loginCode = memberUserLoginDTO.getLoginCode();
        String phoneCode = memberUserLoginDTO.getPhoneCode();

        // 微信授权获取openId
//        String openId = loginCode;
        Map<String, String> map = weiXinXcxMemberUtils.getWebAuthorizeInfoMap(loginCode);

        if (CollectionUtils.isEmpty(map)) {
            throw new ServiceException(ServiceResponseEnum.MINIPROGRAM_AUTHORIZE_ERR);
        }

        String openId = map.get("openid");
        String unionId = map.get("unionId");
        if (StringUtils.isBlank(openId)) {
            throw new ServiceException(ServiceResponseEnum.MINIPROGRAM_AUTHORIZE_ERR);
        }
      /*  if (StringUtils.isBlank(unionId)) {
            throw new ServiceException(ServiceResponseEnum.MINIPROGRAM_AUTHORIZE_ERR);
        }*/

        // 微信授权获取手机号
        String phoneNumber = weiXinXcxMemberUtils.getUserPhoneNumber(phoneCode);
        if (StringUtils.isBlank(phoneNumber)) {
            throw new ServiceException(ServiceResponseEnum.MINIPROGRAM_AUTHORIZE_PHONE_ERR);
        }

        TbStudent tbStudent = null;
        // 查询用户信息
        tbStudent = tbStudentMapper.selectTbStudentBy(phoneNumber, null);
        if (StringUtils.isNull(tbStudent)) {
            //如果根据手机号查询不到 则用unionId去查询
            tbStudent = tbStudentMapper.getByUnionId(unionId);
        }

        if (ObjectUtils.isNotEmpty(tbStudent)) {

            // 登录成功
            tbStudent.setOpenId(openId);
            tbStudent.setPhone(phoneNumber);
            tbStudent.setUnionId(unionId);
            tbStudent.setLoginType(2);
            tbStudentMapper.updateTbStudent(tbStudent);
            result.put("AuthToken", tbStudent.getStudentId());
        } else {
            // 新用户注册
            TbStudent student = new TbStudent();
            student.setOpenId(openId);
            student.setPhone(phoneNumber);
            student.setUnionId(unionId);

            student.setSex(0);
            student.setUnionId(unionId);
            student.setStudentNumber(IdUtils.fastSimpleUUID());
            student.setExamineStatus(3);
            student.setFrozenStatus(0);
            String headPortrait = StringUtils.isNotEmpty(weiXinXcxMemberConfig.getAvatarUrl()) ? weiXinXcxMemberConfig.getAvatarUrl() : "https://image.xnszz.com/IMG_1280_1280@FuvEKIdCm5NN36gZN9gJhk2Ei0-p.jpg";
            student.setHeadPortrait(headPortrait);
            student.setNickName("学员_" + IdUtils.fastSimpleUUID().substring(1, 8));

            student.setCreateTime(DateUtils.getNowDate());
            student.setCreateBy("小程序授权");
            student.setDelFlag(0);

            tbStudentMapper.insertTbStudent(student);
            // 登录成功
            result.put("AuthToken", student.getStudentId());
        }
        return result;
    }

    @Override
    public JSONObject memberUserRegister(MemberUserLoginDTO memberUserLoginDTO) {
        JSONObject result = new JSONObject();

        String loginCode = memberUserLoginDTO.getLoginCode();
        String phoneCode = memberUserLoginDTO.getPhoneCode();
        String avatarUrl = memberUserLoginDTO.getAvatarUrl();
        String nickName = memberUserLoginDTO.getNickName();

        // 微信授权获取openId
//        String openId = loginCode;
        Map<String, String> map = weiXinXcxMemberUtils.getWebAuthorizeInfoMap(loginCode);

        if (CollectionUtils.isEmpty(map)) {
            throw new ServiceException(ServiceResponseEnum.MINIPROGRAM_AUTHORIZE_ERR);
        }

        String openId = map.get("openid");
        String unionId = map.get("unionId");
        if (StringUtils.isBlank(openId)) {
            throw new ServiceException(ServiceResponseEnum.MINIPROGRAM_AUTHORIZE_ERR);
        }
        if (StringUtils.isBlank(unionId)) {
            throw new ServiceException(ServiceResponseEnum.MINIPROGRAM_AUTHORIZE_ERR);
        }

        // 微信授权获取手机号
        String phoneNumber = weiXinXcxMemberUtils.getUserPhoneNumber(phoneCode);
        if (StringUtils.isBlank(phoneNumber)) {
            throw new ServiceException(ServiceResponseEnum.MINIPROGRAM_AUTHORIZE_PHONE_ERR);
        }

        // 查询用户信息
        TbStudent tbStudent = tbStudentMapper.selectTbStudentBy(phoneNumber, null);
        if (ObjectUtils.isNotEmpty(tbStudent)) {

            // 登录成功
            tbStudent.setOpenId(openId);
            tbStudent.setPhone(phoneNumber);
            result.put("AuthToken", tbStudent.getStudentId());
        } else {
            // 新用户注册
            TbStudent student = new TbStudent();
            student.setOpenId(openId);
            student.setPhone(phoneNumber);

            student.setSex(0);
            student.setStudentNumber(IdUtils.fastSimpleUUID());
            student.setExamineStatus(3);
            student.setFrozenStatus(0);
            student.setHeadPortrait("https://image.xnszz.com/IMG_1280_1280@FuvEKIdCm5NN36gZN9gJhk2Ei0-p.jpg");
            student.setNickName("学员_" + IdUtils.fastSimpleUUID().substring(1, 8));

            student.setCreateTime(DateUtils.getNowDate());
            student.setCreateBy("小程序授权");
            student.setDelFlag(0);

            tbStudentMapper.insertTbStudent(student);
            // 登录成功
            result.put("AuthToken", student.getStudentId());
        }
        return result;
    }

    @Override
    public int editPassword(TbStudent tbStudent) {
        tbStudent.setUpdateTime(DateUtils.getNowDate());
//        //根据studentId查信息
//        TbStudent studentInfo = tbStudentMapper.selectTbStudentByStudentId(tbStudent.getStudentId());
//        //校验老密码是否正确
//        if (studentInfo.getPasswordUnencrypted().equals(tbStudent.getOldPassword())) {
//            tbStudent.setPasswordUnencrypted(tbStudent.getPassword());
//            tbStudent.setPassword(SecurityUtils.encryptPassword(tbStudent.getPassword()));
//        }
        tbStudent.setPasswordUnencrypted(tbStudent.getPassword());
        tbStudent.setPassword(SecurityUtils.encryptPassword(tbStudent.getPassword()));
        return tbStudentMapper.updateTbStudent(tbStudent);
    }

    @Override
    public String createQrCode(String memberUserId) {
        if (StringUtils.isBlank(memberUserId)){
            return "";
        }
        // 查询用户信息
        TbStudent tbMemberUser = tbStudentMapper.selectTbStudentByStudentId(Long.valueOf(memberUserId));
        if (ObjectUtils.isNotEmpty(tbMemberUser)){
            String qrCode = tbMemberUser.getInvitationCodeImg();//获取邀请码图
            if (StringUtils.isNotBlank(qrCode)){
                return qrCode;
            }

        }
        String userAvatar = "";
        String qrCode = "";
        Image image = null;
        if (ObjectUtils.isNotEmpty(tbMemberUser)){

            // 生成二维码
            String key = "qr_"  + IdUtils.fastSimpleUUID() + ".png";

            qrCode = this.getQRCode(memberUserId, key);

            tbMemberUser.setInvitationCodeImg(qrCode);
            tbMemberUser.setUpdateTime(DateUtils.getNowDate());
            tbStudentMapper.updateTbStudent(tbMemberUser);
        }

        return qrCode;
    }

    /**
     * 获取小程序码
     *
     * @param memberUserId 用户id
     * @param key key
     * @return 图片链接
     */
    public String getQRCode(String memberUserId, String key){
        String qrCodeUrl = "";
        try {
            //获取token
            String accessToken = this.getAccessToken();
            String codeUrl = "https://api.weixin.qq.com/wxa/getwxacode?access_token="+ accessToken;

            String path = weiXinConfig.getWxPath()+memberUserId;
            //post参数
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("path", path);
            Map<String, Object> lineColor = new HashMap<>();
            lineColor.put("r", 4);
            lineColor.put("g", 157);
            lineColor.put("b", 150);
            jsonObject.put("line_color", lineColor);
            jsonObject.put("env_version", "trial");
            String params = jsonObject.toString();

            URL url = new URL(codeUrl);
            HttpURLConnection httpUrlConnection = (HttpURLConnection) url.openConnection();
            // 提交模式
            httpUrlConnection.setRequestMethod("POST");
            // 发送POST请求必须设置如下两行
            httpUrlConnection.setDoOutput(true);
            httpUrlConnection.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            PrintWriter printWriter = new PrintWriter(httpUrlConnection.getOutputStream());
            printWriter.write(params);
            printWriter.flush();
            //获取数据
            BufferedInputStream bis = new BufferedInputStream(httpUrlConnection.getInputStream());
            //文件上传,返回小程序码url
            qrCodeUrl = new ImgUpload().uploadStream(bis, key);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return qrCodeUrl;
    }


    /**
     * 获取access_token
     *
     * @return access_token
     */
    public String getAccessToken() {
        JSONObject jsonObject = new JSONObject();
        String accessToken = "";
        String redisKey = "xcx:access_token:";
        try {
            if (redisCache.hasKey(redisKey)) {
                return redisCache.getCacheObject(redisKey).toString();
            }
            String requestUrl = "https://api.weixin.qq.com/cgi-bin/token" +
                    "?grant_type=client_credential" +
                    "&appid="+weiXinConfig.getAppId() +
                    "&secret="+weiXinConfig.getAppSecret();
            String result = HttpUtil.get(requestUrl);

            jsonObject = JSONObject.parseObject(result);
            // 有效期(s)
            Integer expiresIn = 0;
            if (ObjectUtils.isNotEmpty(jsonObject)) {
                accessToken = jsonObject.getString("access_token");
                expiresIn = jsonObject.getInteger("expires_in");
            }
            if (StringUtils.isBlank(accessToken)){
                System.out.println("小程序获取access_token失败 -> {"+ DateUtils.getTime()+": "+jsonObject+"}");
            }else {
                redisCache.setCacheObject(redisKey, accessToken, expiresIn, SECONDS);
            }
        } catch (Exception e) {
            System.out.println("小程序获取access_token异常 -> {"+DateUtils.getTime()+": "+e.getMessage()+"}");
        }
        return accessToken;
    }

}
