diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpExternalContactService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpExternalContactService.java index 3f5ee3677..3ceee6490 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpExternalContactService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpExternalContactService.java @@ -132,6 +132,31 @@ public interface WxCpExternalContactService { */ WxCpUserExternalContactInfo getContactDetail(String userId) throws WxErrorException; + /** + * 批量获取客户详情. + *
+   *
+   * 企业/第三方可通过此接口获取指定成员添加的客户信息列表。
+   *
+   * 请求方式:POST(HTTPS)
+   * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/batch/get_by_user?access_token=ACCESS_TOKEN
+   *
+   * 权限说明:
+   *
+   * 企业需要使用“客户联系”secret或配置到“可调用应用”列表中的自建应用secret所获取的accesstoken来调用(accesstoken如何获取?);
+   * 第三方/自建应用调用时,返回的跟进人follow_user仅包含应用可见范围之内的成员。
+   * 
+ * + * @param userId 企业成员的userid,注意不是外部联系人的帐号 + * @param cursor the cursor + * @param limit the limit + * @return wx cp user external contact batch info + * @throws WxErrorException . + */ + WxCpUserExternalContactBatchInfo getContactDetailBatch(String userId, String cursor, + Integer limit) + throws WxErrorException; + /** * 修改客户备注信息. *
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImpl.java
index 6c6a413a7..2d62f8aef 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImpl.java
@@ -104,6 +104,27 @@ public class WxCpExternalContactServiceImpl implements WxCpExternalContactServic
     return WxCpUserExternalContactInfo.fromJson(responseContent);
   }
 
+  @Override
+  public WxCpUserExternalContactBatchInfo getContactDetailBatch(String userId,
+                                                                String cursor,
+                                                                Integer limit)
+    throws WxErrorException {
+    final String url =
+      this.mainService
+        .getWxCpConfigStorage()
+        .getApiUrl(GET_CONTACT_DETAIL_BATCH);
+    JsonObject json = new JsonObject();
+    json.addProperty("userid", userId);
+    if (StringUtils.isNotBlank(cursor)) {
+      json.addProperty("cursor", cursor);
+    }
+    if (limit != null) {
+      json.addProperty("limit", limit);
+    }
+    String responseContent = this.mainService.post(url, json.toString());
+    return WxCpUserExternalContactBatchInfo.fromJson(responseContent);
+  }
+
   @Override
   public void updateRemark(WxCpUpdateRemarkRequest request) throws WxErrorException {
     final String url = this.mainService.getWxCpConfigStorage().getApiUrl(UPDATE_REMARK);
@@ -162,10 +183,10 @@ public class WxCpExternalContactServiceImpl implements WxCpExternalContactServic
     if (ArrayUtils.isNotEmpty(userIds) || ArrayUtils.isNotEmpty(partyIds)) {
       JsonObject ownerFilter = new JsonObject();
       if (ArrayUtils.isNotEmpty(userIds)) {
-        json.add("userid_list", new Gson().toJsonTree(userIds).getAsJsonArray());
+        ownerFilter.add("userid_list", new Gson().toJsonTree(userIds).getAsJsonArray());
       }
       if (ArrayUtils.isNotEmpty(partyIds)) {
-        json.add("partyid_list", new Gson().toJsonTree(partyIds).getAsJsonArray());
+        ownerFilter.add("partyid_list", new Gson().toJsonTree(partyIds).getAsJsonArray());
       }
       json.add("owner_filter", ownerFilter);
     }
@@ -212,10 +233,10 @@ public class WxCpExternalContactServiceImpl implements WxCpExternalContactServic
     if (ArrayUtils.isNotEmpty(userIds) || ArrayUtils.isNotEmpty(partyIds)) {
       JsonObject ownerFilter = new JsonObject();
       if (ArrayUtils.isNotEmpty(userIds)) {
-        json.add("userid_list", new Gson().toJsonTree(userIds).getAsJsonArray());
+        ownerFilter.add("userid_list", new Gson().toJsonTree(userIds).getAsJsonArray());
       }
       if (ArrayUtils.isNotEmpty(partyIds)) {
-        json.add("partyid_list", new Gson().toJsonTree(partyIds).getAsJsonArray());
+        ownerFilter.add("partyid_list", new Gson().toJsonTree(partyIds).getAsJsonArray());
       }
       json.add("owner_filter", ownerFilter);
     }
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpUserExternalContactBatchInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpUserExternalContactBatchInfo.java
new file mode 100644
index 000000000..5275dc9dd
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpUserExternalContactBatchInfo.java
@@ -0,0 +1,163 @@
+package me.chanjar.weixin.cp.bean.external;
+
+import com.google.gson.annotations.SerializedName;
+import java.io.Serializable;
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+import me.chanjar.weixin.cp.bean.WxCpBaseResp;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+/**
+ * 
+ * 批量获取客户详情
+ * Created by Binary Wang on 2020/10/22.
+ * 参考文档:https://work.weixin.qq.com/api/doc/90000/90135/92994
+ * 
+ * + * @author alucardxh + */ +@Getter +@Setter +public class WxCpUserExternalContactBatchInfo extends WxCpBaseResp implements Serializable { + private static final long serialVersionUID = -5166048319463473186L; + + @SerializedName("external_contact_list") + private List externalContactList; + + @SerializedName("next_cursor") + private String nextCursor; + + @Getter + @Setter + public static class ExternalContactInfo { + @SerializedName("external_contact") + private ExternalContact externalContact; + + @SerializedName("follow_info") + private FollowedUser followInfo; + } + + @Getter + @Setter + public static class ExternalContact { + @SerializedName("external_userid") + private String externalUserId; + + @SerializedName("position") + private String position; + + @SerializedName("name") + private String name; + + @SerializedName("avatar") + private String avatar; + + @SerializedName("corp_name") + private String corpName; + + @SerializedName("corp_full_name") + private String corpFullName; + + @SerializedName("type") + private Integer type; + + @SerializedName("gender") + private Integer gender; + + @SerializedName("unionid") + private String unionId; + + @SerializedName("external_profile") + private ExternalProfile externalProfile; + } + + @Setter + @Getter + public static class ExternalProfile { + @SerializedName("external_attr") + private List externalAttrs; + } + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + public static class ExternalAttribute { + @Setter + @Getter + public static class Text { + private String value; + } + + @Setter + @Getter + public static class Web { + private String title; + private String url; + } + + @Setter + @Getter + public static class MiniProgram { + @SerializedName("pagepath") + private String pagePath; + private String appid; + private String title; + } + + private int type; + + private String name; + + private Text text; + + private Web web; + + @SerializedName("miniprogram") + private MiniProgram miniProgram; + } + + @Setter + @Getter + public static class FollowedUser { + @SerializedName("userid") + private String userId; + private String remark; + private String description; + @SerializedName("createtime") + private Long createTime; + private String state; + @SerializedName("remark_company") + private String remarkCompany; + @SerializedName("remark_mobiles") + private String[] remarkMobiles; + private Tag[] tags; + @SerializedName("remark_corp_name") + private String remarkCorpName; + @SerializedName("add_way") + private String addWay; + @SerializedName("oper_userid") + private String operUserId; + + } + + public static WxCpUserExternalContactBatchInfo fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpUserExternalContactBatchInfo.class); + } + + @Setter + @Getter + public static class Tag { + @SerializedName("group_name") + private String groupName; + @SerializedName("tag_name") + private String tagName; + private int type; + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java index 18b39ed2e..97e30f034 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java @@ -171,6 +171,7 @@ public final class WxCpApiPathConsts { public static final String CLOSE_TEMP_CHAT = "/cgi-bin/externalcontact/close_temp_chat"; public static final String GET_FOLLOW_USER_LIST = "/cgi-bin/externalcontact/get_follow_user_list"; public static final String GET_CONTACT_DETAIL = "/cgi-bin/externalcontact/get?external_userid="; + public static final String GET_CONTACT_DETAIL_BATCH = "/cgi-bin/externalcontact/batch/get_by_user?"; public static final String UPDATE_REMARK = "/cgi-bin/externalcontact/remark"; public static final String LIST_EXTERNAL_CONTACT = "/cgi-bin/externalcontact/list?userid="; public static final String LIST_UNASSIGNED_CONTACT = "/cgi-bin/externalcontact/get_unassigned_list";