|
|
|
|
@ -102,23 +102,21 @@ public class MiniProgramUtils {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取 acceess_token
|
|
|
|
|
* 微信小程序 / 微信公众号 获取地址是一样得,但是 要用各自得 appid 和 secret
|
|
|
|
|
* <p>
|
|
|
|
|
* 将 access_token 保存在 redis,官方定义说 access_token 的有效期暂定为 2个小时,
|
|
|
|
|
* 使用注意事项: 从 redis 获取 access_token,存在则未过期,不存在则过期了,重新获取 access_token
|
|
|
|
|
*
|
|
|
|
|
* @return
|
|
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
|
|
|
|
public static String getAccessToken() throws Exception {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* TODO: 将 access_token 保存在 redis,官方定义说 access_token 的有效期暂定为 2个小时,使用注意事项:
|
|
|
|
|
* 1、从 redis 获取 access_token,存在则未过期,不存在则过期了,重新获取 access_token
|
|
|
|
|
*/
|
|
|
|
|
String accessToken = redisService.getCacheObject(CacheConstants.WX_ACCESS_TOKEN_CACHE);
|
|
|
|
|
public static String getAccessToken(String appid, String secret, String cacheKey) throws Exception {
|
|
|
|
|
String accessToken = redisService.getCacheObject(cacheKey);
|
|
|
|
|
if (StringUtils.isBlank(accessToken)) {
|
|
|
|
|
// 获取 access_token
|
|
|
|
|
Map<String, String> params = new HashMap();
|
|
|
|
|
WxParameterSetting wxParameterSetting = wxParameterSettingMapper.selectWxParameterSettingById(1L);
|
|
|
|
|
params.put("appid", wxParameterSetting.getAppid());
|
|
|
|
|
params.put("secret", wxParameterSetting.getAppkey());
|
|
|
|
|
params.put("appid", appid);
|
|
|
|
|
params.put("secret", secret);
|
|
|
|
|
params.put("grant_type", "client_credential");
|
|
|
|
|
String result = HttpClientUtils.getParameters(wxConfig.getAccessTokenUrl(), params);
|
|
|
|
|
logger.info("请求微信服务器获取access_token返回结果:{}", result);
|
|
|
|
|
@ -128,7 +126,7 @@ public class MiniProgramUtils {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
// 保存缓存
|
|
|
|
|
redisService.setCacheObject(CacheConstants.WX_ACCESS_TOKEN_CACHE,
|
|
|
|
|
redisService.setCacheObject(cacheKey,
|
|
|
|
|
wxAccessTokenRet.getAccess_token(), CacheConstants.WX_ACCESS_TOKEN_EXPIRATION, TimeUnit.MINUTES);
|
|
|
|
|
return wxAccessTokenRet.getAccess_token();
|
|
|
|
|
}
|
|
|
|
|
@ -136,6 +134,8 @@ public class MiniProgramUtils {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 注意 要使用 微信小程序得 appid 和 appKey
|
|
|
|
|
*
|
|
|
|
|
* @param code
|
|
|
|
|
* @return <p></p>
|
|
|
|
|
* errcode number 错误码
|
|
|
|
|
@ -147,7 +147,8 @@ public class MiniProgramUtils {
|
|
|
|
|
* countryCode string 区号
|
|
|
|
|
*/
|
|
|
|
|
public static String getPhone(String code) throws Exception {
|
|
|
|
|
String accessToken = getAccessToken();
|
|
|
|
|
WxParameterSetting wxParameterSetting = wxParameterSettingMapper.selectWxParameterSettingById(1L);
|
|
|
|
|
String accessToken = getAccessToken(wxParameterSetting.getAppid(), wxParameterSetting.getAppkey(), CacheConstants.WX_MINI_PROGRAM_ACCESS_TOKEN_CACHE);
|
|
|
|
|
if (StringUtils.isBlank(accessToken)) {
|
|
|
|
|
throw new ServiceException("获取用户手机号码失败");
|
|
|
|
|
}
|
|
|
|
|
@ -166,7 +167,7 @@ public class MiniProgramUtils {
|
|
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
|
|
|
|
public static OfficialAccountUserRet obtainWxOfficialAccountUser(String nextOpenid) throws Exception {
|
|
|
|
|
String accessToken = getAccessToken();
|
|
|
|
|
String accessToken = getAccessToken(wxConfig.getOfficialAccountAppid(), wxConfig.getOfficialAccountAppSecret(), CacheConstants.WX_OFFICIAL_ACCOUNT_ACCESS_TOKEN_CACHE);
|
|
|
|
|
if (StringUtils.isBlank(accessToken)) {
|
|
|
|
|
logger.error("获取关注微信公众号用户列表失败,获取accessToken失败!");
|
|
|
|
|
throw new ServiceException("操作失败");
|
|
|
|
|
@ -180,7 +181,7 @@ public class MiniProgramUtils {
|
|
|
|
|
String result = HttpClientUtils.getParameters(wxConfig.getObtainWxOfficialAccountUserUrl(), params);
|
|
|
|
|
logger.info("请求微信服务器获取关注微信公众号的用户列表:{}", result);
|
|
|
|
|
OfficialAccountUserRet officialAccountUserRet = JSON.parseObject(result, OfficialAccountUserRet.class);
|
|
|
|
|
if (officialAccountUserRet.getErrcode() != 0) {
|
|
|
|
|
if (officialAccountUserRet.getErrcode() != null) {
|
|
|
|
|
logger.error("获取 关注微信公众号的用户列表 失败: {}", officialAccountUserRet.getErrmsg());
|
|
|
|
|
throw new ServiceException("操作失败");
|
|
|
|
|
}
|
|
|
|
|
@ -192,18 +193,19 @@ public class MiniProgramUtils {
|
|
|
|
|
* TODO: officialAccountUserReqList 最多支持 100 条
|
|
|
|
|
*/
|
|
|
|
|
public static OfficialAccountUserDetailRet ObtainUserInfoByOpenid(List<OfficialAccountUserReq> officialAccountUserReqList) throws Exception {
|
|
|
|
|
String accessToken = getAccessToken();
|
|
|
|
|
String accessToken = getAccessToken(wxConfig.getOfficialAccountAppid(), wxConfig.getOfficialAccountAppSecret(), CacheConstants.WX_OFFICIAL_ACCOUNT_ACCESS_TOKEN_CACHE);
|
|
|
|
|
if (StringUtils.isBlank(accessToken)) {
|
|
|
|
|
logger.error("获取关注微信公众号用户的unionid,获取accessToken失败!");
|
|
|
|
|
throw new ServiceException("操作失败");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Map<String, String> params = new HashMap();
|
|
|
|
|
params.put("user_list", JSON.toJSONString(officialAccountUserReqList));
|
|
|
|
|
String result = HttpClientUtils.postParameters(wxConfig.getObtainUserInfoByOpenidUrl() + "access_token=" + accessToken, params);
|
|
|
|
|
Map<String, Object> params = new HashMap();
|
|
|
|
|
params.put("user_list", officialAccountUserReqList);
|
|
|
|
|
// String result = HttpClientUtils.postJsonParameters(wxConfig.getObtainUserInfoByOpenidUrl() + "?access_token=" + accessToken, JSON.toJSONString(params));
|
|
|
|
|
String result = HttpClientUtils.postParameters(wxConfig.getObtainUserInfoByOpenidUrl() + "?access_token=" + accessToken, JSON.toJSONString(params));
|
|
|
|
|
logger.info("请求微信服务器获获取 关注微信公众号用户的 unionid列表:{}", result);
|
|
|
|
|
OfficialAccountUserDetailRet officialAccountUserDetailRet = JSON.parseObject(result, OfficialAccountUserDetailRet.class);
|
|
|
|
|
if (officialAccountUserDetailRet.getErrcode() != 0) {
|
|
|
|
|
if (officialAccountUserDetailRet.getErrcode() != null) {
|
|
|
|
|
logger.error("获取 关注微信公众号的用户列表 失败: {}", officialAccountUserDetailRet.getErrmsg());
|
|
|
|
|
throw new ServiceException("操作失败");
|
|
|
|
|
}
|
|
|
|
|
@ -221,10 +223,6 @@ public class MiniProgramUtils {
|
|
|
|
|
while (true) {
|
|
|
|
|
// 1、获取关注微信公众号的用户列表
|
|
|
|
|
OfficialAccountUserRet officialAccountUserRet = obtainWxOfficialAccountUser(null);
|
|
|
|
|
if (officialAccountUserRet.getErrcode() != 0) {
|
|
|
|
|
logger.error("获取微信用户列表失败: {}", officialAccountUserRet.getErrmsg());
|
|
|
|
|
throw new ServiceException("获取微信用户列表失败");
|
|
|
|
|
}
|
|
|
|
|
if (officialAccountUserRet.getCount() == null || officialAccountUserRet.getCount() == 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
@ -234,13 +232,13 @@ public class MiniProgramUtils {
|
|
|
|
|
logger.info("微信公众号关注列表:{}", openidList);
|
|
|
|
|
|
|
|
|
|
// 2、获取关注微信公众号的unionid
|
|
|
|
|
int pageSize = 100;
|
|
|
|
|
int page = (int) Math.ceil(officialAccountUserRet.getCount() / pageSize);
|
|
|
|
|
int pageSize = 10;
|
|
|
|
|
int page = officialAccountUserRet.getTotal() % pageSize == 0 ? officialAccountUserRet.getTotal() / pageSize : officialAccountUserRet.getTotal() / pageSize + 1;
|
|
|
|
|
if (page > 0) {
|
|
|
|
|
List<String> pageOpenidList = officialAccountUserRet.getOpenidList();
|
|
|
|
|
for (int pageNo = 1; pageNo <= page; pageNo++) {
|
|
|
|
|
// 构建分页集合
|
|
|
|
|
List<String> pageList = pageOpenidList.stream().skip((pageNo - 1) * 100).limit(pageSize).collect(Collectors.toList());
|
|
|
|
|
List<String> pageList = pageOpenidList.stream().skip((pageNo - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
|
|
|
|
|
// 获取 unionid 集合
|
|
|
|
|
List<OfficialAccountUserReq> officialAccountUserReqList = new ArrayList<>();
|
|
|
|
|
for (String openid : pageList) {
|
|
|
|
|
@ -250,9 +248,12 @@ public class MiniProgramUtils {
|
|
|
|
|
OfficialAccountUserDetailRet officialAccountUserDetailRet = ObtainUserInfoByOpenid(officialAccountUserReqList);
|
|
|
|
|
|
|
|
|
|
// 3、判断当前unionid是否在关注者列表
|
|
|
|
|
return officialAccountUserDetailRet.getUser_info_list().contains(unionId);
|
|
|
|
|
if (officialAccountUserDetailRet.isContainUnionid(unionId)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 4、 查完全部,未找到退出
|
|
|
|
|
if (StringUtils.isBlank(nextOpenid) || officialAccountUserRet.getTotal() == currentTotal) {
|
|
|
|
|
break;
|
|
|
|
|
|