From 9b6893161a459688d99b737d916ccacbc6bf34c7 Mon Sep 17 00:00:00 2001 From: gaigeshen Date: Tue, 18 Dec 2018 10:34:53 +0800 Subject: [PATCH] =?UTF-8?q?#783=20=E4=BC=81=E4=B8=9A=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E5=A2=9E=E5=8A=A0=E7=BE=A4=E8=81=8A=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 实现消息推送的服务,添加发送应用消息的方法 * 添加创建群聊会话方法,去除不需要的类 * 完成群聊会话的修改和获取 * 重构群聊服务,提出到单独的服务类里面 * 完成群聊的测试 --- .../weixin/cp/api/WxCpChatService.java | 48 +++++++++++ .../me/chanjar/weixin/cp/api/WxCpService.java | 12 ++- .../cp/api/impl/WxCpAgentServiceImpl.java | 6 +- .../cp/api/impl/WxCpChatServiceImpl.java | 83 +++++++++++++++++++ .../cp/api/impl/WxCpServiceAbstractImpl.java | 10 ++- .../me/chanjar/weixin/cp/bean/WxCpChat.java | 20 +++++ .../cp/util/json/WxCpChatGsonAdapter.java | 77 +++++++++++++++++ .../weixin/cp/util/json/WxCpGsonBuilder.java | 2 + .../cp/api/impl/WxCpChatServiceImplTest.java | 46 ++++++++++ 9 files changed, 298 insertions(+), 6 deletions(-) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpChat.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpChatGsonAdapter.java create mode 100644 weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java new file mode 100644 index 00000000..2c24701d --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java @@ -0,0 +1,48 @@ +package me.chanjar.weixin.cp.api; + +import java.util.List; + +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.bean.WxCpChat; + +/** + * 群聊服务 + * + * @author gaigeshen + */ +public interface WxCpChatService { + + /** + * 创建群聊会话,注意:刚创建的群,如果没有下发消息,在企业微信不会出现该群。 + * + * @param name 群聊名,最多50个utf8字符,超过将截断 + * @param owner 指定群主的id。如果不指定,系统会随机从userlist中选一人作为群主 + * @param users 群成员id列表。至少2人,至多500人 + * @param chatId 群聊的唯一标志,不能与已有的群重复;字符串类型,最长32个字符。只允许字符0-9及字母a-zA-Z。如果不填,系统会随机生成群id + * @return 创建群聊会话的结果,群聊的唯一标志 + * @throws WxErrorException 发生异常 + */ + String chatCreate(String name, String owner, List users, String chatId) throws WxErrorException; + + /** + * 修改群聊会话 + * + * @param chatId 群聊id + * @param name 新的群聊名。若不需更新,请忽略此参数(null or empty)。最多50个utf8字符,超过将截断 + * @param owner 新群主的id。若不需更新,请忽略此参数(null or empty) + * @param usersToAdd 添加成员的id列表,若不需要更新,则传递空对象或者空集合 + * @param usersToDelete 踢出成员的id列表,若不需要更新,则传递空对象或者空集合 + * @throws WxErrorException 发生异常 + */ + void chatUpdate(String chatId, String name, String owner, List usersToAdd, List usersToDelete) throws WxErrorException; + + /** + * 获取群聊会话 + * + * @param chatId 群聊编号 + * @return 群聊会话 + * @throws WxErrorException 发生异常 + */ + WxCpChat chatGet(String chatId) throws WxErrorException; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java index 3e33c4eb..afda991b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java @@ -7,7 +7,8 @@ import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; import me.chanjar.weixin.common.util.http.RequestExecutor; import me.chanjar.weixin.common.util.http.RequestHttp; -import me.chanjar.weixin.cp.bean.*; +import me.chanjar.weixin.cp.bean.WxCpMessage; +import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; import me.chanjar.weixin.cp.config.WxCpConfigStorage; /** @@ -241,13 +242,20 @@ public interface WxCpService { * 获取用户相关接口的服务类对象 */ WxCpUserService getUserService(); + + /** + * 获取群聊服务 + * + * @return 群聊服务 + */ + WxCpChatService getChatService(); WxCpAgentService getAgentService(); /** * http请求对象 */ - RequestHttp getRequestHttp(); + RequestHttp getRequestHttp(); void setUserService(WxCpUserService userService); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImpl.java index e4914134..3a977b81 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpAgentServiceImpl.java @@ -1,9 +1,11 @@ package me.chanjar.weixin.cp.api.impl; -import com.google.gson.Gson; +import java.util.List; + import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; + import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.cp.api.WxCpAgentService; @@ -11,8 +13,6 @@ import me.chanjar.weixin.cp.api.WxCpService; import me.chanjar.weixin.cp.bean.WxCpAgent; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; -import java.util.List; - /** *
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java
new file mode 100644
index 00000000..b8e894fb
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java
@@ -0,0 +1,83 @@
+package me.chanjar.weixin.cp.api.impl;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.google.gson.JsonParser;
+
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.common.util.json.WxGsonBuilder;
+import me.chanjar.weixin.cp.api.WxCpChatService;
+import me.chanjar.weixin.cp.api.WxCpService;
+import me.chanjar.weixin.cp.bean.WxCpChat;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+/**
+ * 群聊服务实现
+ *
+ * @author gaigeshen
+ */
+public class WxCpChatServiceImpl implements WxCpChatService { 
+
+  private final WxCpService internalService;
+  
+  /**
+   * 创建群聊服务实现的实例
+   * 
+   * @param internalService 企业微信的服务
+   */
+  public WxCpChatServiceImpl(WxCpService internalService) {
+    this.internalService = internalService;
+  }
+
+  @Override
+  public String chatCreate(String name, String owner, List users, String chatId) throws WxErrorException {
+    Map data = new HashMap<>(4);
+    if (StringUtils.isNotBlank(name)) {
+      data.put("name", name);
+    }
+    if (StringUtils.isNotBlank(owner)) {
+      data.put("owner", owner);
+    }
+    if (users != null) {
+      data.put("userlist", users);
+    }
+    if (StringUtils.isNotBlank(chatId)) {
+      data.put("chatid", chatId);
+    }
+    String result = internalService.post("https://qyapi.weixin.qq.com/cgi-bin/appchat/create", WxGsonBuilder.create().toJson(data));
+    return new JsonParser().parse(result).getAsJsonObject().get("chatid").getAsString();
+  }
+
+  @Override
+  public void chatUpdate(String chatId, String name, String owner, List usersToAdd, List usersToDelete) throws WxErrorException {
+    Map data = new HashMap<>(5);
+    if (StringUtils.isNotBlank(chatId)) {
+      data.put("chatid", chatId);
+    }
+    if (StringUtils.isNotBlank(name)) {
+      data.put("name", name);
+    }
+    if (StringUtils.isNotBlank(owner)) {
+      data.put("owner", owner);
+    }
+    if (usersToAdd != null && !usersToAdd.isEmpty()) {
+      data.put("add_user_list", usersToAdd);
+    }
+    if (usersToDelete != null && !usersToDelete.isEmpty()) {
+      data.put("del_user_list", usersToDelete);
+    }
+    internalService.post("https://qyapi.weixin.qq.com/cgi-bin/appchat/update", WxGsonBuilder.create().toJson(data));
+  }
+
+  @Override
+  public WxCpChat chatGet(String chatId) throws WxErrorException {
+    String result = internalService.get("https://qyapi.weixin.qq.com/cgi-bin/appchat/get?chatid=" + chatId, null);
+    return WxCpGsonBuilder.create().fromJson(
+        new JsonParser().parse(result).getAsJsonObject().getAsJsonObject("chat_info").toString(), WxCpChat.class);
+  }
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceAbstractImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceAbstractImpl.java
index 3b2292ca..f0c15109 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceAbstractImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceAbstractImpl.java
@@ -10,6 +10,7 @@ import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
+
 import me.chanjar.weixin.common.bean.WxJsapiSignature;
 import me.chanjar.weixin.common.error.WxError;
 import me.chanjar.weixin.common.error.WxErrorException;
@@ -24,6 +25,7 @@ import me.chanjar.weixin.common.util.http.RequestHttp;
 import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
 import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
 import me.chanjar.weixin.cp.api.WxCpAgentService;
+import me.chanjar.weixin.cp.api.WxCpChatService;
 import me.chanjar.weixin.cp.api.WxCpDepartmentService;
 import me.chanjar.weixin.cp.api.WxCpMediaService;
 import me.chanjar.weixin.cp.api.WxCpMenuService;
@@ -39,6 +41,7 @@ public abstract class WxCpServiceAbstractImpl implements WxCpService, Requ
   protected final Logger log = LoggerFactory.getLogger(this.getClass());
 
   private WxCpUserService userService = new WxCpUserServiceImpl(this);
+  private WxCpChatService chatService = new WxCpChatServiceImpl(this);
   private WxCpDepartmentService departmentService = new WxCpDepartmentServiceImpl(this);
   private WxCpMediaService mediaService = new WxCpMediaServiceImpl(this);
   private WxCpMenuService menuService = new WxCpMenuServiceImpl(this);
@@ -343,7 +346,12 @@ public abstract class WxCpServiceAbstractImpl implements WxCpService, Requ
   }
 
   @Override
