引入pom
<dependency>
<groupId>com.github.binarywanggroupId>
<artifactId>weixin-java-mpartifactId>
<version>4.4.0version>
dependency>
配置文件增加
# 业务配置
business:
# 服务端根路径
serviceUrl: http://tellsea.4kb.cn/simplebuy-service
# 用户端根路径
appUserUrl: http://192.168.3.7:8081/simplebuy-app-user/#
# 微信配置
weiXinMp:
# 公众号授权登录回调地址
callbackUrl: ${business.serviceUrl}/au/weiXinMp/callback
# 登录回调完成重定向前端地址
loginUrl: ${business.appUserUrl}/pages/login/login
# 支付完成之后重定向前端地址
paySuccessUrl: ${business.appUserUrl}/pages/cart/pay-success
# 微信配置
wx:
# 公众号配置
mp:
configs:
- appid: # 自己设置
secret: # 自己设置
token: #微信小程序消息服务器配置的token
aesKey: #微信小程序消息服务器配置的EncodingAESKey
msgDataFormat: JSON
自定义属性配置
package com.ruoyi.business.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 业务配置
*
* @author Tellsea
* @date 2022/9/7
*/
@Data
@Component
@ConfigurationProperties(prefix = "business")
public class BusinessProperties {
/**
* 服务端根路径
*/
private String serviceUrl;
/**
* 微信公众号配置
*/
private WeiXinMp weiXinMp;
@Data
public static class WeiXinMp {
/**
* 公众号授权登录回调地址
*/
private String callbackUrl;
/**
* 登录回调完成重定向前端地址
*/
private String loginUrl;
/**
* 支付完成之后重定向前端地址
*/
private String paySuccessUrl;
}
}
wxjava属性配置
package com.ruoyi.business.appuser.config;
import com.ruoyi.business.appuser.utils.JsonUtils;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;
/**
* wechat mp properties
*
* @author Binary Wang
*/
@Data
@ConfigurationProperties(prefix = "wx.mp")
public class WxMpProperties {
/**
* 是否使用redis存储access token
*/
private boolean useRedis;
/**
* redis 配置
*/
private RedisConfig redisConfig;
/**
* 多个公众号配置信息
*/
private List<MpConfig> configs;
@Override
public String toString() {
return JsonUtils.toJson(this);
}
@Data
public static class RedisConfig {
/**
* redis服务器 主机地址
*/
private String host;
/**
* redis服务器 端口号
*/
private Integer port;
/**
* redis服务器 密码
*/
private String password;
/**
* redis 服务连接超时时间
*/
private Integer timeout;
}
@Data
public static class MpConfig {
/**
* 设置微信公众号的appid
*/
private String appId;
/**
* 设置微信公众号的app secret
*/
private String secret;
/**
* 设置微信公众号的token
*/
private String token;
/**
* 设置微信公众号的EncodingAESKey
*/
private String aesKey;
}
}
wxjava配置文件
package com.ruoyi.business.appuser.config;
import lombok.AllArgsConstructor;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
import java.util.stream.Collectors;
/**
* wechat mp configuration
*
* @author Binary Wang
*/
@AllArgsConstructor
@Configuration
@EnableConfigurationProperties(WxMpProperties.class)
public class WxMpConfiguration {
private final WxMpProperties properties;
@Bean
public WxMpService wxMpService() {
// 代码里 getConfigs()处报错的同学,请注意仔细阅读项目说明,你的IDE需要引入lombok插件!!!!
final List<WxMpProperties.MpConfig> configs = this.properties.getConfigs();
if (configs == null) {
throw new RuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!");
}
WxMpService service = new WxMpServiceImpl();
service.setMultiConfigStorages(configs
.stream().map(a -> {
WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl();
configStorage.setAppId(a.getAppId());
configStorage.setSecret(a.getSecret());
configStorage.setToken(a.getToken());
configStorage.setAesKey(a.getAesKey());
return configStorage;
}).collect(Collectors.toMap(WxMpDefaultConfigImpl::getAppId, a -> a, (o, n) -> o)));
return service;
}
@Bean
public WxMpMessageRouter messageRouter(WxMpService wxMpService) {
final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService);
return newRouter;
}
}
控制层
package com.ruoyi.business.appuser.controller;
import com.ruoyi.business.appuser.service.WeiXinMpService;
import com.ruoyi.common.core.domain.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 微信公众号Controller
*
* @author Tellsea
* @date 2022/9/6
*/
@Api("微信公众号Controller")
@RestController
@RequestMapping("/au/weiXinMp")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class WeiXinMpController {
private final WeiXinMpService weiXinMpService;
@ApiOperation("获取授权登录Url")
@GetMapping("getLoginUrl")
public AjaxResult getLoginUrl() {
return AjaxResult.success("操作成功", weiXinMpService.getLoginUrl());
}
@ApiOperation("登录回调")
@RequestMapping("callback")
public void callback() {
weiXinMpService.callback();
}
}
接口层
package com.ruoyi.business.appuser.service;
import com.ruoyi.common.core.domain.AjaxResult;
/**
* 微信公众号接口
*
* @author Tellsea
* @date 2022/9/7
*/
public interface WeiXinMpService {
/**
* 获取授权登录Url
*
* @return
*/
String getLoginUrl();
/**
* 登录回调
*/
void callback();
}
接口层实现类
package com.ruoyi.business.appuser.service.impl;
import com.ruoyi.business.appuser.service.WeiXinMpService;
import com.ruoyi.business.properties.BusinessProperties;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author Tellsea
* @date 2022/9/7
*/
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class WeiXinMpServiceImpl implements WeiXinMpService {
private final WxMpService wxMpService;
private final BusinessProperties businessProperties;
private final ISysUserService sysUserService;
private final SysLoginService loginService;
@Override
public String getLoginUrl() {
return wxMpService.getOAuth2Service().buildAuthorizationUrl(businessProperties.getWeiXinMp().getCallbackUrl(), WxConsts.OAuth2Scope.SNSAPI_USERINFO, null);
}
@Override
public void callback() {
HttpServletRequest request = ServletUtils.getRequest();
HttpServletResponse response = ServletUtils.getResponse();
String code = request.getParameter("code");
try {
WxOAuth2AccessToken accessToken = wxMpService.getOAuth2Service().getAccessToken(code);
// 这里可以拿到:头像、昵称、openId、性别
WxOAuth2UserInfo userInfo = wxMpService.getOAuth2Service().getUserInfo(accessToken, null);
SysUser sysUser = new SysUser();
sysUser.setUserName(userInfo.getOpenid());
sysUser.setOpenId(userInfo.getOpenid());
sysUser.setNickName(userInfo.getNickname());
sysUser.setPhonenumber("");
sysUser.setAvatar(userInfo.getHeadImgUrl());
sysUser.setSex(String.valueOf(userInfo.getSex()));
String token = loginService.getToken(sysUser);
response.sendRedirect(businessProperties.getWeiXinMp().getLoginUrl() + "?token=" + token);
} catch (WxErrorException e) {
log.error("根据code获取AccessToken异常");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
<template>
<view>
<view class="login">
<img class="img" src="/static/images/logo.png" />
<view class="title">口袋简购view>
<view class="desc">使用微信公众号授权登录view>
<view class="container-null">
<u-button type="primary" @tap="login" style="margin-top: 20px;">
公众号授权登录
u-button>
view>
view>
view>
template>
<script>
let that;
export default {
data() {
return {
form: {
// 换取openId
code: '',
// 解密手机号
rawData: '',
signature: '',
encryptedData: '',
iv: '',
// 用户信息
nickName: '',
avatarUrl: '',
gender: '',
}
}
},
onLoad(option) {
that = this;
that.getCode();
if (that.$validator.isNotEmpty(option.token)) {
uni.setStorageSync(that.$config.cachePrefix + 'token', option.token);
uni.$u.http.get('/au/defaultLogin/getInfo').then(result => {
uni.setStorageSync(that.$config.cachePrefix + 'user', result.user);
uni.setStorageSync(that.$config.cachePrefix + 'roles', result.roles);
uni.setStorageSync(that.$config.cachePrefix + 'permissions', result.permissions);
uni.$u.route({url: '/pages/index/index'});
});
}
},
methods: {
// 微信公众号授权登录
login() {
uni.$u.http.get('/au/weiXinMp/getLoginUrl').then(res => {
window.location.href = res.data;
});
},
},
}
script>
<style lang="scss" scoped>
page {
background-color: white;
}
.login {
text-align: center;
padding-top: 50px;
.title {
font-size: 20px;
margin-top: 20px;
}
.img {
width: 80px;
height: 80px;
}
.desc {
color: $u-tips-color;
margin-top: 10px;
}
}
style>