判断是否关注微信公众

master
382696293@qq.com 2 years ago
parent fbbd75e057
commit 6913a2f9a2

@ -27,6 +27,11 @@ public class WxConfig {
private String accessTokenUrl;
private String obtainWxOfficialAccountUserUrl;
private String ObtainUserInfoByOpenidUrl;
public String getLoginUrl() {
return loginUrl;
@ -51,4 +56,20 @@ public class WxConfig {
public void setAccessTokenUrl(String accessTokenUrl) {
this.accessTokenUrl = accessTokenUrl;
}
public String getObtainWxOfficialAccountUserUrl() {
return obtainWxOfficialAccountUserUrl;
}
public void setObtainWxOfficialAccountUserUrl(String obtainWxOfficialAccountUserUrl) {
this.obtainWxOfficialAccountUserUrl = obtainWxOfficialAccountUserUrl;
}
public String getObtainUserInfoByOpenidUrl() {
return ObtainUserInfoByOpenidUrl;
}
public void setObtainUserInfoByOpenidUrl(String obtainUserInfoByOpenidUrl) {
ObtainUserInfoByOpenidUrl = obtainUserInfoByOpenidUrl;
}
}

@ -40,4 +40,14 @@ public class WxNoRemindController extends BaseController {
return AjaxResult.success();
}
/**
*
*
* @return
*/
@GetMapping("/isAttentionOfficialAccount")
public R isAttentionOfficialAccount() throws Exception {
return R.ok(wxNoRemindService.isAttentionOfficialAccount());
}
}

@ -0,0 +1,167 @@
package com.flossom.miniProgram.domain.vo;
import java.util.List;
/**
*
*/
public class OfficialAccountUserDetailRet {
private List<userInfoList> user_info_list;
private Integer errcode;
private String errmsg;
public OfficialAccountUserDetailRet() {
}
public OfficialAccountUserDetailRet(List<userInfoList> user_info_list, Integer errcode, String errmsg) {
this.user_info_list = user_info_list;
this.errcode = errcode;
this.errmsg = errmsg;
}
public List<userInfoList> getUser_info_list() {
return user_info_list;
}
public void setUser_info_list(List<userInfoList> user_info_list) {
this.user_info_list = user_info_list;
}
public Integer getErrcode() {
return errcode;
}
public void setErrcode(Integer errcode) {
this.errcode = errcode;
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
class userInfoList {
private Integer subscribe;
private String openid;
private String language;
private String subscribe_time;
private String unionid;
private String remark;
private Integer groupid;
private List<Integer> tagid_list;
private String subscribe_scene;
private String qr_scene;
private String qr_scene_str;
public userInfoList() {
}
public userInfoList(Integer subscribe, String openid, String language, String subscribe_time, String unionid, String remark, Integer groupid, List<Integer> tagid_list, String subscribe_scene, String qr_scene, String qr_scene_str) {
this.subscribe = subscribe;
this.openid = openid;
this.language = language;
this.subscribe_time = subscribe_time;
this.unionid = unionid;
this.remark = remark;
this.groupid = groupid;
this.tagid_list = tagid_list;
this.subscribe_scene = subscribe_scene;
this.qr_scene = qr_scene;
this.qr_scene_str = qr_scene_str;
}
public Integer getSubscribe() {
return subscribe;
}
public void setSubscribe(Integer subscribe) {
this.subscribe = subscribe;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getSubscribe_time() {
return subscribe_time;
}
public void setSubscribe_time(String subscribe_time) {
this.subscribe_time = subscribe_time;
}
public String getUnionid() {
return unionid;
}
public void setUnionid(String unionid) {
this.unionid = unionid;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Integer getGroupid() {
return groupid;
}
public void setGroupid(Integer groupid) {
this.groupid = groupid;
}
public List<Integer> getTagid_list() {
return tagid_list;
}
public void setTagid_list(List<Integer> tagid_list) {
this.tagid_list = tagid_list;
}
public String getSubscribe_scene() {
return subscribe_scene;
}
public void setSubscribe_scene(String subscribe_scene) {
this.subscribe_scene = subscribe_scene;
}
public String getQr_scene() {
return qr_scene;
}
public void setQr_scene(String qr_scene) {
this.qr_scene = qr_scene;
}
public String getQr_scene_str() {
return qr_scene_str;
}
public void setQr_scene_str(String qr_scene_str) {
this.qr_scene_str = qr_scene_str;
}
}
}

@ -0,0 +1,32 @@
package com.flossom.miniProgram.domain.vo;
/**
*
*/
public class OfficialAccountUserReq {
private String openid;
private String lang = "zh_CN";
public OfficialAccountUserReq() {
}
public OfficialAccountUserReq(String openid) {
this.openid = openid;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getLang() {
return lang;
}
public void setLang(String lang) {
this.lang = lang;
}
}

@ -0,0 +1,100 @@
package com.flossom.miniProgram.domain.vo;
import java.util.List;
/**
*
*/
public class OfficialAccountUserRet {
private Integer total;
private Integer count;
private data data;
private String next_openid;
private Integer errcode;
private String errmsg;
public OfficialAccountUserRet() {
}
public OfficialAccountUserRet(Integer total, Integer count, OfficialAccountUserRet.data data, String next_openid, Integer errcode, String errmsg) {
this.total = total;
this.count = count;
this.data = data;
this.next_openid = next_openid;
this.errcode = errcode;
this.errmsg = errmsg;
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
public OfficialAccountUserRet.data getData() {
return data;
}
public void setData(OfficialAccountUserRet.data data) {
this.data = data;
}
public String getNext_openid() {
return next_openid;
}
public void setNext_openid(String next_openid) {
this.next_openid = next_openid;
}
public Integer getErrcode() {
return errcode;
}
public void setErrcode(Integer errcode) {
this.errcode = errcode;
}
public String getErrmsg() {
return errmsg;
}
public void setErrmsg(String errmsg) {
this.errmsg = errmsg;
}
public List<String> getOpenidList() {
return getData().getOpenid();
}
class data {
private List<String> openid;
public data() {
}
public data(List<String> openid) {
this.openid = openid;
}
public List<String> getOpenid() {
return openid;
}
public void setOpenid(List<String> openid) {
this.openid = openid;
}
}
}

@ -1,6 +1,7 @@
package com.flossom.miniProgram.service;
import com.flossom.common.core.domain.entity.WxNoRemindRecord;
import com.sun.org.apache.xpath.internal.operations.Bool;
public interface IWxNoRemindService {
@ -8,4 +9,6 @@ public interface IWxNoRemindService {
void closeOfficialAccount();
Boolean isAttentionOfficialAccount() throws Exception;
}

@ -7,6 +7,7 @@ import com.flossom.common.core.utils.DateUtils;
import com.flossom.common.core.web.domain.AjaxResult;
import com.flossom.common.security.utils.SecurityUtils;
import com.flossom.miniProgram.service.IWxNoRemindService;
import com.flossom.miniProgram.utils.MiniProgramUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -28,4 +29,9 @@ public class WxNoRemindServiceImpl implements IWxNoRemindService {
wxNoRemindRecord.setCreateTime(DateUtils.getNowDate());
wxNoRemindRecordMapper.insertWxNoRemindRecord(wxNoRemindRecord);
}
@Override
public Boolean isAttentionOfficialAccount() throws Exception {
return MiniProgramUtils.isAttentionOfficialAccount(SecurityUtils.getLoginUser().getWxUserMember().getUnionid());
}
}

@ -100,13 +100,8 @@ public class WxUserMemberServiceImpl implements IWxUserMemberService {
@Override
public String upgradeMember(String code) throws Exception {
String accessToken = MiniProgramUtils.getAccessToken(SecurityUtils.getLoginUser().getWxUserMember().getOpenid());
if (StringUtils.isBlank(accessToken)) {
throw new ServiceException("获取用户手机号码失败");
}
// 获取手机号
String result = MiniProgramUtils.getPhone(code, accessToken);
String result = MiniProgramUtils.getPhone(code);
logger.info("请求微信服务器获取手机号码返回结果:{}", result);
WxCode2PhoneRet wxCode2PhoneRet = JSON.parseObject(result, WxCode2PhoneRet.class);
if (wxCode2PhoneRet.getErrcode() != 0) {

@ -3,19 +3,26 @@ package com.flossom.miniProgram.utils;
import com.alibaba.fastjson.JSON;
import com.flossom.common.core.constant.CacheConstants;
import com.flossom.common.core.domain.entity.WxParameterSetting;
import com.flossom.common.core.exception.ServiceException;
import com.flossom.common.core.mapper.WxParameterSettingMapper;
import com.flossom.common.core.utils.StringUtils;
import com.flossom.common.redis.service.RedisService;
import com.flossom.miniProgram.config.properties.WxConfig;
import com.flossom.miniProgram.domain.vo.OfficialAccountUserDetailRet;
import com.flossom.miniProgram.domain.vo.OfficialAccountUserReq;
import com.flossom.miniProgram.domain.vo.OfficialAccountUserRet;
import com.flossom.miniProgram.domain.vo.WxAccessTokenRet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
*
@ -94,29 +101,18 @@ public class MiniProgramUtils {
}
/**
* @param code
* @return <p></p>
* errcode number
* errmsg string
* phone_info object
*
* phoneNumber string
* purePhoneNumber string
* countryCode string
* acceess_token
*
* @return
* @throws Exception
*/
public static String getPhone(String code, String accessToken) throws Exception {
Map<String, String> params = new HashMap();
params.put("code", code);
return HttpClientUtils.postParameters(wxConfig.getObtainPhoneUrl() + "?access_token=" + accessToken, JSON.toJSONString(params));
}
public static String getAccessToken(String openid) 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 + openid);
String accessToken = redisService.getCacheObject(CacheConstants.WX_ACCESS_TOKEN_CACHE);
if (StringUtils.isBlank(accessToken)) {
// 获取 access_token
Map<String, String> params = new HashMap();
@ -132,10 +128,138 @@ public class MiniProgramUtils {
return null;
}
// 保存缓存
redisService.setCacheObject(CacheConstants.WX_ACCESS_TOKEN_CACHE + openid,
redisService.setCacheObject(CacheConstants.WX_ACCESS_TOKEN_CACHE,
wxAccessTokenRet.getAccess_token(), CacheConstants.WX_ACCESS_TOKEN_EXPIRATION, TimeUnit.MINUTES);
return wxAccessTokenRet.getAccess_token();
}
return accessToken;
}
/**
* @param code
* @return <p></p>
* errcode number
* errmsg string
* phone_info object
*
* phoneNumber string
* purePhoneNumber string
* countryCode string
*/
public static String getPhone(String code) throws Exception {
String accessToken = getAccessToken();
if (StringUtils.isBlank(accessToken)) {
throw new ServiceException("获取用户手机号码失败");
}
Map<String, String> params = new HashMap();
params.put("code", code);
return HttpClientUtils.postParameters(wxConfig.getObtainPhoneUrl() + "?access_token=" + accessToken, JSON.toJSONString(params));
}
/**
*
* TODO: 10000OpenID
*
* @param nextOpenid openid
* @return
* @throws Exception
*/
public static OfficialAccountUserRet obtainWxOfficialAccountUser(String nextOpenid) throws Exception {
String accessToken = getAccessToken();
if (StringUtils.isBlank(accessToken)) {
logger.error("获取关注微信公众号用户列表失败获取accessToken失败");
throw new ServiceException("操作失败");
}
Map<String, String> params = new HashMap();
params.put("access_token", accessToken);
if (StringUtils.isNotBlank(nextOpenid)) {
params.put("next_openid", nextOpenid);
}
String result = HttpClientUtils.getParameters(wxConfig.getObtainWxOfficialAccountUserUrl(), params);
logger.info("请求微信服务器获取关注微信公众号的用户列表:{}", result);
OfficialAccountUserRet officialAccountUserRet = JSON.parseObject(result, OfficialAccountUserRet.class);
if (officialAccountUserRet.getErrcode() != 0) {
logger.error("获取 关注微信公众号的用户列表 失败: {}", officialAccountUserRet.getErrmsg());
throw new ServiceException("操作失败");
}
return officialAccountUserRet;
}
/**
* unionid
* TODO: officialAccountUserReqList 100
*/
public static OfficialAccountUserDetailRet ObtainUserInfoByOpenid(List<OfficialAccountUserReq> officialAccountUserReqList) throws Exception {
String accessToken = getAccessToken();
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);
logger.info("请求微信服务器获获取 关注微信公众号用户的 unionid列表{}", result);
OfficialAccountUserDetailRet officialAccountUserDetailRet = JSON.parseObject(result, OfficialAccountUserDetailRet.class);
if (officialAccountUserDetailRet.getErrcode() != 0) {
logger.error("获取 关注微信公众号的用户列表 失败: {}", officialAccountUserDetailRet.getErrmsg());
throw new ServiceException("操作失败");
}
return officialAccountUserDetailRet;
}
/**
*
*
* @return
*/
public static Boolean isAttentionOfficialAccount(String unionId) throws Exception {
String nextOpenid = null;
Integer currentTotal = 0;
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;
}
currentTotal += officialAccountUserRet.getCount();
nextOpenid = officialAccountUserRet.getNext_openid();
List<String> openidList = officialAccountUserRet.getOpenidList();
logger.info("微信公众号关注列表:{}", openidList);
// 2、获取关注微信公众号的unionid
int pageSize = 100;
int page = (int) Math.ceil(officialAccountUserRet.getCount() / pageSize);
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());
// 获取 unionid 集合
List<OfficialAccountUserReq> officialAccountUserReqList = new ArrayList<>();
for (String openid : pageList) {
OfficialAccountUserReq officialAccountUserReq = new OfficialAccountUserReq(openid);
officialAccountUserReqList.add(officialAccountUserReq);
}
OfficialAccountUserDetailRet officialAccountUserDetailRet = ObtainUserInfoByOpenid(officialAccountUserReqList);
// 3、判断当前unionid是否在关注者列表
return officialAccountUserDetailRet.getUser_info_list().contains(unionId);
}
}
// 4、 查完全部,未找到退出
if (StringUtils.isBlank(nextOpenid) || officialAccountUserRet.getTotal() == currentTotal) {
break;
}
}
return false;
}
}

Loading…
Cancel
Save