package com.project.common.utils;
|
|
import cn.hutool.http.HttpUtil;
|
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSONObject;
|
import com.project.common.exception.base.BaseException;
|
import com.project.common.utils.http.HttpUtils;
|
import com.project.common.vo.UserWxPhoneInfoVO;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.boot.CommandLineRunner;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.stereotype.Component;
|
import java.util.*;
|
import java.util.concurrent.TimeUnit;
|
|
import static com.project.common.constant.WechatConstants.*;
|
|
|
@Component
|
@Slf4j
|
public class WeChatUtils implements CommandLineRunner {
|
|
@Override
|
public void run(String... args) throws Exception {
|
getAccessToken();
|
}
|
|
private static StringRedisTemplate stringRedisTemplate;
|
|
@Autowired
|
public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
|
WeChatUtils.stringRedisTemplate = stringRedisTemplate;
|
}
|
|
private static String appid;
|
|
private static String secret;
|
|
@Value("${pay.wx.xcx.appid}")
|
public void setAppid(String appid) {
|
this.appid = appid;
|
}
|
|
@Value("${pay.wx.xcx.secret}")
|
public void setSecret(String secret) {
|
this.secret = secret;
|
}
|
|
|
/**
|
* 刷新access_token
|
*/
|
public static void refreshAccessToken() {
|
String url = WEIXIN_ACCESS_TOKEN_URL + "?grant_type=client_credential&appid=" + appid + "&secret=" + secret;
|
try {
|
//向微信发送请求
|
String result = HttpUtils.sendGet(url, null);
|
//将获取的结果转化为JSONObject
|
JSONObject re = JSON.parseObject(result);
|
String accessToken = re.getString("access_token");
|
//设置access_token的生命周期为1小时
|
int expires_in = 3600;
|
if (StringUtils.isNotBlank(accessToken)) {
|
stringRedisTemplate
|
.opsForValue()
|
.set(appid + ":access_token", accessToken, expires_in, TimeUnit.SECONDS);
|
}
|
} catch (Exception e) {
|
log.error("getAccess_token ERROR, appid = " + appid, e);
|
}
|
}
|
|
/**
|
* 获取微信公众号access_token
|
* @return
|
*/
|
public static String getAccessToken()
|
{
|
String accessToken = stringRedisTemplate.opsForValue().get(appid + ":access_token");
|
if (StringUtils.isBlank(accessToken)) {
|
String url = WEIXIN_ACCESS_TOKEN_URL + "?grant_type=client_credential&appid=" + appid + "&secret=" + secret;
|
try {
|
//向微信发送请求
|
String result = HttpUtils.sendGet(url, null);
|
//将获取的结果转化为JSONObject
|
JSONObject re = JSON.parseObject(result);
|
accessToken = re.getString("access_token");
|
//设置access_token的生命周期为1小时
|
int expires_in = 3600;
|
if (StringUtils.isNotBlank(re.getString("expires_in"))) {
|
expires_in = re.getIntValue("expires_in");
|
}
|
if (StringUtils.isNotBlank(accessToken)) {
|
stringRedisTemplate
|
.opsForValue()
|
.set(appid + ":access_token", accessToken, expires_in, TimeUnit.SECONDS);
|
}
|
} catch (Exception e) {
|
log.error("getAccess_token ERROR, appid = " + appid, e);
|
}
|
}
|
return accessToken;
|
}
|
|
/**
|
* 获取微信用户信息
|
*
|
* @param accessToken 用户的access_token
|
* @param openid 用户的openid
|
* @return 包含用户信息的Map
|
* @throws Exception
|
*/
|
public static Map<String, String> getUserInfo(String accessToken, String openid) throws Exception
|
{
|
String url = USER_INFO_URL + "?access_token=" + accessToken + "&openid=" + openid + "&lang=zh_CN";
|
String result = HttpUtils.sendGet(url, null);
|
JSONObject jsonObject = JSON.parseObject(result);
|
System.out.println(jsonObject.toString());
|
String unionid = jsonObject.getString("unionid");
|
String nickname = jsonObject.getString("nickname");
|
String avatar = jsonObject.getString("headimgurl");
|
String phoneNumber = jsonObject.getString("phoneNumber"); // 获取用户手机号需要用户在小程序内进行授权
|
Map<String, String> map = new HashMap<>();
|
map.put("unionId", unionid);
|
map.put("nickname", nickname);
|
map.put("avatar", avatar);
|
map.put("phoneNumber", phoneNumber);
|
return map;
|
}
|
|
|
|
/**
|
* 获取用户手机号
|
* @return
|
*/
|
public static String getUserPhone(String accessToken, String code)
|
{
|
String phone = "";
|
String urlPath = WEIXIN_GET_USERPHONENUMBER_URL + accessToken;
|
try {
|
Map<String, String> headerMap = new HashMap<>();
|
headerMap.put("content-type", "application/json");
|
Map<String, Object> dataMap = new HashMap<>();
|
dataMap.put("code", code);
|
String result = HttpUtils.callPostServices(urlPath, dataMap, headerMap);
|
JSONObject re = JSON.parseObject(result);
|
if (re.getString("errmsg").equals("ok")) {
|
String resultStr = re.getString("phone_info");
|
UserWxPhoneInfoVO phoneInfoVO = JSONObject.parseObject(resultStr, UserWxPhoneInfoVO.class);
|
if (phoneInfoVO != null) {
|
phone = phoneInfoVO.getPhoneNumber();
|
}
|
} else {
|
log.error("getUserPhone ERROR " + re.getString("errmsg"));
|
stringRedisTemplate.delete(appid + ":access_token");
|
}
|
} catch (Exception e) {
|
log.error("getUserPhone ERROR, accessToken = " + accessToken, e);
|
}
|
return phone;
|
}
|
|
|
/**
|
* 获取用户小程序openID
|
* @param code
|
* @return
|
*/
|
public static String getOpenId(String code)
|
{
|
//通过小程序端的code获取openid
|
StringBuilder urlPath = new StringBuilder(WEIXIN_JSCODE2SESSION_URL);
|
urlPath.append(String.format("?appid=%s", appid));
|
urlPath.append(String.format("&secret=%s", secret));
|
urlPath.append(String.format("&js_code=%s", code));
|
urlPath.append(String.format("&grant_type=%s", "authorization_code"));
|
//向微信发送请求
|
String result = HttpUtils.sendGet(urlPath.toString(), null);
|
//将获取的结果转化为JSONObject
|
JSONObject object = JSON.parseObject(result);
|
if(object != null && StringUtils.isNotBlank(object.getString("openid"))){
|
result = object.getString("openid");
|
}else{
|
throw new BaseException("获取用户openid失败!");
|
}
|
return result;
|
}
|
|
|
|
/**
|
* 小程序授权获取openID和unionID
|
*
|
* @return
|
*/
|
public static Map<String, String> oauth2GetUnion(String code) {
|
|
//通过小程序端的code获取openid
|
StringBuilder urlPath = new StringBuilder(WEIXIN_JSCODE2SESSION_URL);
|
urlPath.append(String.format("?appid=%s", appid));
|
urlPath.append(String.format("&secret=%s", secret));
|
urlPath.append(String.format("&js_code=%s", code));
|
urlPath.append(String.format("&grant_type=%s", "authorization_code"));
|
//向微信发送请求
|
String resultStr = HttpUtils.sendGet(urlPath.toString(), null);
|
|
Map<String, String> result = new HashMap<>();
|
//将获取的结果转化为JSONObject
|
JSONObject object = JSON.parseObject(resultStr);
|
if(object != null && StringUtils.isNotBlank(object.getString("openid"))){
|
result.put("wxOpenid", object.getString("openid"));
|
result.put("unionId", object.getString("unionid"));
|
result.put("sessionKey", object.getString("session_key"));
|
}else{
|
throw new BaseException("获取用户openid失败!");
|
}
|
return result;
|
|
}
|
|
|
}
|