From a685e8f3fa2b849f2af3e82a9f1c8747e38badd2 Mon Sep 17 00:00:00 2001 From: zhongjun Date: Tue, 26 Apr 2022 11:31:59 +0800 Subject: [PATCH] =?UTF-8?q?:new:=20#2620=20=E3=80=90=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E3=80=91=E5=BE=AE=E4=BF=A1=E5=AE=A2=E6=9C=8D?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1=E7=AE=A1=E7=90=86=E6=A8=A1=E5=9D=97=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E8=8E=B7=E5=8F=96=E3=80=8C=E5=AE=A2=E6=88=B7=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E7=BB=9F=E8=AE=A1=E3=80=8D=E4=BC=81=E4=B8=9A=E6=B1=87?= =?UTF-8?q?=E6=80=BB=E6=95=B0=E6=8D=AE=E7=9A=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chanjar/weixin/cp/api/WxCpKfService.java | 32 +++---- .../weixin/cp/api/impl/WxCpKfServiceImpl.java | 26 ++--- .../kf/WxCpKfGetCorpStatisticRequest.java | 34 +++++++ .../bean/kf/WxCpKfGetCorpStatisticResp.java | 96 +++++++++++++++++++ .../weixin/cp/constant/WxCpApiPathConsts.java | 1 + .../cp/util/json/StatisticListAdapter.java | 32 +++++++ .../weixin/cp/util/json/WxCpGsonBuilder.java | 3 + 7 files changed, 192 insertions(+), 32 deletions(-) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfGetCorpStatisticRequest.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfGetCorpStatisticResp.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/StatisticListAdapter.java diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpKfService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpKfService.java index 0da548905..0795fb724 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpKfService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpKfService.java @@ -1,23 +1,10 @@ package me.chanjar.weixin.cp.api; -import java.util.List; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.cp.bean.WxCpBaseResp; -import me.chanjar.weixin.cp.bean.kf.WxCpKfAccountAdd; -import me.chanjar.weixin.cp.bean.kf.WxCpKfAccountAddResp; -import me.chanjar.weixin.cp.bean.kf.WxCpKfAccountDel; -import me.chanjar.weixin.cp.bean.kf.WxCpKfAccountLink; -import me.chanjar.weixin.cp.bean.kf.WxCpKfAccountLinkResp; -import me.chanjar.weixin.cp.bean.kf.WxCpKfAccountListResp; -import me.chanjar.weixin.cp.bean.kf.WxCpKfAccountUpd; -import me.chanjar.weixin.cp.bean.kf.WxCpKfCustomerBatchGetResp; -import me.chanjar.weixin.cp.bean.kf.WxCpKfMsgListResp; -import me.chanjar.weixin.cp.bean.kf.WxCpKfMsgSendRequest; -import me.chanjar.weixin.cp.bean.kf.WxCpKfMsgSendResp; -import me.chanjar.weixin.cp.bean.kf.WxCpKfServiceStateResp; -import me.chanjar.weixin.cp.bean.kf.WxCpKfServiceStateTransResp; -import me.chanjar.weixin.cp.bean.kf.WxCpKfServicerListResp; -import me.chanjar.weixin.cp.bean.kf.WxCpKfServicerOpResp; +import me.chanjar.weixin.cp.bean.kf.*; + +import java.util.List; /** * 微信客服接口 @@ -188,4 +175,17 @@ public interface WxCpKfService { */ WxCpKfCustomerBatchGetResp customerBatchGet(List externalUserIdList) throws WxErrorException; + + /** + *
+   * 获取「客户数据统计」企业汇总数据
+   * 通过此接口,可以获取咨询会话数、咨询客户数等企业汇总统计数据
+   * 请求方式:POST(HTTPS)
+   * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/kf/get_corp_statistic?access_token=ACCESS_TOKEN
+   * 文档地址:https://developer.work.weixin.qq.com/document/path/95489
+   * 
+   * @param request 查询参数
+   * @return 客户数据统计-企业汇总数据
+   */
+  WxCpKfGetCorpStatisticResp getCorpStatistic(WxCpKfGetCorpStatisticRequest request) throws WxErrorException;
 }
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpKfServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpKfServiceImpl.java
index 12f1062b0..26afa1d64 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpKfServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpKfServiceImpl.java
@@ -4,29 +4,16 @@ import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonObject;
-import java.util.List;
 import lombok.RequiredArgsConstructor;
 import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.cp.api.WxCpKfService;
 import me.chanjar.weixin.cp.api.WxCpService;
 import me.chanjar.weixin.cp.bean.WxCpBaseResp;
