微信公众平台(服务号)扫码注册登录

该文章已生成可运行项目,

开发主要流程:

首先,我们需要注册获取一个公众号(服务号);

取到公众号之后我们做如下配置;

  1. 获取公众号开发信息;
  2. 设置IP白名单(需要在外网可访问到);
  3. 设置服务器配置(可能需要等待几天);
    填写验证及回调地址,该地址保存时会进行验证,扫码后回调该地址,再进行验证可获取用户信息等;
  4. 在 「设置与开发 / 接口权限 / 网页授权」 中,找到 网页授权 网页授权获取用户基本信息 进行修改,设置 网页授权域名;域名需要在外网可以访问到
    注意:网页授权域名最多可以设置 2个。

 开发过程中,我们可以使用测试号,配置跟上面差不多;

下面直接上代码:

Constant:
import java.util.Arrays;
import java.util.List;

/**
 * 微信扫码登录常量地址
 *
 * @author yl
 * @date 2024-05-09 10:30
 */

public interface WeChatConstant {


    /**
     * 创建二维码ticket
     */
    String QRCODE_TICKET_URI = "https://api.weixin.qq.com/cgi-bin/qrcode/create";

    /**
     * 获取tokenURI
     */
    String TOKEN_URI = "https://api.weixin.qq.com/cgi-bin/token";

    /**
     * 获取用户信息URI
     */
    String USER_INFO_URI = "https://api.weixin.qq.com/cgi-bin/user/info";

    /**
     * 调用微信公众平台的接口,发送客服消息
     */
    String SEND_MESSAGE_URI = "https://api.weixin.qq.com/cgi-bin/message/custom/send";

}
Util:
import cn.hutool.extra.spring.SpringUtil;
import com.jeeplus.channel.domain.SysWechatConfig;
import com.jeeplus.channel.service.SysWechatConfigService;
import com.jeeplus.wechat.constant.WeChatConstant;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * 微信公众号工具类
 * @author yl
 */
@Slf4j
public class WxChatUtil {

    /**
     *  获取accessToken
     * @return
     */
    public static String getAccessToken() {
        SysWechatConfig config = SpringUtil.getBean(SysWechatConfigService.class).getById("1");

        Random r = new Random();
        StringBuilder rs = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            rs.append(r.nextInt(10));
        }

        String accessToken = null;
        //根据appid和appsecret获取access_token
        String accessTokenUrl = WeChatConstant.TOKEN_URI +
                "?appid=" + config.getAppId() +
                "&secret=" + config.getAppSecret() +
                "&grant_type=client_credential";
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> responseEntity = restTemplate.getForEntity(accessTokenUrl, String.class);
        String responseBody = responseEntity.getBody();

        if (responseBody != null) {
            // 解析JSON响应
            JSONObject json = new JSONObject(responseBody);
            accessToken = json.getString("access_token");
        }

        return accessToken;
    }


    /**
     * 向用户发送提醒消息
     * @param content
     * @param openId
     * @param token
     */
    public static void sendReminderMessage(String content, String openId, String token) {
        // 构造消息的参数

        // 调用微信公众平台的接口,发送客服消息
        String apiUrl = WeChatConstant.SEND_MESSAGE_URI + "?access_token=" + token;

        Map<String, Object> requestBody = new HashMap<>();
        requestBody.put("touser", openId);
        requestBody.put("msgtype", "text");
        requestBody.put("text", new HashMap<String, String>() {{
            put("content", content);
        }});

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(requestBody, headers);

        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(apiUrl, requestEntity, String.class);

        if (responseEntity.getStatusCode() == HttpStatus.OK) {
            // 客服消息发送成功
            log.info("客服消息发送成功");
        } else {
            // 客服消息发送失败
            log.info("客服消息发送失败");
        }
    }


    /**
     * 验证消息加密
     *
     * @param input
     * @return
     */
    public static String sha1(String input) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            byte[] digest = md.digest(input.getBytes());
            StringBuilder sb = new StringBuilder();
            for (byte b : digest) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }

}

 