-  public RequestHttp getRequestHttp() {
+  public WxCpChatService getChatService() {
+    return chatService;
+  }
+
+  @Override
+  public RequestHttp getRequestHttp() {
     return this;
   }
 
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpChat.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpChat.java
new file mode 100644
index 00000000..1f593e47
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpChat.java
@@ -0,0 +1,20 @@
+package me.chanjar.weixin.cp.bean;
+
+import java.util.List;
+
+import lombok.Data;
+
+/**
+ * 群聊
+ *
+ * @author gaigeshen
+ */
+@Data
+public class WxCpChat {
+  
+  private String id;
+  private String name;
+  private String owner;
+  private List users;
+
+}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpChatGsonAdapter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpChatGsonAdapter.java
new file mode 100644
index 00000000..0e97181a
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpChatGsonAdapter.java
@@ -0,0 +1,77 @@
+/*
+ * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved.
+ *
+ * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended
+ * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction
+ * arose from modification of the original source, or other redistribution of this source
+ * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD.
+ */
+package me.chanjar.weixin.cp.util.json;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonDeserializationContext;
+import com.google.gson.JsonDeserializer;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParseException;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+
+import me.chanjar.weixin.common.util.json.GsonHelper;
+import me.chanjar.weixin.cp.bean.WxCpChat;
+
+/**
+ * 群聊适配器
+ *
+ * @author gaigeshen
+ */
+public class WxCpChatGsonAdapter implements JsonSerializer, JsonDeserializer {
+
+  @Override
+  public JsonElement serialize(WxCpChat chat, Type typeOfSrc, JsonSerializationContext context) {
+    JsonObject json = new JsonObject();
+    if (chat.getId() != null) { 
+      json.addProperty("chatid", chat.getId());
+    }
+    if (chat.getName() != null) {
+      json.addProperty("name", chat.getName());
+    } 
+    if (chat.getOwner() != null) {
+      json.addProperty("owner", chat.getOwner());
+    }
+    if (chat.getUsers() != null) {
+      JsonArray users = new JsonArray();
+      for (String user : chat.getUsers()) {
+        users.add(user);
+      }
+      json.add("userlist", users);
+    }
+    return json;
+  }
+
+  @Override
+  public WxCpChat deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
+    JsonObject chatJson = json.getAsJsonObject();
+
+    WxCpChat chat = new WxCpChat();
+    chat.setId(GsonHelper.getAsString(chatJson.get("chatid")));
+    chat.setName(GsonHelper.getAsString(chatJson.get("name")));
+    chat.setOwner(GsonHelper.getAsString(chatJson.get("owner")));
+    
+    JsonArray usersJson = chatJson.getAsJsonArray("userlist");
+    if (usersJson != null) {
+      List users = new ArrayList<>(usersJson.size());
+      chat.setUsers(users);
+      for (JsonElement userJson : usersJson) {
+        users.add(userJson.getAsString());
+      }
+    }
+    
+    return chat;
+  }
+
+}
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 6ff49bf0..654d5511 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
@@ -5,6 +5,7 @@ import com.google.gson.GsonBuilder;
 import me.chanjar.weixin.common.bean.menu.WxMenu;
 import me.chanjar.weixin.common.error.WxError;
 import me.chanjar.weixin.common.util.json.WxErrorAdapter;