-import me.chanjar.weixin.cp.bean.kf.WxCpKfAccountAdd;
-import me.chanjar.weixin.cp.bean.kf.WxCpKfAccountAddResp;
-import me.chanjar.weixin.cp.bean.kf.WxCpKfAccountDel;
-import me.chanjar.weixin.cp.bean.kf.WxCpKfAccountLink;
-import me.chanjar.weixin.cp.bean.kf.WxCpKfAccountLinkResp;
-import me.chanjar.weixin.cp.bean.kf.WxCpKfAccountListResp;
-import me.chanjar.weixin.cp.bean.kf.WxCpKfAccountUpd;
-import me.chanjar.weixin.cp.bean.kf.WxCpKfCustomerBatchGetResp;
-import me.chanjar.weixin.cp.bean.kf.WxCpKfMsgListResp;
-import me.chanjar.weixin.cp.bean.kf.WxCpKfMsgSendRequest;
-import me.chanjar.weixin.cp.bean.kf.WxCpKfMsgSendResp;
-import me.chanjar.weixin.cp.bean.kf.WxCpKfServiceStateResp;
-import me.chanjar.weixin.cp.bean.kf.WxCpKfServiceStateTransResp;
-import me.chanjar.weixin.cp.bean.kf.WxCpKfServicerListResp;
-import me.chanjar.weixin.cp.bean.kf.WxCpKfServicerOpResp;
+import me.chanjar.weixin.cp.bean.kf.*;
 import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
 