Controller层:
import cn.hutool.extra.spring.SpringUtil;
import com.jeeplus.channel.domain.SysWechatConfig;
import com.jeeplus.channel.service.SysWechatConfigService;
import com.jeeplus.common.json.AjaxJson;
import com.jeeplus.sys.service.UserService;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.wechat.service.WeChatService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * @program: 微信公众号注册登录
 * @description: WeChatController
 * @author: yl
 * @create: 2024-05-09 10:39
 */
@Slf4j
@RestController
@Api(tags = "微信扫码登录")
@RequestMapping("/ai/wechat")
public class WeChatController {

    @Autowired
    private UserService userService;
    @Autowired
    private WeChatService weChatService;



    /**
     * pc点击微信登录,生成登录二维码
     *
     */
    @GetMapping("/qrcode")
    public Map<String,Object> generateQRCode() {
        return weChatService.generateQRCode();
    }


    /**
     * 验证签名,扫码后回调验证签名
     *
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping("checkSign")
    public String checkSign(HttpServletRequest request) throws Exception {
        return weChatService.checkSign(request);
    }


    /**
     * 将用户信息放到缓存中
     * @param nickname
     * @param avatar
     * @param openid
     * @param state
     * @param invitationCode
     * @return
     */
    @GetMapping("/setCache")
    @ApiOperation("将用户信息放到缓存中")
    public AjaxJson setCache(String nickname, String avatar, String openid, String state, String invitationCode) {
        return weChatService.setCache(nickname, avatar, openid, state, invitationCode);
    }


    /**
     * 查看是否过期
     * @return
     */
    @GetMapping("/isExpired")
    @ApiOperation("查看是否过期")
    public Boolean isExpired(String openid) {
        UserDTO user = userService.findByOpenid(openid);
        if (user == null) {
            return true;
        }
        return false;
    }


    /**
     * 根据二维码标识获取用户openId=>获取用户信息
     *
     * @param sceneId
     * @param roleId
     * @return
     */
    @GetMapping("/login")
    @ApiOperation("登录接口")
    public AjaxJson login(String sceneId, String roleId) {
        return weChatService.login(sceneId, roleId);
    }


    /**
     * 获取微信公众号配置信息
     * @return
     */
    @GetMapping("/getQrcodeImg")
    @ApiOperation("获取微信公众号配置信息")
    public AjaxJson getQrcodeImg () {
        SysWechatConfig config = SpringUtil.getBean(SysWechatConfigService.class).getById("1");
        return AjaxJson.success().put("data", config);
    }

}

Service层:

import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.http.HttpUtil;
import com.jeeplus.channel.domain.SysWechatConfig;
import com.jeeplus.channel.service.SysWechatConfigService;
import com.jeeplus.common.json.AjaxJson;
import com.jeeplus.common.redis.RedisUtils;
import com.jeeplus.common.utils.RequestUtils;
import com.jeeplus.common.utils.ResponseUtil;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.config.properties.JeePlusProperties;
import com.jeeplus.invitationcode.domain.SysUserInvitationCode;
import com.jeeplus.invitationcode.service.SysUserInvitationCodeService;
import com.jeeplus.security.jwt.TokenProvider;
import com.jeeplus.security.util.SecurityUtils;
import com.jeeplus.sys.constant.CacheNames;
import com.jeeplus.sys.domain.AiConfigInfo;
import com.jeeplus.sys.domain.AiIntegralDetailInfo;
import com.jeeplus.sys.domain.AiPersonalPointsInfo;
import com.jeeplus.sys.service.AiConfigInfoService;
import com.jeeplus.sys.service.AiIntegralDetailInfoService;
import com.jeeplus.sys.service.AiPersonalPointsInfoService;
import com.jeeplus.sys.service.UserService;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.wechat.constant.WeChatConstant;
import com.jeeplus.wechat.util.WxChatUtil;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @program: 微信扫码注册登录Service
 * @description:
 * @author: yl
 * @create: 2024-05-09 10:39
 */
@Slf4j
@Service
public class WeChatService {

