Skip to content

Commit

Permalink
🆕 #2612 【企业微信】增加获取企业活跃成员数和通讯录异步导出的接口
Browse files Browse the repository at this point in the history
  • Loading branch information
zhongjun96 authored Apr 22, 2022
1 parent 5d0364f commit 1030115
Show file tree
Hide file tree
Showing 10 changed files with 325 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package me.chanjar.weixin.cp.api;

import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.bean.export.WxCpExportRequest;
import me.chanjar.weixin.cp.bean.export.WxCpExportResult;

/**
* 异步导出接口
*
* @author <a href="https://github.com/zhongjun96">zhongjun</a>
* @date 2022/4/21
**/
public interface WxCpExportService {

/**
* <pre>
*
* 导出成员
*
* 请求方式:POST(HTTPS)
* 请求地址:<a href="https://qyapi.weixin.qq.com/cgi-bin/export/simple_user?access_token=ACCESS_TOKEN">https://qyapi.weixin.qq.com/cgi-bin/export/simple_user?access_token=ACCESS_TOKEN</a>
*
* 文档地址:<a href="https://developer.work.weixin.qq.com/document/path/94849">https://developer.work.weixin.qq.com/document/path/94849</a>
* </pre>
*
* @param params 导出参数
* @return jobId 异步任务id
* @throws WxErrorException .
*/
String simpleUser(WxCpExportRequest params) throws WxErrorException;

/**
* <pre>
*
* 导出成员详情
*
* 请求方式:POST(HTTPS)
* 请求地址:<a href="https://qyapi.weixin.qq.com/cgi-bin/export/user?access_token=ACCESS_TOKEN">https://qyapi.weixin.qq.com/cgi-bin/export/user?access_token=ACCESS_TOKEN</a>
*
* 文档地址:<a href="https://developer.work.weixin.qq.com/document/path/94851">https://developer.work.weixin.qq.com/document/path/94851</a>
* </pre>
*
* @param params 导出参数
* @return jobId 异步任务id
* @throws WxErrorException .
*/
String user(WxCpExportRequest params) throws WxErrorException;

/**
* <pre>
*
* 导出部门
*
* 请求方式:POST(HTTPS)
* 请求地址:<a href="https://qyapi.weixin.qq.com/cgi-bin/export/department?access_token=ACCESS_TOKEN">https://qyapi.weixin.qq.com/cgi-bin/export/department?access_token=ACCESS_TOKEN</a>
*
* 文档地址:<a href="https://developer.work.weixin.qq.com/document/path/94852">https://developer.work.weixin.qq.com/document/path/94852</a>
* </pre>
*
* @param params 导出参数
* @return jobId 异步任务id
* @throws WxErrorException .
*/
String department(WxCpExportRequest params) throws WxErrorException;

/**
* <pre>
*
* 导出标签成员
*
* 请求方式:POST(HTTPS)
* 请求地址:<a href="https://qyapi.weixin.qq.com/cgi-bin/export/taguser?access_token=ACCESS_TOKEN">https://qyapi.weixin.qq.com/cgi-bin/export/taguser?access_token=ACCESS_TOKEN</a>
*
* 文档地址:<a href="https://developer.work.weixin.qq.com/document/path/94853">https://developer.work.weixin.qq.com/document/path/94853</a>
* </pre>
*
* @param params 导出参数
* @return jobId 异步任务id
* @throws WxErrorException .
*/
String tagUser(WxCpExportRequest params) throws WxErrorException;

/**
* <pre>
*
* 获取导出结果
*
* 请求方式:GET(HTTPS)
* 请求地址:<a href="https://qyapi.weixin.qq.com/cgi-bin/export/get_result?access_token=ACCESS_TOKEN&jobid=jobid_xxxxxxxxxxxxxxx">https://qyapi.weixin.qq.com/cgi-bin/export/get_result?access_token=ACCESS_TOKEN&jobid=jobid_xxxxxxxxxxxxxxx</a>
*
* 文档地址:<a href="https://developer.work.weixin.qq.com/document/path/94854">https://developer.work.weixin.qq.com/document/path/94854</a>
* 返回的url文件下载解密可参考 <a href="https://blog.csdn.net/a201692/article/details/123530529">CSDN</a>
* </pre>
*
* @param jobId 异步任务id
* @return 导出结果
* @throws WxErrorException .
*/
WxCpExportResult getResult(String jobId) throws WxErrorException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -511,4 +511,18 @@ public interface WxCpService extends WxService {
* @param kfService the kf service
*/
void setKfService(WxCpKfService kfService);

/**
* 获取异步导出服务
*
* @return 异步导出服务
*/
WxCpExportService getExportService();

/**
* 设置异步导出服务
*
* @param exportService 异步导出服务
*/
void setExportService(WxCpExportService exportService);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import me.chanjar.weixin.cp.bean.WxCpUser;
import me.chanjar.weixin.cp.bean.external.contact.WxCpExternalContactInfo;

import java.util.Date;
import java.util.List;
import java.util.Map;

Expand Down Expand Up @@ -199,4 +200,21 @@ public interface WxCpUserService {
* @throws WxErrorException .
*/
String getJoinQrCode(int sizeType) throws WxErrorException;

/**
* <pre>
*
* 获取企业活跃成员数。
*
* 请求方式:POST(HTTPS)
* 请求地址:<a href="https://qyapi.weixin.qq.com/cgi-bin/user/get_active_stat?access_token=ACCESS_TOKEN">https://qyapi.weixin.qq.com/cgi-bin/user/get_active_stat?access_token=ACCESS_TOKEN</a>
*
* 文档地址:<a href="https://developer.work.weixin.qq.com/document/path/92714">https://developer.work.weixin.qq.com/document/path/92714</a>
* </pre>
*
* @param date 具体某天的活跃人数,最长支持获取30天前数据
* @return join_qrcode 活跃成员数
* @throws WxErrorException .
*/
Integer getActiveStat(Date date) throws WxErrorException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH
private WxCpAgentWorkBenchService workBenchService = new WxCpAgentWorkBenchServiceImpl(this);
private WxCpKfService kfService = new WxCpKfServiceImpl(this);

private WxCpExportService exportService = new WxCpExportServiceImpl(this);

/**
* 全局的是否正在刷新access token的锁.
*/
Expand Down Expand Up @@ -588,4 +590,15 @@ public WxCpKfService getKfService() {
public void setKfService(WxCpKfService kfService) {
this.kfService = kfService;
}


@Override
public WxCpExportService getExportService() {
return exportService;
}

@Override
public void setExportService(WxCpExportService exportService) {
this.exportService = exportService;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package me.chanjar.weixin.cp.api.impl;

import com.google.gson.JsonObject;
import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.util.json.GsonParser;
import me.chanjar.weixin.cp.api.WxCpExportService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.export.WxCpExportRequest;
import me.chanjar.weixin.cp.bean.export.WxCpExportResult;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;

import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Export.*;

/**
* 异步导出接口
*
* @author <a href="https://github.com/zhongjun96">zhongjun</a>
* @date 2022/4/21
**/
@RequiredArgsConstructor
public class WxCpExportServiceImpl implements WxCpExportService {

private final WxCpService mainService;

@Override
public String simpleUser(WxCpExportRequest params) throws WxErrorException {
return export(SIMPLE_USER, params);
}

@Override
public String user(WxCpExportRequest params) throws WxErrorException {
return export(USER, params);
}

@Override
public String department(WxCpExportRequest params) throws WxErrorException {
return export(DEPARTMENT, params);
}

@Override
public String tagUser(WxCpExportRequest params) throws WxErrorException {
return export(TAG_USER, params);
}

@Override
public WxCpExportResult getResult(String jobId) throws WxErrorException {
String url = String.format(this.mainService.getWxCpConfigStorage().getApiUrl(GET_RESULT), jobId);
String responseContent = this.mainService.get(url, null);
return WxCpGsonBuilder.create().fromJson(responseContent, WxCpExportResult.class);
}

private String export(String path, WxCpExportRequest params) throws WxErrorException {
String url = this.mainService.getWxCpConfigStorage().getApiUrl(path);
String responseContent = this.mainService.post(url, params.toJson());
JsonObject tmpJson = GsonParser.parse(responseContent);
return tmpJson.get("jobid").getAsString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
import me.chanjar.weixin.cp.bean.WxCpUser;
import me.chanjar.weixin.cp.bean.external.contact.WxCpExternalContactInfo;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
import org.apache.commons.lang3.time.FastDateFormat;

import java.text.Format;
import java.util.Date;
import java.util.List;
import java.util.Map;

Expand All @@ -29,6 +32,8 @@
*/
@RequiredArgsConstructor
public class WxCpUserServiceImpl implements WxCpUserService {
private final Format dateFormat = FastDateFormat.getInstance("yyyy-MM-dd");

private final WxCpService mainService;

@Override
Expand Down Expand Up @@ -208,4 +213,14 @@ public String getJoinQrCode(int sizeType) throws WxErrorException {
JsonObject tmpJson = GsonParser.parse(responseContent);
return tmpJson.get("join_qrcode").getAsString();
}

@Override
public Integer getActiveStat(Date date) throws WxErrorException {
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("date", this.dateFormat.format(date));
String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_ACTIVE_STAT);
String responseContent = this.mainService.post(url, jsonObject.toString());
JsonObject tmpJson = GsonParser.parse(responseContent);
return tmpJson.get("active_cnt").getAsInt();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package me.chanjar.weixin.cp.bean.export;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;

import java.io.Serializable;

/**
* 异步导出参数
*
* @author zhongjun
* @date 2022/4/21
**/
@Data
public class WxCpExportRequest implements Serializable {
private static final long serialVersionUID = -8127528999898984359L;

/**
* base64encode的加密密钥,长度固定为43,base64decode之后即得到AESKey。加密方式采用AES-256-CBC方式,数据采用PKCS#7填充至32字节的倍数;IV初始向量大小为16字节,取AESKey前16字节,详见:<a href="http://tools.ietf.org/html/rfc2315">http://tools.ietf.org/html/rfc2315</a>
*/
@SerializedName("encoding_aeskey")
private String encodingAesKey;

/**
* 每块数据的部门数,支持范围[104,106],默认值为10^6
*/
@SerializedName("block_size")
private Integer blockSize;

/**
* 需要导出的标签
* 导出标签成员时使用
*/
@SerializedName("tagid")
private Integer tagId;

public String toJson() {
return WxCpGsonBuilder.create().toJson(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package me.chanjar.weixin.cp.bean.export;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import me.chanjar.weixin.cp.bean.WxCpBaseResp;

import java.util.List;

/**
* 异步导出响应
*
* @author zhongjun
* @date 2022/4/21
**/
@Data
@EqualsAndHashCode(callSuper = true)
public class WxCpExportResult extends WxCpBaseResp {
private static final long serialVersionUID = -8673839248829238966L;

/**
* 任务状态:0-未处理,1-处理中,2-完成,3-异常失败
*/
private Integer status;

@SerializedName("data_list")
private List<ExportData> dataList;


@Data
public static class ExportData {

/**
* 数据下载链接,支持指定Range头部分段下载。有效期2个小时
*/
private String url;

/**
* 密文数据大小
*/
private Integer size;

/**
* 密文数据md5
*/
private String md5;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ interface User {
String GET_USER_ID = "/cgi-bin/user/getuserid";
String GET_EXTERNAL_CONTACT = "/cgi-bin/crm/get_external_contact?external_userid=";
String GET_JOIN_QR_CODE = "/cgi-bin/corp/get_join_qrcode?size_type=";
String GET_ACTIVE_STAT = "/cgi-bin/user/get_active_stat";
}

interface ExternalContact {
Expand Down Expand Up @@ -310,4 +311,12 @@ interface Kf {
String CUSTOMER_BATCH_GET = "/cgi-bin/kf/customer/batchget";

}

interface Export {
String SIMPLE_USER = "/cgi-bin/export/simple_user";
String USER = "/cgi-bin/export/user";
String DEPARTMENT = "/cgi-bin/export/department";
String TAG_USER = "/cgi-bin/export/taguser";
String GET_RESULT = "/cgi-bin/export/get_result?jobid=%s";
}
}
Loading

0 comments on commit 1030115

Please sign in to comment.