+import java.util.List;
+
 import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Kf.*;
 
 /**
@@ -188,4 +175,11 @@ public class WxCpKfServiceImpl implements WxCpKfService {
     return WxCpKfCustomerBatchGetResp.fromJson(responseContent);
   }
 
+  @Override
+  public WxCpKfGetCorpStatisticResp getCorpStatistic(WxCpKfGetCorpStatisticRequest request) throws WxErrorException {
+    String url = cpService.getWxCpConfigStorage().getApiUrl(GET_CORP_STATISTIC);
+    String responseContent = cpService.post(url, GSON.toJson(request));
+    return WxCpKfGetCorpStatisticResp.fromJson(responseContent);
+  }
+
 }
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfGetCorpStatisticRequest.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfGetCorpStatisticRequest.java
new file mode 100644
index 000000000..193a6b353
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfGetCorpStatisticRequest.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.cp.bean.kf;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * 获取「客户数据统计」企业汇总数据
+ *
+ * @author zhongjun
+ * @date 2022/4/25
+ **/
+@NoArgsConstructor
+@Data
+public class WxCpKfGetCorpStatisticRequest {
+
+  /**
+   * 客服帐号ID。不传入时返回的数据为企业维度汇总的数据
+   */
+  @SerializedName("open_kfid")
+  private String openKfId;
+
+  /**
+   * 起始日期的时间戳,填这一天的0时0分0秒(否则系统自动处理为当天的0分0秒)。取值范围:昨天至前180天
+   */
+  @SerializedName("start_time")
+  private Long startTime;
+  /**
+   * 结束日期的时间戳,填这一天的0时0分0秒(否则系统自动处理为当天的0分0秒)。取值范围:昨天至前180天
+   */
+  @SerializedName("end_time")
+  private Long endTime;
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfGetCorpStatisticResp.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfGetCorpStatisticResp.java
new file mode 100644
index 000000000..86d97ab3f
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/kf/WxCpKfGetCorpStatisticResp.java
@@ -0,0 +1,96 @@
+package me.chanjar.weixin.cp.bean.kf;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import me.chanjar.weixin.cp.bean.WxCpBaseResp;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+import java.util.List;
+
+/**
+ * 获取「客户数据统计」企业汇总数据
+ *
+ * @author zhongjun
+ * @date 2022/4/25
+ **/
+@EqualsAndHashCode(callSuper = true)
+@NoArgsConstructor
+@Data
+public class WxCpKfGetCorpStatisticResp extends WxCpBaseResp {
+  private static final long serialVersionUID = -89898989898989898L;
+
+  /**
+   * 统计数据列表
+   */
+  @SerializedName("statistic_list")
+  private List statisticList;
+
+  @NoArgsConstructor
+  @Data
+  public static class StatisticList {
+    /**
+     * 数据统计日期,为当日0点的时间戳
+     */
+    @SerializedName("stat_time")
+    private Long statTime;
+
+    /**
+     * 一天的统计数据。若当天未产生任何下列统计数据或统计数据还未计算完成则不会返回此项
+     */
+    @SerializedName("statistic")
+    private Statistic statistic;
+  }
+
+  @NoArgsConstructor
+  @Data
+  public static class Statistic {
+
+    /**
+     * 咨询会话数。客户发过消息并分配给接待人员或智能助手的客服会话数,转接不会产生新的会话
+     */
+    @SerializedName("session_cnt")
+    private Integer sessionCnt;
+
+    /**
+     * 咨询客户数。在会话中发送过消息的客户数量,若客户多次咨询只计算一个客户
+     */
+    @SerializedName("user_cnt")
+    private Integer customerCnt;
+
+    /**
+     * 咨询消息总数。客户在会话中发送的消息的数量
+     */
+    @SerializedName("customer_msg_cnt")
+    private Integer customerMsgCnt;
+
+    /**
+     * 升级服务客户数。通过「升级服务」功能成功添加专员或加入客户群的客户数,若同一个客户添加多个专员或客户群,只计算一个客户。在2022年3月10日以后才会有对应统计数据
+     */
+    @SerializedName("upgrade_service_customer_cnt")
+    private Integer upgradeServiceCustomerCnt;
+
+    /**
+     * 智能回复会话数。客户发过消息并分配给智能助手的咨询会话数。通过API发消息或者开启智能回复功能会将客户分配给智能助手
+     */
+    @SerializedName("ai_transfer_rate")
+    private Integer aiSessionReplyCnt;
+
+    /**
+     * 转人工率。一个自然日内,客户给智能助手发消息的会话中,转人工的会话的占比。
+     */
+    @SerializedName("ai_transfer_rate")
+    private Integer aiTransferRate;
+
+    /**
+     * 知识命中率。一个自然日内,客户给智能助手发送的消息中,命中知识库的占比。只有在开启了智能回复原生功能并配置了知识库的情况下,才会产生该项统计数据。当api托管了会话分配,智能回复原生功能失效。若不返回,代表没有向配置知识库的智能接待助手发送消息,该项无法计算
+     */
+    @SerializedName("ai_knowledge_hit_rate")
+    private Integer aiKnowledgeHitRate;
+  }
+
+  public static WxCpKfGetCorpStatisticResp fromJson(String json) {
+    return WxCpGsonBuilder.create().fromJson(json, WxCpKfGetCorpStatisticResp.class);
+  }
+}
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 d82148421..2923d8f45 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
@@ -328,6 +328,7 @@ public interface WxCpApiPathConsts {
 
     String SEND_MSG_ON_EVENT = "/cgi-bin/kf/send_msg_on_event";
     String CUSTOMER_BATCH_GET = "/cgi-bin/kf/customer/batchget";
+    String GET_CORP_STATISTIC = "/cgi-bin/kf/get_corp_statistic";
 
   }
 
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/StatisticListAdapter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/StatisticListAdapter.java
new file mode 100644
index 000000000..1dbe15149
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/StatisticListAdapter.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.cp.util.json;
+
+import com.google.gson.*;
+import me.chanjar.weixin.common.util.json.GsonHelper;
+import me.chanjar.weixin.cp.bean.kf.WxCpKfGetCorpStatisticResp;
+
+import java.lang.reflect.Type;
+
+/**
+ * @author zhongjun
+ * @date 2022/4/25
+ **/
+public class StatisticListAdapter implements JsonDeserializer {
+
+  @Override
+  public WxCpKfGetCorpStatisticResp.StatisticList deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
+    WxCpKfGetCorpStatisticResp.StatisticList statisticList = new WxCpKfGetCorpStatisticResp.StatisticList();
+    JsonObject asJsonObject = jsonElement.getAsJsonObject();
+    statisticList.setStatTime(asJsonObject.get("stat_time").getAsLong());
+    JsonElement statistic = asJsonObject.get("statistic");
+    if (GsonHelper.isNotNull(statistic)) {
+      WxCpKfGetCorpStatisticResp.Statistic statisticObj = new WxCpKfGetCorpStatisticResp.Statistic();
+      statisticObj.setSessionCnt(statistic.getAsJsonObject().get("session_cnt").getAsInt());
+      statisticObj.setCustomerCnt(statistic.getAsJsonObject().get("customer_cnt").getAsInt());
+      statisticObj.setCustomerMsgCnt(statistic.getAsJsonObject().get("customer_msg_cnt").getAsInt());
+      statisticObj.setUpgradeServiceCustomerCnt(statistic.getAsJsonObject().get("upgrade_service_customer_cnt").getAsInt());
+      statisticObj.setAiTransferRate(statistic.getAsJsonObject().get("ai_transfer_rate").getAsInt());
+      statisticObj.setAiKnowledgeHitRate(statistic.getAsJsonObject().get("ai_knowledge_hit_rate").getAsInt());
+    }
+    return statisticList;
+  }
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpGsonBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpGsonBuilder.java
index 098935bf0..750d24ed0 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpGsonBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpGsonBuilder.java
@@ -9,6 +9,8 @@ import me.chanjar.weixin.cp.bean.WxCpChat;
 import me.chanjar.weixin.cp.bean.WxCpDepart;
 import me.chanjar.weixin.cp.bean.WxCpTag;
 import me.chanjar.weixin.cp.bean.WxCpUser;
+import me.chanjar.weixin.cp.bean.kf.WxCpKfGetCorpStatisticResp;
+
 import java.util.Objects;
 
 /**
@@ -27,6 +29,7 @@ public class WxCpGsonBuilder {
     INSTANCE.registerTypeAdapter(WxError.class, new WxErrorAdapter());
     INSTANCE.registerTypeAdapter(WxMenu.class, new WxCpMenuGsonAdapter());
     INSTANCE.registerTypeAdapter(WxCpTag.class, new WxCpTagGsonAdapter());
+    INSTANCE.registerTypeAdapter(WxCpKfGetCorpStatisticResp.StatisticList.class, new StatisticListAdapter());
   }
 
   public static Gson create() {