+import me.chanjar.weixin.cp.bean.WxCpChat;
 import me.chanjar.weixin.cp.bean.WxCpDepart;
 import me.chanjar.weixin.cp.bean.WxCpMessage;
 import me.chanjar.weixin.cp.bean.WxCpTag;
@@ -20,6 +21,7 @@ public class WxCpGsonBuilder {
   static {
     INSTANCE.disableHtmlEscaping();
     INSTANCE.registerTypeAdapter(WxCpMessage.class, new WxCpMessageGsonAdapter());
+    INSTANCE.registerTypeAdapter(WxCpChat.class, new WxCpChatGsonAdapter());
     INSTANCE.registerTypeAdapter(WxCpDepart.class, new WxCpDepartGsonAdapter());
     INSTANCE.registerTypeAdapter(WxCpUser.class, new WxCpUserGsonAdapter());
     INSTANCE.registerTypeAdapter(WxError.class, new WxErrorAdapter());
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java
new file mode 100644
index 00000000..8317a45e
--- /dev/null
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java
@@ -0,0 +1,46 @@
+package me.chanjar.weixin.cp.api.impl;
+
+import java.util.Arrays;
+
+import me.chanjar.weixin.cp.bean.WxCpChat;
+import org.testng.Assert;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import com.google.inject.Inject;
+
+import me.chanjar.weixin.cp.api.ApiTestModule;
+import me.chanjar.weixin.cp.api.WxCpService;
+
+/**
+ * 测试群聊服务
+ *
+ * @author gaigeshen
+ */
+@Guice(modules = ApiTestModule.class)
+public class WxCpChatServiceImplTest {
+
+  @Inject
+  private WxCpService wxCpService;
+  
+  @Test
+  public void create() throws Exception {
+    wxCpService.getChatService().chatCreate("测试群聊", "gaige_shen", Arrays.asList("gaige_shen", "ZhangXiaoMing"), "mychatid");
+  }
+
+  @Test
+  public void get() throws Exception {
+    WxCpChat chat = wxCpService.getChatService().chatGet("mychatid");
+    System.out.println(chat);
+    Assert.assertEquals(chat.getName(), "测试群聊");
+  }
+
+  @Test
+  public void update() throws Exception {
+    wxCpService.getChatService().chatUpdate("mychatid",  "", "", Arrays.asList("ZhengWuYao"), null);
+    WxCpChat chat = wxCpService.getChatService().chatGet("mychatid");
+    System.out.println(chat);
+    Assert.assertEquals(chat.getUsers().size(), 3);
+  }
+
+}