    @Autowired
    private UserService userService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private SysUserInvitationCodeService sysUserInvitationCodeService;
    @Autowired
    private AiConfigInfoService aiConfigInfoService;
    @Autowired
    private AiPersonalPointsInfoService aiPersonalPointsInfoService;
    @Autowired
    private AiIntegralDetailInfoService aiIntegralDetailInfoService;

    /**
     * pc点击微信登录,生成登录二维码
     * @return
     */
    public Map<String,Object> generateQRCode() {

        Map<String,Object> map = new HashMap<String,Object>();

        String code_url = WeChatConstant.QRCODE_TICKET_URI + "?access_token=" + WxChatUtil.getAccessToken();
        try{
            //获取公众号的Token,自行实现,我是定任务获取,存到了数据库
            SysWechatConfig config = SpringUtil.getBean(SysWechatConfigService.class).getById("1");
            code_url = code_url.replace("TOKEN", config.getToken());
            String scene_id = (System.currentTimeMillis()+"").substring(0,10);
            JSONObject json = new JSONObject();
            json.put("expire_seconds", "36000");
            json.put("action_name", "QR_SCENE");
            JSONObject info = new JSONObject();
            JSONObject scen = new JSONObject();
            scen.put("scene_id", scene_id);
            info.put("scene", scen);
            json.put("action_info", info);
            String data = HttpUtil.post(code_url, json.toString());
            net.sf.json.JSONObject resp = net.sf.json.JSONObject.fromObject(data);
            System.out.println("data=="+data);
            map.put("data", resp);
            map.put("scene_id", scene_id);
            map.put("succ", "1");
        } catch(Exception e){
            map.put("succ", "0");
            e.printStackTrace();
        }
        return map;
    }


    /**
     * 验证微信消息
     * @param request
     * @return
     */
    public String checkSign(HttpServletRequest request) throws Exception {
        log.info("===========>checkSign");
        //获取微信请求参数
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        //参数排序。 token 就要换成自己实际写的 token
        SysWechatConfig config = SpringUtil.getBean(SysWechatConfigService.class).getById("1");
        String[] params = new String[]{timestamp, nonce, config.getToken()};
        Arrays.sort(params);
        //拼接
        String paramstr = params[0] + params[1] + params[2];
        //加密
        String mysignature = WxChatUtil.sha1(paramstr);
        //是否正确
        boolean signsuccess = mysignature.equalsIgnoreCase(signature);
        //逻辑处理
        if (signsuccess && echostr != null) {
            log.info("签名一致可以通过");
            //验证签名,接入服务器
            return echostr;
        } else {
            log.error("这不是微信发来的消息!!");
            //接入失败或已经接入成功后
            com.alibaba.fastjson.JSONObject jsonObject = callback(request);
            return jsonObject.toJSONString();
        }
    }

