职贝云数AI新零售门户
标题:
企微提取用户unionid
[打印本页]
作者:
jQGCPeAbH
时间:
2022-12-30 14:58
标题:
企微提取用户unionid
前言
业务需求 需求根据提取企业微信一切员工所拥有客户 也就是提取unionid 特此写个一站式工具类 一次性生成
pom
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.73</version></dependency><!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version><scope>provided</scope></dependency>
复制代码
工具类
package ins.platfrom.test;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import ins.platfrom.dao.WXUserVoMapper;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.web.client.RestTemplate;import java.util.*;/**
* 企微员工所绑定用户提取
* @author zhangle
* @create 2021-04-21 10:41
*/@Slf4j@ServicepublicclassQiWeiTest{/**
* 微信token公共变量
*/private String access_token;/**
* HTTP线程池 这个假如需求代理需求配置 看我博客
* https://blog.csdn.net/HezhezhiyuLe/article/details/92395041
*/@Autowiredprivate RestTemplate bean;/**
* 最终获得用户信息保存接口 自定义 不用删除
*/@Autowiredprivate WXUserVoMapper wxUserVoMapper;/**
* corpid corpsecret 填本人的公司
* 获取token get
* https://work.weixin.qq.com/api/doc/90000/90135/91039 参考文档
*/privatefinal String tokenurl ="https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=10086&corpsecret=10010";/**
* 获取部门 post 可省略ID 不填默许拉取当前权限下可见部门
* https://work.weixin.qq.com/api/doc/90000/90135/90208
*/private String depturl ="https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token=";/**
* 批量获取客户概况 post
* https://work.weixin.qq.com/api/doc/90000/90135/92994
*/private String userurl ="https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user?access_token=";/**
* 企微当前最高权限获取部门一切成员 department_id=1 fetch_child=1 递归 =0当前部门
* https://work.weixin.qq.com/api/doc/90000/90135/90200
*/private String deptuserurl ="https://qyapi.weixin.qq.com/cgi-bin/user/simplelist?fetch_child=1&department_id=";/**
* 1
* 获取企微token
* @return token
*/public String getToken(){
String tokenstr = bean.getForEntity(tokenurl, String.class).getBody();
log.info("获取token:"+tokenstr);
JSONObject tokenjson =parseStr(tokenstr);
access_token=tokenjson.get("access_token").toString();return access_token;}/**
* 0
*/publicvoidstart(){//获取token
access_token=getToken();//获得父节点
Set<String> treeDept =findTreeDept();if(treeDept==null||treeDept.size()==0){
log.info("查询部门为空");return;}//迭代父节点for(String deptparent : treeDept){//父节点下一切员工 递归
Set<String> deptUserByDId =findDeptUserByDId(deptparent);int unionidByUserId =findUnionidByUserId(deptUserByDId);
log.info("当前"+deptparent+"部门员工客户人数:"+unionidByUserId);}}/**
* 2
* 获取当前企微最高节点部门ID
* 当本人不是当前公众号最高权限即不可以查看一切部门时运用
* @return 最高父节点
*/public Set<String>findTreeDept(){
String deptstr = bean.getForEntity(depturl+access_token, String.class).getBody();
deptstr=iflegal(deptstr);if(deptstr==null||"".equals(deptstr)){
log.info("获取部门失败");return null;}
JSONObject jsonObject =parseStr(deptstr);//获取一切部门
String dept = jsonObject.get("department").toString();
List<JSONObject> departments = JSON.parseArray(dept, JSONObject.class);returnrecursiondept(departments);}/**
* 判别微信接口前往能否合法
* @param resp
* @return
*/public String iflegal(String resp){if(resp.contains(""errcode":0")){return resp;}
log.info("失敗預警:"+resp);if(resp.contains(""errcode":40014")||resp.contains(" "errcode":42001")){getToken();
log.info("恢复:"+access_token);}return null;}/**
* 转换企微前往数据为json对象
* @param str
* @return
*/public JSONObject parseStr(String str){return JSON.parseObject(str);}/**
* 查询部门父ID
* @param departments 当前企微权限下一切部门 包含父子级
* @return 最高父节点
*/public Set<String>recursiondept(List<JSONObject> departments){
Set<String> deptid =newHashSet<>();
Set<String> treedept =newHashSet<>();for(JSONObject department : departments){
deptid.add(department.getString("id"));}for(JSONObject department : departments){
String parentid = department.getString("parentid");//找不到父ID即为最高节点if(!deptid.contains(parentid)){
treedept.add(department.getString("id"));}}return treedept;}/**
* 3
* 经过部门ID查询当前部门员工 递归获取当前部门一切员工
* @param deptId 部门ID
* @return
*/public Set<String>findDeptUserByDId(String deptId){//获取当前部门下的一切员工 包括子节点
String deptuserstr = bean.getForEntity(deptuserurl+deptId+"&access_token="+access_token, String.class).getBody();
deptuserstr=iflegal(deptuserstr);if(deptuserstr==null||"".equals(deptuserstr)){
log.info("获取部门成员失败");return null;}
JSONObject jsonObject =parseStr(deptuserstr);
String dept = jsonObject.get("userlist").toString();
List<JSONObject> departments = JSON.parseArray(dept, JSONObject.class);if(departments==null||departments.size()==0){return null;}//去重
Set<String> userids =newHashSet<>();for(JSONObject department : departments){
userids.add(department.getString("userid"));}
log.info("用户ID总数:"+userids.size());return userids;}/**
* 4
* 企微员工经过员工ID查找用户unionid
* @param userids 当前部门一切员工
* @return
*/publicintfindUnionidByUserId(Set<String> userids){//用户unionid集合 一切用户 包含反复 假如父级部门平行有多个 用户能够会反复 建议把人员再次汇总 我是由于确定父级只要一个有最大权限才这么写int count=0;int size = userids.size();//去重总用户(一个客户加了N个员工) 这个存储值几十万没成绩 SQL写对加主键一把就成功
Set<String> unionids =newHashSet<>();int formum=0;for(String userid : userids){
formum++;if(formum%1000==0){
log.info("循环到:"+formum+"/"+unionids.size()+"/"+size);}//实时更新token 防止失效
Set<String> personnelUsers =handleUserByUserId(userid,userurl+access_token);
unionids.addAll(personnelUsers);
count+=personnelUsers.size();}//用户unionid集合有值就保存 可以根据业务需求 自行决议存储 IO SQL
ArrayList<String> unionidarr =newArrayList<>();for(String unionid : unionids){
unionidarr.add(unionid);//根据本人数据库才能分批次插入 一次插入几十万容易IO溢出if(unionidarr.size()==1000){
Integer insertnum = wxUserVoMapper.insertQiWei(unionidarr);
log.info(insertnum+"");
unionidarr.clear();}}if(unionidarr.size()>0){
Integer insertnum = wxUserVoMapper.insertQiWei(unionidarr);
log.info(insertnum+"");}
log.info(" 员工总用户数:"+unionids.size()+"交叉结果集:"+count);return unionids.size();}/**
* 处理单个用户所拥有的全部客户
* @param userid 用户ID
* @param url 实时链接
* @return
*/public Set<String>handleUserByUserId(String userid,String url){
Set<String> unionids =newHashSet<>();
Map<String, Object> params =newHashMap<>();
params.put("userid",userid);//企微最大分页量
params.put("limit",100);
String openid ="";//封顶值 一个员工10W用户for(int i =0; i <1000; i++){
params.put("cursor",openid);
String resp = bean.postForEntity(url, params, String.class).getBody();
resp=iflegal(resp);if(resp == null ||"".equals(resp)){
log.info("不合法前往:"+userid);break;}if(i==999){
log.info("员工用户超限:"+userid);}
JSONObject jsonObject =parseStr(resp);//员工客户列表
List<JSONObject> external_contact_list = JSON.parseArray(jsonObject.get("external_contact_list").toString(), JSONObject.class);if(external_contact_list==null||external_contact_list.size()==0){break;}for(JSONObject customer : external_contact_list){
String external_contact = customer.getString("external_contact");if(external_contact==null||"".equals(external_contact)){break;}//用户粗略概况
JSONObject customercontact =parseStr(external_contact);if(customercontact==null){break;}// 可以拿到 客户微信名 name 头像 avatar 性别 gender 标识 unionid 类型 type更多概况需求换链接
String unionid = customercontact.getString("unionid");if(unionid!=null&&!"".equals(unionid)){
unionids.add(unionid);}}
String next_cursor = jsonObject.getString("next_cursor");if("".equals(next_cursor)){break;}else{//迭代
openid=next_cursor;}}return unionids;}}
复制代码
欢迎光临 职贝云数AI新零售门户 (https://www.taojin168.com/cloud/)
Powered by Discuz! X3.5