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();
}