    /**
     * 回调方法
     *
     * @param request
     * @return
     * @throws Exception
     */
    public com.alibaba.fastjson.JSONObject callback(HttpServletRequest request) throws Exception {
        log.info("===========>callback");

        //request中有相应的信息,进行解析
        WxMpXmlMessage message = WxMpXmlMessage.fromXml(request.getInputStream());//获取消息流,并解析xml
        String messageType = message.getMsgType();                                //消息类型
        String messageEvent = message.getEvent();                                 //消息事件
        // openid
        String fromUser = message.getFromUser();                                  //发送者帐号
        String touser = message.getToUser();                                      //开发者微信号
        String text = message.getContent();                                       //文本消息  文本内容
        // 生成二维码时穿过的特殊参数
        String eventKey = message.getEventKey();                                  //二维码参数

        //if判断,判断查询
        com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject();
        if (messageType.equals("event")) {

            String token = WxChatUtil.getAccessToken();

            //从微信上中拉取用户信息
            String url = WeChatConstant.USER_INFO_URI + "?access_token=" + token + "&openid=" + fromUser + "&lang=zh_CN";
            String result = HttpUtil.get(url);
            jsonObject = com.alibaba.fastjson.JSONObject.parseObject(result);

            String openid = jsonObject.getString("openid");

            if (messageEvent.equals("SCAN")) {

                log.info("欢迎回来");
                //扫描二维码
                String content = "欢迎回来";
                WxChatUtil.sendReminderMessage(content, openid, token);
            }
            if (messageEvent.equals("subscribe")) {
                eventKey = eventKey.substring(8);
                System.out.println(eventKey);
                //关注
                log.info("感谢您的关注");
                SysWechatConfig config = SpringUtil.getBean(SysWechatConfigService.class).getById("1");
                String content = "<a href=\"" + config.getRedirectUri() + "?openid="+openid+"&state=" + eventKey + "\">点击确认登录</a>";

                WxChatUtil.sendReminderMessage(content, openid, token);

                return jsonObject;
            }
            if (messageEvent.equals("unsubscribe")) {
                // 删除用户积分数据
                UserDTO userDTO = userService.findByOpenid(fromUser);
                if (userDTO != null) {
                    RedisUtils.getInstance().delete("user:" + userDTO.getId() + ":points");
                    AiPersonalPointsInfo aiPersonalPoints = aiPersonalPointsInfoService.lambdaQuery()
                            .eq(AiPersonalPointsInfo::getUserId, userDTO.getId())
                            .eq(AiPersonalPointsInfo::getDelFlag, "0")
                            .one();
                    if (aiPersonalPoints != null) {
                        aiPersonalPointsInfoService.removeById(aiPersonalPoints.getId());
                    }
                }


                //取消关注,从数据库中删除用户信息
                userService.removeByOpenId(fromUser);

                return jsonObject;
            }

            // 扫码成功,存入缓存,有效期 5分钟
            redisUtils.set(CacheNames.SYS_WECHAT_CODE + "::" + eventKey, jsonObject, 5 * 60);
            return jsonObject;
        }
        return jsonObject;
    }


    /**
     * 将用户信息放到缓存中
     * @param nickname
     * @param avatar
     * @param openid
     * @param state
     * @param invitationCode
     * @return
     */
    public AjaxJson setCache(String nickname, String avatar, String openid, String state, String invitationCode) {
        // 判断邀请码是否有效
        if (StringUtils.isEmpty(invitationCode)) {
            return AjaxJson.error("邀请码不可为空");
        }
        SysUserInvitationCode userInvitationCode = (SysUserInvitationCode)RedisUtils.getInstance().get(CacheNames.SYS_INVITATION_CODE, invitationCode);
        if (userInvitationCode == null) {
            return AjaxJson.error("邀请码无效!");
        }

        // 从缓存中移除
        RedisUtils.getInstance().delete(CacheNames.SYS_INVITATION_CODE, invitationCode);

        // 更新邀请码状态
        userInvitationCode.setStatus("1");
        sysUserInvitationCodeService.saveOrUpdate(userInvitationCode);

        com.alibaba.fastjson.JSONObject jsonObject = new com.alibaba.fastjson.JSONObject();
        jsonObject.put("openid", openid);
        jsonObject.put("invitationUserId", userInvitationCode.getUserId());
        redisUtils.set(CacheNames.SYS_WECHAT_CODE + "::" + state, jsonObject, 60 * 5);

        WxChatUtil.sendReminderMessage("登录成功", openid, WxChatUtil.getAccessToken());

        return AjaxJson.success("设置成功!");
    }


    /**
     * 根据授权码获取访问令牌和用户的唯一标识
     *
     * @param code
     * @return
     */
    public String getOpenId(String code) {

        SysWechatConfig config = SpringUtil.getBean(SysWechatConfigService.class).getById("1");
        String appId = config.getAppId();
        String appSecret = config.getAppSecret();

        String accessTokenUrl = WeChatConstant.TOKEN_URI +
                "?appid=" + appId + "&secret=" + appSecret + "&code=" + code + "&grant_type=authorization_code";
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.getForEntity(accessTokenUrl, String.class);
        return response.getBody();
    }

