赞
踩
maven pom.xml文件添加依赖
- <dependency>
- <groupId>com.github.binarywang</groupId>
- <artifactId>weixin-java-miniapp</artifactId>
- <version>4.4.8.B</version>
- </dependency>
微信小程序配置:
- #环境配置文件配置小程序APPID和密钥
- wx:
- app-id: xx
- app-secret: xx
-
-
- #获取配置环境的属性值
- package com.xx.framework.config.properties;
-
- import lombok.Data;
- import org.springframework.boot.context.properties.ConfigurationProperties;
- import org.springframework.context.annotation.Configuration;
-
- /**
- * 微信参数
- */
- @Configuration
- @ConfigurationProperties(prefix = "wx")
- @Data
- public class WxProperties {
- private String appId;
- private String appSecret;
- }
-
- #配置微信小程序类
- package com.xx.framework.config;
-
- import cn.binarywang.wx.miniapp.api.WxMaService;
- import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
- import cn.binarywang.wx.miniapp.config.WxMaConfig;
- import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
- import com.xx.framework.config.properties.WxProperties;
- import lombok.AllArgsConstructor;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
-
- @AllArgsConstructor
- @Configuration
- public class WxConfig {
- private final WxProperties wxProperties;
- /**
- * 小程序配置
- * @return
- */
- @Bean
- @ConditionalOnMissingBean
- public WxMaConfig wxMaConfig() {
- WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
- config.setAppid(this.wxProperties.getAppId());
- config.setSecret(this.wxProperties.getAppSecret());
- return config;
- }
-
- @Bean
- public WxMaService wxMaService(WxMaConfig maConfig) {
- WxMaService service = new WxMaServiceImpl();
- service.setWxMaConfig(maConfig);
- return service;
- }
- }

1、获取二维码地址,通过请求微信开发者文档中的服务端获取无限制小程序二维码URL
- #controller层
- import org.apache.commons.codec.binary.Base64;
- /**
- * 获取小程序二维码
- */
- @PassToken
- @GetMapping("/getQrCode")
- public AjaxResult getQrCode(BlogUserDto blogUserDto){
- String base64 = blogUserService.getQrCode(blogUserDto);
- if (StrUtil.isBlank(base64)){
- return AjaxResult.error("获取二维码失败");
- }
- return AjaxResult.success("data:image/png;base64,"+base64);
- }
-
- #service层
-
- /**
- * 获取小程序二维码
- * @return
- */
- String getQrCode(BlogUserDto blogUserDto);
-
-
- #service impl层
- @Override
- public String getQrCode(BlogUserDto blogUserDto) {
- String base64;
- try{
- //先判断access_token是否存在。不存在则查询
- String key = Constants.MINAPP_ACCESS_TOKEN;
- String accessToken = null;
- if (redisCache.hasKey(key)){
- accessToken = redisCache.getCacheObject(key);
- }
- if (accessToken == null){
- accessToken = wxMaService.getAccessToken(true);
- redisCache.setCacheObject(key,accessToken,7200, TimeUnit.SECONDS);
- }
- //传入的参数a=1&b=2
- String scene = blogUserDto.getScene();
- //扫码后跳转的页面
- String page = "pages/index";
- boolean checkPath = false;
- //版本。正式版为release,体验版trial,开发版develop
- String envVersion = "develop";
- //二维码的宽度
- int width = 280;
- boolean autoColor= false;
- WxMaCodeLineColor lineColor = null;
- boolean isHyaline = false;
- //获取无限制二维码
- byte[] bytes = wxMaService.getQrcodeService().createWxaCodeUnlimitBytes(scene,page,checkPath,envVersion,width,autoColor,lineColor,
- isHyaline);
- base64 = new String(Objects.requireNonNull(Base64.encodeBase64(bytes)));
- }catch (Exception e){
- e.printStackTrace();
- return null;
- }
- return base64;
- }
-
- #Constant类
- /**
- * 小程序access_token
- */
- public static final String MINAPP_ACCESS_TOKEN = "minapp_access_token:";

2、将获取到的base64图片地址显示在PC端
- <div style="width: 100%;height: 100%;text-align: center;position:relative">
- <img :src="codeUrl" alt="" :loading="loadingCorUrl"
- style="">
- <div v-if="showexpire" @click="clickScanQR" style="width: 65%;height: 98%;
- position:absolute;top:0%;left:50%;
- transform:translateX(-50%);opacity: 0.9;font-size:20px;
- background-color: darkgray;font-color:black;">
- <div style="position:absolute;top:40%;left:40%;">
- <i class="el-icon-refresh" style="font-size:60px;color:#ffffff;cursor: pointer;"></i>
- </div>
- <div style="position:absolute;top:65%;left:25%;font-size:15px;color:#ffffff;">
- 二维码失效,点击重试</div>
- </div>
- </div>
-
-
-
- scene:null,
- timer:null,
- loadingCorUrl:false,
- showexpire:false,
-
-
-
- //点击重新刷新二维码
- clickScanQR(){
- this.getQrCode();
- },

