mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2025-04-05 17:38:05 +08:00
🆕 #2612 【企业微信】增加获取企业活跃成员数和通讯录异步导出的接口
This commit is contained in:
parent
5d0364f6d2
commit
1030115751
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import me.chanjar.weixin.cp.bean.WxCpInviteResult;
|
||||
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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
@ -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的锁.
|
||||
*/
|
||||
@ -588,4 +590,15 @@ public abstract class BaseWxCpServiceImpl<H, P> implements WxCpService, RequestH
|
||||
public void setKfService(WxCpKfService kfService) {
|
||||
this.kfService = kfService;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public WxCpExportService getExportService() {
|
||||
return exportService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExportService(WxCpExportService exportService) {
|
||||
this.exportService = exportService;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -14,7 +14,10 @@ import me.chanjar.weixin.cp.bean.WxCpInviteResult;
|
||||
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;
|
||||
|
||||
@ -29,6 +32,8 @@ import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.User.*;
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class WxCpUserServiceImpl implements WxCpUserService {
|
||||
private final Format dateFormat = FastDateFormat.getInstance("yyyy-MM-dd");
|
||||
|
||||
private final WxCpService mainService;
|
||||
|
||||
@Override
|
||||
@ -208,4 +213,14 @@ public class WxCpUserServiceImpl implements WxCpUserService {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -215,6 +215,7 @@ public interface WxCpApiPathConsts {
|
||||
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 {
|
||||
@ -310,4 +311,12 @@ public interface WxCpApiPathConsts {
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package me.chanjar.weixin.cp.api.impl;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -121,4 +122,11 @@ public class WxCpUserServiceImplTest {
|
||||
@Test
|
||||
public void testGetExternalContact() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetActiveStat() throws WxErrorException {
|
||||
Integer activeStat = this.wxCpService.getUserService().getActiveStat(new Date());
|
||||
System.out.printf("active stat: %d", activeStat);
|
||||
assertNotNull(activeStat);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user