    /**
     * 根据二维码标识获取用户openId=>获取用户信息
     * @param sceneId
     * @return
     */
    public AjaxJson login(String sceneId, String roleId) {
        com.alibaba.fastjson.JSONObject jsonObject = (com.alibaba.fastjson.JSONObject) RedisUtils.getInstance().get(CacheNames.SYS_WECHAT_CODE + "::" + sceneId);
        if (jsonObject == null) {
            return AjaxJson.error("未扫码成功!");
        } else {
            ResponseUtil responseUtil = new ResponseUtil();

            String nickname = jsonObject.getString("nickname");
            String openid = jsonObject.getString("openid");
            String invitationUserId = jsonObject.getString("invitationUserId");
            String userSource = jsonObject.getString("userSource");
            // 检查用户是否存在
            UserDTO user = userService.findByOpenid(openid);
            if (user == null) {
                // 创建新用户账号
                user = new UserDTO();
                user.setLoginName("IMMS_" + RandomUtil.randomNumbers(6));
                user.setPassword(SecurityUtils.encryptPassword("123456"));
                user.setOpenid(openid);
                user.setName(nickname);
                user.setInvitationUserId(invitationUserId);
                user.setUserSource(userSource);
//                user.setIsAdminPower("1");
                userService.saveOrUpdate(user);

                // 更新用户与角色关联
                if (StringUtils.isNotEmpty(roleId)) {
                    userService.insertUserRole(user.getId(), roleId);
                }

                // 插入绑定时间
                setBindTime(user.getId(), nickname);

                // 插入 用户积分/个人积分明细 数据
                setIntegral(user.getId());

            }

            String token = TokenProvider.createAccessToken(user.getLoginName(), user.getPassword());
            Authentication authentication = TokenProvider.getAuthentication(token);
            SecurityContextHolder.getContext().setAuthentication(authentication);
            responseUtil.add(TokenProvider.TOKEN, token);
            //更新登录信息
            updateUserLoginInfo(responseUtil, user, token);

            RedisUtils.getInstance().delete(CacheNames.SYS_WECHAT_CODE + "::" + sceneId);

            return AjaxJson.success().put("data", responseUtil.ok());
        }
    }

    /**
     * 插入绑定时间
     * @param userId
     */
    public void setBindTime(String userId, String nickname) {
        try {
            userService.setBindTime(userId, "0", nickname);
        } catch (Exception e) {
            log.info("绑定时间插入失败", e);
        }
    }


    /**
     * 插入用户积分数据
     * @param userId
     */
    public void setIntegral(String userId) {
        // 插入用户积分数据
        try {
            AiConfigInfo aiConfig = aiConfigInfoService.lambdaQuery()
                    .eq(AiConfigInfo::getConfigType, "register_reward")
                    .eq(AiConfigInfo::getConfigName, "state")
                    .one();
            if (aiConfig != null) {
                if ("1".equals(aiConfig.getConfigValue())) {
                    // 用户积分
                    AiPersonalPointsInfo aiPersonalPoints = new AiPersonalPointsInfo();

                    // 个人积分明细
                    AiIntegralDetailInfo detailInfo = new AiIntegralDetailInfo();

                    // 配置参数
                    AiConfigInfo aiConfig1 = aiConfigInfoService.lambdaQuery()
                            .eq(AiConfigInfo::getConfigType, "register_reward")
                            .eq(AiConfigInfo::getConfigName, "powers")
                            .one();

                    if (aiConfig1 != null) {
                        aiPersonalPoints.setValue(new BigDecimal(aiConfig1.getConfigValue()));
                        detailInfo.setValue(new BigDecimal(aiConfig1.getConfigValue()));
                    } else {
                        aiPersonalPoints.setValue(new BigDecimal(0));
                        detailInfo.setValue(new BigDecimal(0));
                    }
                    aiPersonalPoints.setUserId(userId);
                    aiPersonalPointsInfoService.saveOrUpdate(aiPersonalPoints);

                    detailInfo.setUserId(userId);
                    detailInfo.setOperationType("1");
                    detailInfo.setType("3");
                    detailInfo.setOccurrenceTime(new Date());
                    aiIntegralDetailInfoService.saveOrUpdate(detailInfo);

                    com.jeeplus.common.utils.RedisUtils.setAtomicValue("user:" + userId + ":points", new BigDecimal(aiConfig1.getConfigValue()).doubleValue());
                }
            }
        } catch (Exception e) {
            log.info("用户积分插入失败", e);
        }
    }