3、scene的值由PC端生成传给获取二维码的接口。
4、uniapp收到scene的值后,小程序微信登录
- onLoad: function(query) {
- this.getBanner();
- // this.getBlogList();
- setTimeout(function () {
- console.log('start pulldown');
- }, 1000);
- uni.startPullDownRefresh();
- //获取pc端扫码后传的参数值
- const scene = decodeURIComponent(query.scene);
- console.log("scene:"+scene);
- //如果scene有值,判断用户是否登录
- if(scene && scene != undefined && scene != 'undefined'){
- console.log("token:"+this.$store.state.user.token)
- //如果登录,授权网站。
- if(this.$store.state.user.token){
- console.log("llll")
- updateScene({"scene":scene}).then(res=>{
-
- });
- }else{
- // 如果没有登录,直接微信登录,授权网站
- this.$tab.navigateTo('/pages/mine/wxlogin/index?scene='+scene)
- }
- }
- },

5、pc端具体代码
- algorithm(){
- let abc=['a','b','c','d','e','f','g','h','i','g','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
- let [max,min]=[Math.floor(Math.random()*(10-7+1)+1),Math.floor(Math.random()*(17-10+1)+17)];
- abc=abc.sort(()=>0.4-Math.random()).slice(max,min).slice(0,8).join("");
- var a=new Date().getTime()+abc;
- return a
- },
-
- getQrCode(){
- this.scene = this.algorithm();
- this.loadingCorUrl=true;
- this.showexpire=false;
- getQrCode({"scene":this.scene}).then(res=>{
- if(res.code == 200){
- this.codeUrl=res.msg;
- if(this.codeUrl && this.codeUrl != undefined && this.codeUrl != 'undefined'){
- this.loadingCorUrl=false;
- //获取后轮询
- var _this = this;
- var seconds=0,minutes=0;
- _this.timer = setInterval(()=>{
- seconds=seconds+3;
- console.log("seconds:"+seconds);
- if(seconds == 60){
- minutes = minutes+1;
- }
- _this.$store.dispatch("BlogLoginByScene", {"scene":_this.scene}).then((res) => {
- if(res.code == 200 && res.token && res.token != undefined && res.token != 'undefined'){
- clearInterval(_this.timer);
- _this.open = false;
- _this.getUserInfo();
- }
- }).catch(() => {
- });
- console.log("minutes:"+minutes)
- if(minutes == 1){
- clearInterval(_this.timer);
- _this.showexpire=true;
- }
- },3000)
- }
- }
- })
- },

6、第5条里的微信扫码登录是另外的接口,在登录配置里另外配置,设置如下
- #store->userBlog.js里设置
- import {login, logout, getInfo,loginByScene} from '@/api/loginBlog'
- //根据scene查询登录
- BlogLoginByScene({commit}, userInfo) {
- const scene = userInfo.scene
- return new Promise((resolve, reject) => {
- loginByScene(scene).then(res => {
- if(res.code == 200 && res.token && res.token != undefined && res.token != 'undefined'){
- setToken(res.token)
- commit('SET_BLOG_TOKEN', res.token)
- }
- resolve(res)
- }).catch(error => {
- reject(error)
- })
- })
- },
-
- #api->loginBlog.js
- //根据scene查询登录
- export function loginByScene(scene) {
- const data = {
- scene
- }
- return request({
- url: '/reception/blog/user/getUserByScene',
- headers: {
- isToken: false
- },
- method: 'get',
- params: data
- })
- }

7、后端接口
- #controller层
- /**
- * 根据scene查询用户
- */
- @PassToken
- @GetMapping("/getUserByScene")
- public AjaxResult getUserByScene(BlogUserDto blogUserDto){
- if (StrUtil.isBlank(blogUserDto.getScene())){
- return AjaxResult.error("参数值错误");
- }
- BlogUser blogUser = blogUserService.getOne(new LambdaQueryWrapper<BlogUser>()
- .select(BlogUser::getId)
- .eq(BlogUser::getScene,blogUserDto.getScene()));
- if (blogUser != null){
- //创建token
- Map<String,Object> claims = new HashMap<>();
- claims.put("uuid", IdUtils.getLongId());
- claims.put(Constants.BLOG_LOGIN_USER_KEY,blogUser.getId());
- String token = tokenService.createToken((claims));
-
- redisCache.setCacheObject(CacheConstants.BLOG_LOGIN_TOKEN_KEY + blogUser.getId(),token);
- AjaxResult ajax = AjaxResult.success();
- ajax.put(Constants.TOKEN, token);
- return ajax;
- }
- return AjaxResult.success();
- }
-
- /**
- * 更新用户scene值
- * @param id
- * @param blogUser
- * @return
- */
- @PutMapping("/updateScene")
- public AjaxResult updateScene(@CurrentUser Long id,@RequestBody BlogUser blogUser){
- blogUser.setId(id);
- blogUserService.updateById(blogUser);
- return AjaxResult.success();
- }

注释:
如果获取accesstoken出现以下错误,请获取稳定版本
{"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest, could get access_token by getStableAccessToken, more details at https://mmbizurl.cn/s/JtxxFh33r rid: 65b3294e-6993fa45-745b3def"}
结果:{"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest, could get access_token by getStableAccessToken, more details at https://mmbizurl.cn/s/JtxxFh33r rid: 65b3294e-6993fa45-745b3def"}
POST https://api.weixin.qq.com/cgi-bin/stable_token
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。