公司这两天开发微信小程序,记录一下微信登录的过程
步骤:
1: 获取微信code、sessionKey(加密秘钥)、avatar(商家头像);
2: 通过微信code得到微信openID、微信unionID(微信唯一标识);
3: 通过微信unionID(微信唯一标识)查询数据库是否存在,存在则返回token给到前端,不存在则获取手机号(我这边的流程是小程序是和账号密码互通的);
4: 微信手机号授权通过前端传过来的微信openID、sessionKey(加密秘钥)、encryptedData(加密数据)、iv(加密算法初始向量)、avatar(商家头像)解析出手机号等信息,如果手机号存在则将微信unionID(这里的unionID可通过AccessToken和openId就可以获取到)修改到数据库中这样下次用户登录就会省去获取手机号的流程,如果手机号和微信unionID(微信唯一标识)均在数据库中都不存在则走注册流程。
代码实现:
注:部分 jdk1.9 需要引入 rt.jar
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.10</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.44</version>
</dependency>
<!-- 图片压缩 -->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
WechatUtil(工具类)
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.bouncycastle.util.encoders.Base64;
import org.apache.http.util.TextUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.stereotype.Component;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.AlgorithmParameters;
import java.security.Security;
import java.util.*;
/**
* @ClassName WechatUtil
* @Version 1.0
*/
@Component
public class WechatUtil {
private static final String appId = "xxxxxxxxxxx";
private static final String secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
/**
* 获取小程序codeid换取openid
*
* @param code
* @return
*/
public static JSONObject getOpenId(String code) {
String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + appId
+ "&secret=" + secret + "&js_code=" + code + "&grant_type=authorization_code";
PrintWriter out = null;
BufferedReader in = null;
String line;
StringBuffer stringBuffer = new StringBuffer();
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性 设置请求格式
//设置返回类型
conn.setRequestProperty("contentType", "text/plain");
//设置请求类型
conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
//设置超时时间
conn.setConnectTimeout(1000);
conn.setReadTimeout(1000);
conn.setDoOutput(true);
conn.connect();
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应 设置接收格式
in = new BufferedReader(
new InputStreamReader(conn.getInputStream(), "UTF-8"));
while ((line = in.readLine()) != null) {
stringBuffer.append(line);
}
JSONObject jsonObject = JSONObject.parseObject(stringBuffer.toString());
return jsonObject;
} catch (Exception e) {
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return null;
}
public static Map<String, Object> getPhoneNumber(LoginPhoneInfoParam vo) {
Map<String,Object> map=new HashMap<>();
String openid= vo.getWechatOpenId();
String session_key = vo.getSessionKey();
if (!EmptyUtils.isEmpty(openid)) {
if(EmptyUtils.isEmpty(session_key)){
return null;
}
map.put("openid",openid);
// 被加密的数据
byte[] dataByte = Base64.decode(vo.getEncryptedData());
// 加密秘钥
byte[] keyByte = Base64.decode(session_key);
// 偏移量
byte[] ivByte = Base64.decode(vo.getIv());
try {
// 如果密钥不足16位,那么就补足. 这个if 中的内容很重要
int base = 16;
String result = null;
if (keyByte.length % base != 0) {
int groups = keyByte.length / base + (keyByte.length % base != 0 ? 1 : 0);
byte[] temp = new byte[groups * base];
Arrays.fill(temp, (byte) 0);
System.arraycopy(keyByte, 0, temp, 0, keyByte.length);
keyByte = temp;
}
// 初始化
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
SecretKeySpec spec = new SecretKeySpec(keyByte, "AES");
AlgorithmParameters parameters = AlgorithmParameters.getInstance("AES");
parameters.init(new IvParameterSpec(ivByte));
// 初始化
cipher.init(Cipher.DECRYPT_MODE, spec, parameters);
byte[] resultByte = cipher.doFinal(dataByte);
if (null != resultByte && resultByte.length > 0) {
result = new String(resultByte, "UTF-8");
JSONObject jsonObject = JSONObject.parseObject(result);
map.put("param",jsonObject);
return map;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* 获取小程序token
*
* @return
*/
public static String getAccessToken() {
String url = "https://api.weixin.qq.com/cgi-bin/token?" +
"appid=" + appId + "&secret=" + secret + "&grant_type=client_credential";
PrintWriter out = null;
BufferedReader in = null;
String line;
StringBuffer stringBuffer = new StringBuffer();
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性 设置请求格式
//设置返回类型
conn.setRequestProperty("contentType", "text/plain");
//设置请求类型
conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
//设置超时时间
conn.setConnectTimeout(1000);
conn.setReadTimeout(1000);
conn.setDoOutput(true);
conn.connect();
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应 设置接收格式
in = new BufferedReader(
new InputStreamReader(conn.getInputStream(), "UTF-8"));
while ((line = in.readLine()) != null) {
stringBuffer.append(line);
}
JSONObject jsonObject = JSONObject.parseObject(stringBuffer.toString());
return jsonObject.getString("access_token");
} catch (Exception e) {
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return null;
}
/**
* 获取小程序token和openid
*
* @param code
* @return
*/
public static JSONObject getAccessTokenOrOpenid(String code) {
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?" +
"appid=" + appId + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code";
PrintWriter out = null;
BufferedReader in = null;
String line;
StringBuffer stringBuffer = new StringBuffer();
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性 设置请求格式
//设置返回类型
conn.setRequestProperty("contentType", "text/plain");
//设置请求类型
conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
//设置超时时间
conn.setConnectTimeout(1000);
conn.setReadTimeout(1000);
conn.setDoOutput(true);
conn.connect();
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应 设置接收格式
in = new BufferedReader(
new InputStreamReader(conn.getInputStream(), "UTF-8"));
while ((line = in.readLine()) != null) {
stringBuffer.append(line);
}
JSONObject jsonObject = JSONObject.parseObject(stringBuffer.toString());
return jsonObject;
} catch (Exception e) {
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return null;
}
/**
* 获取小程序unionId
*
* @return
*/
public static String getUnionId(String accessToken,String openid) {
String url = "https://api.weixin.qq.com/sns/userinfo?access_token="+accessToken+"&openid="+openid;
PrintWriter out = null;
BufferedReader in = null;
String line;
StringBuffer stringBuffer = new StringBuffer();
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性 设置请求格式
//设置返回类型
conn.setRequestProperty("contentType", "text/plain");
//设置请求类型
conn.setRequestProperty("content-type", "application/x-www-form-urlencoded");
//设置超时时间
conn.setConnectTimeout(1000);
conn.setReadTimeout(1000);
conn.setDoOutput(true);
conn.connect();
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应 设置接收格式
in = new BufferedReader(
new InputStreamReader(conn.getInputStream(), "UTF-8"));
while ((line = in.readLine()) != null) {
stringBuffer.append(line);
}
JSONObject jsonObject = JSONObject.parseObject(stringBuffer.toString());
return jsonObject.get("unionId").toString();
} catch (Exception e) {
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return null;
}
/**
* 获取微信小程序 session_key 和 openid
*
* @param code 调用微信登陆返回的Code
* @return
*/
public static JSONObject getSessionKeyOropenid(String code) {
//微信端登录code值
String wxCode = code;
String requestUrl = "https://api.weixin.qq.com/sns/jscode2session"; //请求地址 https://api.weixin.qq.com/sns/jscode2session
Map<String, String> requestUrlParam = new HashMap<String, String>();
requestUrlParam.put("appid", appId); //开发者设置中的appId
requestUrlParam.put("secret", secret); //开发者设置中的appSecret
requestUrlParam.put("js_code", wxCode); //小程序调用wx.login返回的code
requestUrlParam.put("grant_type", "authorization_code"); //默认参数 authorization_code
//发送post请求读取调用微信 https://api.weixin.qq.com/sns/jscode2session 接口获取openid用户唯一标识
JSONObject jsonObject = JSON.parseObject(sendPost(requestUrl, requestUrlParam));
return jsonObject;
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param url 发送请求的 URL
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String url, Map<String, ?> paramMap) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
String param = "";
Iterator<String> it = paramMap.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
param += key + "=" + paramMap.get(key) + "&";
}
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("Accept-Charset", "utf-8");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
//使用finally块来关闭输出流、输入流
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
return result;
}
public static BufferedImage getWxacode(String accessToken, String path) {
Map<String, String> paramMap = new HashMap<>();
paramMap.put("path", path);
paramMap.put("width", "120");
String Json = JSONObject.toJSONString(paramMap);
BufferedImage qrCodeImage = null;
BufferedReader reader = null;
try {
URL url = new URL("https://api.weixin.qq.com/wxa/getwxacode?access_token=" + accessToken);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
conn.setRequestProperty("accept", "*/*");
if (!TextUtils.isEmpty(Json)) {
byte[] writebytes = Json.getBytes();
conn.setRequestProperty("Content-Length", String.valueOf(writebytes.length));
OutputStream outwritestream = conn.getOutputStream();
outwritestream.write(Json.getBytes());
outwritestream.flush();
outwritestream.close();
conn.getResponseCode();
}
if (conn.getResponseCode() == 200) {
qrCodeImage = ImageIO.read(conn.getInputStream());
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return qrCodeImage;
}
}
EmptyUtils(判空工具类)
import cn.hutool.core.codec.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.Security;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @ClassName: EmptyUtils
* @Description: 判空工具类
*/
public class EmptyUtils {
/**
* @Title: isEmpty
* @Description: 判断字符串是否为空,长度为0被认为是空字符串.
* @param str
* @return
* @return Integer
*/
public static boolean isEmpty(String str) {
if (null != str) {
return str.trim().length() == 0;
} else {
return true;
}
}
/**
* @Title: isEmpty
* @Description: 判断Bigdecimal类型是否为空或者0
* @return
* @return Integer
*/
public static boolean isEmptyBigdecimal(BigDecimal decimal) {
if(!EmptyUtils.isEmpty(decimal)){
if(decimal.compareTo(BigDecimal.ZERO)!=0){
return false;
}
}
return true;
}
/**
* @Title: isEmpty
* @Description: 判断字符串是否为空,字符串前后空白被截断,截断后长度为0被认为是空字符串
* @param str
* @param isTrimed 是否去掉前后空格
* @return
* @return Integer
*/
public static boolean isEmpty(String str, boolean isTrimed) {
if (isTrimed) {
return null == str || str.trim().length() == 0;
} else {
return null == str || str.length() == 0;
}
}
/**
* @Title: isEmpty
* @Description: 判断列表是否为空,列表没有元素也被认为是空
* @param collection
* @return
* @return Integer
*/
public static boolean isEmpty(Collection<?> collection) {
return null == collection || collection.size() == 0;
}
public static boolean isNotEmpty(Collection<?> collection) {
return !isEmpty(collection);
}
/**
* @Title: isEmpty
* @Description: 判断数组是否为空
* @param array
* @return
* @return Integer
*/
public static boolean isEmpty(Object[] array) {
return null == array || array.length == 0;
}
/**
* @Title: isEmpty
* @Description: 判断对象是否为空
* @param obj
* @return
* @return Integer
*/
public static boolean isEmpty(Object obj) {
return null == obj || "".equals(obj);
}
/**
* @Title: isEmpty
* @Description: 判断Long类型是否为空
* @param obj
* @return
* @return Integer
*/
public static boolean isLongEmpty(Long obj) {
return null == obj || 0l.equals(obj);
}
/**
* 截取字符串中的数字
* @param str
* @return
*/
public static String checkNum(String str) {
StringBuilder builder=new StringBuilder();
String regEx="(\\d+(\\.\\d+)?)";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(str);
while (m.find()) {//当符合正则表达式定义的条件时
builder.append(m.group());
}
return builder.toString();
}
/**
* 截取字符串中除了数字以外的字符串
* @param str
* @return
*/
public static String checkNumOhter(String str) {
StringBuilder builder=new StringBuilder();
String regEx="[^0-9.]";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(str);
while (m.find()) {//当符合正则表达式定义的条件时
builder.append(m.group());
}
return builder.toString();
}
/**
* 图片地址转MultipartFile
*/
public static MultipartFile downloadImageUrl(String imageUrl, Long id) {
try {
HttpURLConnection httpUrl = (HttpURLConnection) new URL(imageUrl).openConnection();
httpUrl.connect();
File file = inputStreamToFile(httpUrl.getInputStream(),"product-"+id+".png");
System.out.println("111====>>>>"+file.getPath());
}catch (Exception e){
e.printStackTrace();
}
return null;
}
/**
* 工具类
* inputStream 转 File
*/
public static File inputStreamToFile(InputStream ins, String name) throws Exception{
File file = new File("C:\\Users\\EDZ\\Pictures\\其他店铺3\\" + name);
if (file.exists()) {
return file;
}
OutputStream os = new FileOutputStream(file);
int bytesRead;
int len = 8192;
byte[] buffer = new byte[len];
while ((bytesRead = ins.read(buffer, 0, len)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
ImageUtil.readImage(file);
return file;
}
/**
* 拿到字符串数组以逗号拼接成字符串返回
* @param images
* @return
*/
public static String getImage(List<String> images) {
String image="";
if(!EmptyUtils.isEmpty(images)){
for (int i = 0; i < images.size(); i++) {
if(i==0||images.size()==1){
image=images.get(i);
}else {
image+=","+images.get(i);
}
}
}
return image;
}
/**
* 拿到字符串数组以逗号拼接成字符串返回
* @param str
* @return
*/
public static String getString(List<Long> str) {
String image="";
if(!EmptyUtils.isEmpty(str)){
for (int i = 0; i < str.size(); i++) {
if(i==0||str.size()==1){
image=String.valueOf(str.get(i));
}else {
image+=","+str.get(i);
}
}
}
return image;
}
/**
* 拿到字符串数组以分号拼接成字符串返回
* @param images
* @return
*/
public static String getFenString(List<String> images) {
String image="";
if(!EmptyUtils.isEmpty(images)){
for (int i = 0; i < images.size(); i++) {
if(i==0||images.size()==1){
image=images.get(i);
}else {
image+=";"+images.get(i);
}
}
}
return image;
}
/**
* 拿到对象数组获取地址以逗号拼接成字符串返回
* @param images
* @return
*/
public static String getImageDateList(List<Image> images) {
String image="";
if(!EmptyUtils.isEmpty(images)){
for (int i = 0; i < images.size(); i++) {
String url = images.get(i).getImgPath();
if(i==0||images.size()==1){
image=url;
}else {
image+=","+url;
}
}
}
return image;
}
/**
* 拿到图片数组封装成数组对象
*/
public static List<Image> getImages(List<String> list){
if(!EmptyUtils.isEmpty(list)){
List<Image> collect = list.stream()
.map(a -> {
Image image = new Image();
image.setImgPath(a);
return image;
}).collect(Collectors.toList());
return collect;
}
return null;
}
/**
* 拿到图片拼接字符串封装成数组对象(以逗号拼接)
*/
public static List<String> getImages(String image){
if(!EmptyUtils.isEmpty(image)){
String[] split = image.split(",");
return Arrays.asList(split);
}
return null;
}
/**
* 拿到图片拼接字符串封装成数组对象(以分号拼接)
*/
public static List<String> getFenStrings(String image){
if(!EmptyUtils.isEmpty(image)){
String[] split = image.split(";");
return Arrays.asList(split);
}
return null;
}
/**
*
* @param secretInfo 微信返回的req_info的值
* @param weChatKey 微信的key
* @return
* @throws Exception
*/
public static String decryption(String secretInfo, String weChatKey) throws Exception {
try {
//对商户key做md5,得到32位小写key*
SecretKeySpec key = new SecretKeySpec(DigestUtils.md5DigestAsHex(getContentBytes(weChatKey, "utf-8")).toLowerCase().getBytes(), "AES");
//创建密码器
Security.addProvider(new BouncyCastleProvider());
//用key*对加密串B做AES-256-ECB解密(PKCS7Padding)
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "BC");
cipher.init(Cipher.DECRYPT_MODE, key);
//返回解密后的内容
return new String(cipher.doFinal(Base64.decode(secretInfo)));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static byte[] getContentBytes(String content, String charset) {
if (charset == null || "".equals(charset)) {
return content.getBytes();
}
try {
return content.getBytes(charset);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 计算切分次数
*/
public static Integer countStep(Integer size, int input) {
return (size + input - 1) / input;
}
/**
* @param list 需要分隔的 集合
* @param input 指定分隔size
* @return
*/
public static List<List<CereRedisKey>> split(List<CereRedisKey> list, int input) {
int limit = countStep(list.size(), input);
List<List<CereRedisKey>> splitList;
splitList = Stream.iterate(0, n -> n + 1).limit(limit).
map(a -> list.stream().skip(a * input).limit(input).collect(Collectors.toList())).
collect(Collectors.toList());
//当输入数量小于分隔数量需反转
if (input<limit){
splitList = Stream.iterate(0, n -> n + 1).limit(input).
map(a -> list.stream().skip(a * limit).limit(limit).collect(Collectors.toList())).
collect(Collectors.toList());
}
return splitList;
}
/**
* 过滤表情包参数
* @param source
* @return
*/
public static String filterEmoji(String source) {
if(source != null)
{
Pattern emoji = Pattern.compile ("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]",Pattern.UNICODE_CASE | Pattern . CASE_INSENSITIVE ) ;
Matcher emojiMatcher = emoji.matcher(source);
if ( emojiMatcher.find())
{
source = emojiMatcher.replaceAll("*");
return source ;
}
return source;
}
return source;
}
}
Service层
import com.alibaba.fastjson.JSONObject;
import com.example.chinese_dance.param.login.LoginPhoneInfoParam;
import com.example.chinese_dance.param.login.LoginPhoneInfoParam;
import com.example.chinese_dance.param.login.WxUserReturnInfo;
import com.example.chinese_dance.model.UsUser;
import com.example.chinese_dance.vo.EbUserVo;
import com.example.chinese_dance.vo.UsUserVo;
import com.example.chinese_dance.vo.WxUserVo;
import java.util.List;
import java.util.Map;
/**
* <p>
* 用户账号 服务类
* </p>
*
* @author ys
* @since 2022-03-05
*/
public interface UsUserService {
/**
* 微信登录
* @param param
* @return
*/
WxUserReturnInfo wxLogin(LoginPhoneInfoParam param);
/**
* 微信获取手机登录
* @param param
* @return
*/
WxUserReturnInfo wxPhoneLogin(LoginPhoneInfoParam param);
}
import com.example.chinese_dance.model.WxUser;
import com.example.chinese_dance.param.login.WxUserReturnInfo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* <p>
* 微信小程序用户表 服务类
* </p>
*
* @author ys123
* @since 2022-07-08
*/
public interface WxUserService {
/**
* WxUser 入库操作
*/
boolean insert(WxUser arg) throws Exception;
/**
* WxUser 修改操作
*/
boolean update(WxUser arg) throws Exception;
/**
* 通过wechatUnionId或手机号查询用户信息
* @param unionId
* @return
*/
WxUserReturnInfo findByUnionIdAndPhone(@Param("wechatUnionId") String unionId,@Param("phone") String phone);
}
ServiceImpl
import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.example.chinese_dance.param.login.LoginPhoneInfoParam;
import com.example.chinese_dance.param.login.LoginPhoneInfoParam;
import com.example.chinese_dance.param.login.WxUserReturnInfo;
import com.example.chinese_dance.util.DateTool;
import com.example.chinese_dance.util.DesensitizationUtil;
import com.example.chinese_dance.util.loginUtil.EmptyUtils;
import com.example.chinese_dance.util.loginUtil.WechatUtil;
import com.example.chinese_dance.vo.EbUserVo;
import com.example.chinese_dance.vo.UsUserVo;
import com.example.chinese_dance.vo.WxUserVo;
import com.example.common.base.ApiReturnCodeEnum;
import com.example.common.base.Params;
import com.example.common.exception.ATException;
import com.example.common.util.IdWorker;
import com.example.common.util.MD5;
import com.example.common.util.MyRestTemplate;
import com.example.common.util.Tree.BuildTree;
import com.example.common.util.Tree.BuildTreeUtils;
import com.example.common.util.UserInfo;
import com.example.chinese_dance.dao.UsUserDao;
import com.example.chinese_dance.dao.mapper.UsUserMapper;
import com.example.chinese_dance.model.*;
import com.example.chinese_dance.service.*;
import com.example.token.JwtUtils;
import net.sf.json.JSONArray;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import java.util.*;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
/**
* <p>
* 用户账号 服务实现类
* </p>
*
* @author ys
*/
@Service
public class UsUserServiceImpl implements UsUserService {
@Autowired
UsUserMapper objectMapper;
@Autowired
UsUserDao objectDao;
@Autowired
MyRestTemplate myRestTemplate;
@Autowired
UsUserService usUserService;
@Autowired
StringRedisTemplate stringRedisTemplate;
@Autowired
UserInfo userInfo;
@Autowired
UsPowerService usPowerService;
@Autowired
WxUserService wxUserService;
@Autowired
EbUserService ebUserService;
Map<String, String> unionIdMap = new HashMap<>();
@Override
@Transactional(readOnly = false,rollbackFor = Exception.class)
public WxUserReturnInfo wxLogin(LoginPhoneInfoParam param) {
WxUserReturnInfo user = null;
boolean flag=false;
try {
// 根据微信code获取相关信息
JSONObject wx = WechatUtil.getOpenId(param.getCode());
String openid = wx.get("openid").toString();
String sessionkey = wx.get("session_key").toString();
String unionId = "";
if (!EmptyUtils.isEmpty(wx.get("unionid"))) {
unionId = wx.get("unionid").toString();
WxUserReturnInfo byUnionid = wxUserService.findByUnionIdAndPhone(unionId,null);
if (!ObjectUtils.isEmpty(byUnionid)) {
WxUser wxUser=new WxUser();
wxUser.setId(byUnionid.getId());
wxUser.setWechatOpenId(openid);
wxUser.setUpdateTime(new Date());
wxUser.setAvatar(param.getAvatar());
//查询另外一个系统是否有对应的手机号
List<EbUser> ebUserList = ebUserService.query(byUnionid.getPhone(), null);
if(!ObjectUtils.isEmpty(ebUserList)){
if(ebUserList.size()==1){
EbUser ebUser=ebUserList.get(0);
//关联另一个系统的用户表
wxUser.setEbUserId(ebUser.getUid());
}
}else{
//没有在另外一个系统中查出来手机号则在eb_user表中新增一个用户
EbUser ebUser=new EbUser();
Integer nowTimeInt=DateTool.dateByInt();
ebUser.setAccount("wx"+ nowTimeInt);
//默认密码:123456
ebUser.setPwd(MD5.encoder("123456"));
ebUser.setAvatar(param.getAvatar());
ebUser.setPhone(byUnionid.getPhone());
ebUser.setAddTime(nowTimeInt);
if(StringUtils.isNotBlank(param.getIp())) {
ebUser.setAddIp(param.getIp());
ebUser.setLastIp(param.getIp());
}
ebUser.setLastTime(nowTimeInt);
ebUser.setStatus(false);
flag=ebUserService.insert(ebUser);
if(!flag){
throw new ATException("用户信息入库失败~",ApiReturnCodeEnum.customTips);
}
}
flag=wxUserService.update(wxUser);
if(!flag){
throw new ATException("用户信息更新失败~",ApiReturnCodeEnum.customTips);
}
user=new WxUserReturnInfo();
BeanUtils.copyProperties(user,wxUser);
user.setUserId(byUnionid.getId());
String token =JwtUtils.generateToken(byUnionid.getId());
user.setToken(token);
user.setPhone(byUnionid.getPhone());
//存token
stringRedisTemplate.opsForValue().set(Params.key + token,user.toString());
stringRedisTemplate.expire(Params.key + token, Params.token_timeout, TimeUnit.SECONDS);
user.setIsFlagPhone(false);
} else {
user = new WxUserReturnInfo();
user.setWechatOpenId(openid);
user.setSessionKey(sessionkey);
unionIdMap.put(openid, unionId);
user.setIsFlagPhone(true);
user.setAvatar(param.getAvatar());
}
} else {
throw new ATException("unionid解析失败~", ApiReturnCodeEnum.customTips);
}
} catch (Exception e) {
e.printStackTrace();
}
return user;
}
@Override
@Transactional(readOnly = false,rollbackFor = Exception.class)
public WxUserReturnInfo wxPhoneLogin(LoginPhoneInfoParam param) {
WxUserReturnInfo wxUserReturnInfo = new WxUserReturnInfo();
boolean flag=false;
String token=null;
try {
WxUser result = new WxUser();
Map<String, Object> map = WechatUtil.getPhoneNumber(param);
if (EmptyUtils.isEmpty(map)) {
throw new ATException("解析手机号失败~", ApiReturnCodeEnum.customTips);
}
String phone = "";
Object phoneNumber = map.get("param");
String jsonString = JSONObject.toJSONString(phoneNumber);
JSONObject obj = JSONObject.parseObject(jsonString);
if (!EmptyUtils.isEmpty(jsonString)) {
phone = obj.get("phoneNumber").toString();
}
String unionId = unionIdMap.get(param.getWechatOpenId());
//校验手机号是否能查询到相关的用户
WxUserReturnInfo allByPhone = wxUserService.findByUnionIdAndPhone(null, phone);
if (!ObjectUtils.isEmpty(allByPhone)) {
result.setId(allByPhone.getId());
result.setWechatOpenId(param.getWechatOpenId());
result.setWechatUnionId(unionId);
result.setAvatar(param.getAvatar());
result.setUpdateTime(new Date());
//查询另外一个系统是否有对应的手机号
List<EbUser> ebUserList = ebUserService.query(phone, null);
if(!ObjectUtils.isEmpty(ebUserList)){
if(ebUserList.size()==1){
EbUser ebUser=ebUserList.get(0);
//关联另一个系统的用户表
result.setEbUserId(ebUser.getUid());
}
}else{
//没有在另外一个系统中查出来手机号则在eb_user表中新增一个用户
EbUser ebUser=new EbUser();
Integer nowTimeInt=DateTool.dateByInt();
ebUser.setAccount("wx"+ nowTimeInt);
//默认密码:123456
ebUser.setPwd(MD5.encoder("123456"));
ebUser.setAvatar(param.getAvatar());
ebUser.setPhone(phone);
ebUser.setAddTime(nowTimeInt);
if(StringUtils.isNotBlank(param.getIp())) {
ebUser.setAddIp(param.getIp());
ebUser.setLastIp(param.getIp());
}
ebUser.setLastTime(nowTimeInt);
ebUser.setStatus(false);
flag=ebUserService.insert(ebUser);
if(!flag){
throw new ATException("用户信息入库失败~",ApiReturnCodeEnum.customTips);
}
}
flag=wxUserService.update(result);
if(!flag){
throw new ATException("用户信息更新失败~",ApiReturnCodeEnum.customTips);
}
token = JwtUtils.generateToken(allByPhone.getId());
BeanUtils.copyProperties(wxUserReturnInfo, result);
wxUserReturnInfo.setUserId(allByPhone.getId());
wxUserReturnInfo.setToken(token);
wxUserReturnInfo.setWechatUnionId("");
unionIdMap.remove(param.getWechatOpenId());
wxUserReturnInfo.setPhone(phone);
wxUserReturnInfo.setWechatName(allByPhone.getWechatName());
wxUserReturnInfo.setBrief(allByPhone.getBrief());
} else {
//注册
String userId=IdWorker.generSequeId();
result.setId(userId);
token = JwtUtils.generateToken(userId);
//手机号脱敏作为用户名
result.setWechatName(DesensitizationUtil.mobileEncrypt(phone));
result.setBrief("暂无简介");
result.setWechatOpenId(param.getWechatOpenId());
result.setWechatUnionId(unionId);
result.setAvatar(param.getAvatar());
result.setPhone(phone);
//查询另外一个系统是否有对应的手机号
List<EbUser> ebUserList = ebUserService.query(phone, null);
if(!ObjectUtils.isEmpty(ebUserList)){
if(ebUserList.size()==1){
EbUser ebUser=ebUserList.get(0);
//关联另一个系统的用户表
result.setEbUserId(ebUser.getUid());
}
}
unionIdMap.remove(param.getWechatOpenId());
flag=wxUserService.insert(result);
if(!flag){
throw new ATException("新用户注册失败~",ApiReturnCodeEnum.customTips);
}
BeanUtils.copyProperties(wxUserReturnInfo, result);
wxUserReturnInfo.setUserId(userId);
}
//存token
stringRedisTemplate.opsForValue().set(Params.key + token, wxUserReturnInfo.toString());
stringRedisTemplate.expire(Params.key + token, Params.token_timeout, TimeUnit.SECONDS);
}catch (Exception e){
e.printStackTrace();
}
return wxUserReturnInfo;
}
}
import com.example.chinese_dance.param.login.WxUserReturnInfo;
import com.example.common.util.IdWorker;
import com.example.chinese_dance.dao.WxUserDao;
import com.example.chinese_dance.dao.mapper.WxUserMapper;
import com.example.chinese_dance.model.WxUser;
import com.example.chinese_dance.model.WxUserExample;
import com.example.chinese_dance.service.WxUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
/**
* <p>
* 微信小程序用户表 服务实现类
* </p>
*
* @author ys123
* @since 2022-07-08
*/
@Service
public class WxUserServiceImpl implements WxUserService {
@Autowired
WxUserMapper objectMapper;
@Autowired
WxUserDao objectDao;
@Override
public boolean insert(WxUser object) throws Exception {
if (StringUtils.isBlank(object.getId())) {
String id = IdWorker.generSequeId();
object.setId(id);
}
object.setCreateTime(new Date());
object.setDel(Short.valueOf("0"));
int count = objectMapper.insertSelective(object);
if (count > 0) return true;
return false;
}
@Override
public boolean update(WxUser object) throws Exception {
object.setUpdateTime(new Date());
int count = objectMapper.updateByPrimaryKeySelective(object);
if (count > 0) return true;
return false;
}
@Override
public WxUserReturnInfo findByUnionIdAndPhone(String unionId,String phone) {
return objectDao.findByUnionId(unionId,phone);
}
}
Controller层调用
import com.alibaba.fastjson.JSONObject;
import com.example.chinese_dance.param.backstageLogin.BackstageLoginParam;
import com.example.chinese_dance.param.login.LoginParam;
import com.example.chinese_dance.param.login.LoginPhoneInfoParam;
import com.example.chinese_dance.param.login.LoginPhoneInfoParam;
import com.example.chinese_dance.param.login.WxUserReturnInfo;
import com.example.chinese_dance.service.UsUserService;
import com.example.chinese_dance.util.loginUtil.WechatUtil;
import com.example.common.base.ApiReturnCodeEnum;
import com.example.common.base.RestResponse;
import com.example.common.util.MyRestTemplate;
import com.github.pagehelper.util.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestClientException;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping("/open/auth")
@Api(tags = {"认证接口,通用固定,认证后返回的\\'token\\'等同于\\'Authorization\\ v1.0"})
public class AuthController {
private final static Logger logger = LoggerFactory.getLogger(AuthController.class);
@Value("${server.port}")
String port;
@Autowired
MyRestTemplate myRestTemplate;
@Autowired
UsUserService usUserService;
/**
* 微信授权登录
*
* @param param 封装json对象
* @return
*/
@PostMapping("wxLogin")
@ApiOperation(value = "微信授权登录")
public RestResponse<LoginParam> wxLogin(@RequestBody LoginPhoneInfoParam param) {
WxUserReturnInfo personal = usUserService.wxLogin(param);
return RestResponse.success(personal);
}
@PostMapping("wxPhoneLogin")
@ApiOperation(value = "微信获取手机登录")
public RestResponse<LoginParam> wxPhoneLogin(@RequestBody LoginPhoneInfoParam param, HttpServletRequest request){
WxUserReturnInfo personal = usUserService.wxPhoneLogin(param);
request.getAttribute("openid");
return RestResponse.success(personal);
}
/**
* 获取微信加密秘钥
* @param param 封装json对象
* @return
*/
@PostMapping("getSessionKey")
@ApiOperation(value = "获取微信加密秘钥")
public RestResponse<WxUserReturnInfo> getSessionKey(@RequestBody LoginParam param){
//传入code后然后获取openid和session_key的,把他们封装到json里面
JSONObject json = WechatUtil.getSessionKeyOropenid(param.getCode());
String session_key = json.getString("session_key");
String openid = json.get("openid").toString();
WxUserReturnInfo platformBusinessReturnInfo=new WxUserReturnInfo();
platformBusinessReturnInfo.setSessionKey(session_key);
platformBusinessReturnInfo.setWechatOpenId(openid);
return RestResponse.success(platformBusinessReturnInfo);
}
}
参数/返回值实体
UserReturnInfo 手机号授权(返回值)
import com.shop.cereshop.commons.domain.business.CerePlatformBusiness;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 登录返回参数
*/
@Data
@ApiModel(value = "PlatformBusinessReturnInfo", description = "登录返回参数")
public class PlatformBusinessReturnInfo extends CerePlatformBusiness {
/**
* 微信code
*/
@ApiModelProperty(value = "微信code")
private String code;
/**
* 商家用户id
*/
@ApiModelProperty(value = "商家用户id")
private Long businessUserId;
/**
* 店铺Id
*/
@ApiModelProperty(value = "店铺Id")
private Long shopId;
/**
* 商家登录账号
*/
@ApiModelProperty(value = "商家登录账号")
private String username;
/**
* 微信昵称
*/
@ApiModelProperty(value = "微信昵称")
private String wechatName;
/**
* 微信openid
*/
@ApiModelProperty(value = "微信openid")
private String wechatOpenId;
/**
* 微信unionId
*/
@ApiModelProperty(value = "微信unionId")
private String wechatUnionId;
/**
* 绑定手机号
*/
@ApiModelProperty(value = "绑定手机号")
private String phone;
/**
* 请求token
*/
@ApiModelProperty(value = "请求token")
private String token;
/**
* 是否启用状态 1-是 0-否
*/
@ApiModelProperty(value = "是否启用状态 1-是 0-否")
private Integer state;
/**
* 商家头像
*/
@ApiModelProperty(value = "商家头像")
private String avatar;
/**
* 微信加密秘钥
*/
@ApiModelProperty(value = "微信加密秘钥")
private String sessionKey;
/**
* 加密数据
*/
@ApiModelProperty(value = "加密数据")
private String encryptedData;
/**
* 加密算法初始向量
*/
@ApiModelProperty(value = "加密算法初始向量")
private String iv;
/**
* 是否获取手机号
*/
@ApiModelProperty(value = "是否获取手机号")
private Boolean isFlagPhone;
}
CerePlatformBusiness手机号授权(参数)
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* cere_platform_business 平台商家用户实体类
* @author
*/
@Data
@ApiModel(value = "CerePlatformBusiness", description = "平台商家用户实体类")
public class CerePlatformBusiness implements Serializable {
/**
* 店铺id
*/
private Long shopId;
/**
* 商家用户id
*/
@ApiModelProperty(value = "商家用户id")
@TableId(type = IdType.AUTO)
private Long businessUserId;
/**
* 商家登录账号
*/
@ApiModelProperty(value = "商家登录账号")
private String username;
/**
* 商家登录密码
*/
@ApiModelProperty(value = "商家登录密码")
@JsonIgnore
private String password;
/**
* 商家昵称
*/
@ApiModelProperty(value = "商家昵称")
private String name;
/**
* 商家头像
*/
@ApiModelProperty(value = "商家头像")
private String avatar;
/**
* 手机号
*/
@ApiModelProperty(value = "手机号")
private String phone;
/**
* 商家性别
*/
@ApiModelProperty(value = "商家性别")
private String sex;
/**
* 商家邮箱
*/
@ApiModelProperty(value = "商家邮箱")
private String email;
/**
* 用户token
*/
@ApiModelProperty(value = "用户token 停用")
private String token;
/**
* 是否启用 1-是 0-否
*/
@ApiModelProperty(value = "是否启用 1-是 0-否")
private Integer state;
/**
* 创建时间
*/
@ApiModelProperty(value = "创建时间")
private String createTime;
/**
* 更新时间
*/
@ApiModelProperty(value = "更新时间")
private String updateTime;
/**
* 微信openID
*/
@ApiModelProperty(value = "微信openID")
private String wechatOpenId;
/**
* 微信unionId
*/
@ApiModelProperty(value = "微信unionId")
private String wechatUnionId;
/**
* 微信昵称
*/
@ApiModelProperty(value = "微信昵称")
private String wechatName;
/**
* 微信号
*/
@ApiModelProperty(value = "微信号")
private String wechatNumber;
private static final long serialVersionUID = 1L;
}
LoginParam登录请求参数(返回值)
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 登录请求参数
*/
@Data
@ApiModel(value = "LoginParam", description = "登录请求参数")
public class LoginParam {
/**
* 微信code
*/
@ApiModelProperty(value = "微信code")
private String code;
/**
* 商家登录账号
*/
@ApiModelProperty(value = "商家登录账号")
private String username;
/**
* 微信昵称
*/
@ApiModelProperty(value = "微信昵称")
private String wechatName;
/**
* 微信openid
*/
@ApiModelProperty(value = "微信openid")
private String wechatOpenId;
/**
* 微信unionId
*/
@ApiModelProperty(value = "微信unionId")
private String wechatUnionId;
/**
* 绑定手机号
*/
@ApiModelProperty(value = "绑定手机号")
private String phone;
/**
* 请求token
*/
@ApiModelProperty(value = "请求token")
private String token;
/**
* 是否启用状态 1-是 0-否
*/
@ApiModelProperty(value = "是否启用状态 1-是 0-否")
private Integer state;
/**
* 商家头像
*/
@ApiModelProperty(value = "商家头像")
private String avatar;
/**
* 加密数据
*/
@ApiModelProperty(value = "加密数据")
private String encryptedData;
/**
* 加密算法初始向量
*/
@ApiModelProperty(value = "加密算法初始向量")
private String iv;
}
LoginPhoneInfoParam手机号授权(参数)
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 手机号授权
*/
@Data
@ApiModel(value = "LoginPhoneInfoParam", description = "手机号授权")
public class LoginPhoneInfoParam {
/**
* 微信code
*/
@ApiModelProperty(value = "微信code")
private String code;
/**
* 微信openID
*/
@ApiModelProperty(value = "微信openID")
private String wechatOpenId;
/**
* 微信unionID
*/
@ApiModelProperty(value = "微信unionID")
private String wechatUnionId;
/**
* 加密秘钥
*/
@ApiModelProperty(value = "加密秘钥")
private String sessionKey;
/**
* 加密数据
*/
@ApiModelProperty(value = "加密数据")
private String encryptedData;
/**
* 加密算法初始向量
*/
@ApiModelProperty(value = "加密算法初始向量")
private String iv;
/**
* 商家头像
*/
@ApiModelProperty(value = "商家头像")
private String avatar;
}
LoginPhoneInfoParam手机号授权
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 手机号授权
*/
@Data
@ApiModel(value = "LoginPhoneInfoParam", description = "手机号授权")
public class LoginPhoneInfoParam{
/**
* 微信openID
*/
@ApiModelProperty(value = "微信openID")
private String wechatOpenId;
/**
* 加密秘钥
*/
@ApiModelProperty(value = "加密秘钥")
private String sessionKey;
/**
* 加密数据
*/
@ApiModelProperty(value = "加密数据")
private String encryptedData;
/**
* 加密算法初始向量
*/
@ApiModelProperty(value = "加密算法初始向量")
private String iv;
/**
* 头像
*/
@ApiModelProperty(value = "头像")
private String avatar;
/**
* ip
*/
@ApiModelProperty(value = "ip")
private String ip;
}
LoginParam登录返回参数
import com.example.chinese_dance.vo.UsUserVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 登录返回参数
*/
@Data
@ApiModel(value = "LoginParam", description = "登录返回参数")
public class WxUserReturnInfo extends UsUserVo {
/**
* 微信code
*/
@ApiModelProperty(value = "微信code")
private String code;
/**
* 用户id
*/
@ApiModelProperty(value = "用户id")
private String userId;
/**
* 微信昵称
*/
@ApiModelProperty(value = "微信昵称")
private String wechatName;
/**
* 微信openid
*/
@ApiModelProperty(value = "微信openid")
private String wechatOpenId;
/**
* 微信unionId
*/
@ApiModelProperty(value = "微信unionId")
private String wechatUnionId;
/**
* 绑定手机号
*/
@ApiModelProperty(value = "绑定手机号")
private String phone;
/**
* 请求token
*/
@ApiModelProperty(value = "请求token")
private String token;
/**
* 是否启用状态 0-是 1-否
*/
@ApiModelProperty(value = "是否启用状态 0-是 1-否")
private Integer del;
/**
* 头像
*/
@ApiModelProperty(value = "头像")
private String avatar;
/**
* 微信加密秘钥
*/
@ApiModelProperty(value = "微信加密秘钥")
private String sessionKey;
/**
* 加密数据
*/
@ApiModelProperty(value = "加密数据")
private String encryptedData;
/**
* 加密算法初始向量
*/
@ApiModelProperty(value = "加密算法初始向量")
private String iv;
/**
* 是否获取手机号
*/
@ApiModelProperty(value = "是否获取手机号")
private Boolean isFlagPhone;
@ApiModelProperty(value = "简介")
private String brief;
}
PageParam分页参数
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel(value = "PageParam", description = "分页参数")
public class PageParam {
@ApiModelProperty(value = "页码")
private Integer pageNo;
@ApiModelProperty(value = "页数")
private Integer pageSize;
}
注意:
如果没有在微信开放平台绑定微信小程序的话通过code是没有办法获取到微信用户的unionId的。
小程序登录需要先注册一个微信小程序,进行登录流程前必须要获取小程序的小程序appid、小程序秘钥secret
这里好像漏了几个工具类和参数类,如果看到需要的话可以留言我这边有时间补上