    /**
     * 更新用户登录信息
     * @param responseUtil
     * @param userDTO
     * @param token
     */
    public void updateUserLoginInfo(ResponseUtil responseUtil, UserDTO userDTO, String token) {

        String username = userDTO.getLoginName();
        redisUtils.set(CacheNames.USER_CACHE_TOKEN + username + ":" + token, token);
        redisUtils.expire(CacheNames.USER_CACHE_TOKEN + username + ":" + token, JeePlusProperties.newInstance().getEXPIRE_TIME());
        responseUtil.add("oldLoginDate", userDTO.getLoginDate());
        responseUtil.add("oldLoginIp", userDTO.getLoginIp());
        //更新登录日期
        userDTO.setLoginDate(new Date());
        userDTO.setLoginIp(ServletUtil.getClientIP(RequestUtils.getRequest()));
        userService.updateUserLoginInfo(userDTO);

    }
}

前端页面:

<template>
  <div>
    <div style="margin-top: 50px;text-align: center">

      <div style="position: relative;">
        <el-image :src="qrCodeImg" style="height: 200px;width: 200px;border-radius: 10px" fit="contain">
        </el-image>
        <div @click="getQrCode"
             v-if="isExpired"
          style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); display: flex; justify-content: center; align-items: center; color: white; font-size: 20px;"
        >
          二维码已过期
        </div>
      </div>
      <div style="margin-top: 30px;font-size: 18px;color: #709f95">
        请使用微信扫码登录/注册
      </div>
    </div>
  </div>
</template>

<script>
import loginService from '@/api/auth/loginService'
import userService from '@/api/sys/userService'

export default {
  // 微信登录
  name: 'weichatLogin',
  props: {
    roleId: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      isExpired: false,
      qrCodeImg: '',
      sceneId:'', //二维码带的参数,用来判断是那个用户扫码的
      qrCodeUrl: '',
      randomNum: '',
      pollingTimer: null,
      timerCount: 10 // 倒计时秒数
    }
  },
  created () {
    // 加载二维码
    console.log('二维码')
    this.getQrCode()
    this.qrCodeUrl = ''
  },
  mounted () {
    // alert(window.location.href.includes('code'))
  },
  methods: {
    // 获取二维码
    getQrCode () {
      this.timerCount = 10

      loginService.qrcode().then(({data}) => {
          if(data.succ === '1') {
            this.url = data.data.url
            this.sceneId = data.scene_id
            console.log('qrcode', data)

            this.timer = setInterval(this.getUserByScene, 2000)
            // 设置有效期为5分钟
            setTimeout(function() {
              this.isExpired = true
              // 取消定时器的执行
              window.clearInterval(this.timer)
              console.log("定时器已取消")
            }.bind(this), 5 * 60 * 1000);
            this.$nextTick(() => {
              this.isExpired = false
              this.qrCodeImg = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=' + data.data.ticket
            })
          }
      })
    },
    //根据 sceneId 轮询查询用户信息,判断用户是否登录成功
    async getUserByScene(){
      if(!this.sceneId) return
      const res = await loginService.wxlogin({sceneId: this.sceneId, roleId: this.roleId}).then(({data}) => {
        if (data.success) {

          window.clearInterval(this.timer)
          this.url = ''
          this.sceneId = ''
          // 登录成功,执行相应操作
          console.log('登录成功')
          this.$cookie.set('token', data.data.body.token)
          console.log('token', data.data.body.token)
          userService.getMenus().then(({data}) => {
            console.log('data', data)
            localStorage.setItem('routerList', JSON.stringify(data.routerList || '[]'))
            localStorage.setItem('allMenuList', JSON.stringify(data.aiMenuList || '[]'))
            localStorage.setItem('permissions', JSON.stringify(data.aiPermissions || '[]'))
            localStorage.setItem('dictList', JSON.stringify(data.dictList || '[]'))
            this.$emit('closeDialog')
          })
          this.$notify({
            title: '登录成功',
            // message: `欢迎回来!<br/>你上次的登录IP是 ${data.data.body.oldLoginIp},登录时间是 ${data.data.body.oldLoginDate}。`,
            dangerouslyUseHTMLString: true,
            duration: 3000,
            type: 'success'
          })
        }
      })
    }
  }
}
</script>

<style scoped>
::v-deep .el-input__inner{
  color:#fff;
}
#qrcode {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 200px; /* 设置QR码容器的高度 */
}
</style>

扫码后的回调页面:

<template>
  <div v-if="expired" class="wx">
    <div class="wx_box">
    <el-form ref="form" :model="form" class="login-form">
      <el-form-item class="password" prop="invitationCode"
                    :rules="[{ required: true, message: '请输入邀请码', trigger: 'blur' }]">
        <el-input v-model="form.invitationCode" placeholder="请输入邀请码" style="width: 90%; margin:30% auto 0 auto; display: block"></el-input>
      </el-form-item>
      <el-form-item style="text-align: center" class="login_button">
        <el-button round @click="login">登 录</el-button>
      </el-form-item>
    </el-form>
    </div>
  </div>
</template>

<script>

import loginService from '@/api/auth/loginService'

export default {
  data () {
    return {
      form: {
        nickname: '',
        avatar: '',
        openid: '',
        state: '',
        invitationCode: ''
      },
      expired: true
    }
  },
  created () {
  },
  mounted () {
    this.form = this.$route.query
    this.isExpired(this.form.openid)
  },
  methods: {
    isExpired (openid) {
      loginService.isExpired(openid).then(({data}) => {
        this.expired = data
        if (!this.expired) {
          this.$message.warning('登录信息已失效')
        }
      })
    },
    login () {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          // 将登录凭证存储到缓存中
          loginService.setCache(this.form).then(({data}) => {
            if (data.success) {
              this.closeWeChatPage()
            } else {
              this.$message.warning(data.msg)
            }
          })
        }
      })
    },
    // 在确认登录后关闭微信页面
    closeWeChatPage () {
      if (typeof WeixinJSBridge === 'undefined') {
        if (document.addEventListener) {
          document.addEventListener('WeixinJSBridgeReady', this.closePage, false)
        } else if (document.attachEvent) {
          document.attachEvent('WeixinJSBridgeReady', this.closePage)
          document.attachEvent('onWeixinJSBridgeReady', this.closePage)
        }
      } else {
        this.closePage()
      }
    },

    // 关闭当前窗口
    closePage () {
      // eslint-disable-next-line no-undef
      WeixinJSBridge.invoke('closeWindow', {}, function (res) {
        // 关闭窗口成功的回调函数
      })
    },
    reject () {
      this.closeWeChatPage()
    }
  }
}
</script>
<style scoped>
.wx{
  background: -webkit-linear-gradient(top, #b5e8c8 0%,#7cd6e3 100%);
  width: 100%;
  height: 100%;
  overflow: hidden;
}
.wx_box{
  background:rgba(255,255,255,0.9);
  border-radius: 12px;
  width: 92%;
  height: 92%;
  margin: 8% auto;
}

::v-deep .el-input__inner{
  border-radius: 8px;
  box-sizing: border-box;
  border: 2px solid;
  border-image:linear-gradient(to right, #02eb54, #167f01) 1;
}
::v-deep .el-button{
  width: 90%;
  margin:0 auto;
  background: -webkit-linear-gradient(left, #07ba90 0%,#64f069 100%);
  color:#fff;
}


</style>

由于我这里是在页面中维护的,所以在yml中未做配置,可以根据需要做相应的配置;

本文章已经生成可运行项目
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值