From 2b27c031ec057e19a6b1db1fa00f6d7c129e9d04 Mon Sep 17 00:00:00 2001 From: huangxiaoming Date: Wed, 29 Jul 2020 17:27:59 +0800 Subject: [PATCH 01/25] =?UTF-8?q?=E5=A4=96=E9=83=A8=E8=81=94=E7=B3=BB?= =?UTF-8?q?=E4=BA=BA=E5=AE=A2=E6=88=B7=E8=AF=A6=E6=83=85=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加字段:remark_corp_name,addWay,oper_userid Signed-off-by: huangxiaoming --- pom.xml | 2 +- .../chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7df2c1832..d1b8da28a 100644 --- a/pom.xml +++ b/pom.xml @@ -92,7 +92,7 @@ huangxiaoming - huangxiaoming@163.com + huangxm129@163.com https://github.com/huangxm129 diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java index d099e4eeb..9a1d07a7f 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java @@ -119,6 +119,12 @@ public static class FollowedUser { @SerializedName("remark_mobiles") private String[] remarkMobiles; private Tag[] tags; + @SerializedName("remark_corp_name") + private String remarkCorpName; + @SerializedName("addWay") + private String addWay; + @SerializedName("oper_userid") + private String operUserId; } From 755c743dec46154ac8c899e7d3fe76cfb55b9720 Mon Sep 17 00:00:00 2001 From: huangxiaoming Date: Wed, 29 Jul 2020 17:29:25 +0800 Subject: [PATCH 02/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: huangxiaoming --- .../weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java index f23108315..d234116a4 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java @@ -30,7 +30,7 @@ public class WxCpExternalContactServiceImplTest { @Test public void testGetExternalContact() throws WxErrorException { String externalUserId = this.configStorage.getExternalUserId(); - WxCpUserExternalContactInfo result = this.wxCpService.getExternalContactService().getExternalContact(externalUserId); + WxCpUserExternalContactInfo result = this.wxCpService.getExternalContactService().getContactDetail(externalUserId); System.out.println(result); assertNotNull(result); } From 33e584d4d0065223a048fae43789b97380f6647e Mon Sep 17 00:00:00 2001 From: huangxiaoming Date: Thu, 30 Jul 2020 19:40:56 +0800 Subject: [PATCH 03/25] =?UTF-8?q?=E5=AE=A2=E6=88=B7=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E7=BB=84=E6=9F=A5=E8=AF=A2=E5=88=97=E8=A1=A8=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: huangxiaoming --- .../cp/api/WxCpExternalContactService.java | 4 +- .../impl/WxCpExternalContactServiceImpl.java | 8 +- ...java => WxCpUserExternalTagGroupInfo.java} | 6 +- .../cp/bean/WxCpUserExternalTagGroupList.java | 75 +++++++++++++++++++ .../WxCpExternalContactServiceImplTest.java | 22 +++--- 5 files changed, 93 insertions(+), 22 deletions(-) rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/{WxCpUserExternalTagGroup.java => WxCpUserExternalTagGroupInfo.java} (88%) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroupList.java 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 e1806d097..12d794462 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 @@ -255,7 +255,7 @@ public interface WxCpExternalContactService { * @param tagId * @return */ - WxCpUserExternalTagGroup getCorpTagList(String [] tagId) throws WxErrorException; + WxCpUserExternalTagGroupList getCorpTagList(String [] tagId) throws WxErrorException; /** @@ -266,7 +266,7 @@ public interface WxCpExternalContactService { * @param tagGroup * @return */ - WxCpUserExternalTagGroup addCorpTag(WxCpUserExternalTagGroup tagGroup)throws WxErrorException; + WxCpUserExternalTagGroupInfo addCorpTag(WxCpUserExternalTagGroupInfo tagGroup)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 01477c854..f9058f017 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
@@ -225,22 +225,22 @@ public WxCpMsgTemplateAddResult addMsgTemplate(WxCpMsgTemplate wxCpMsgTemplate)
   }
 
   @Override
-  public WxCpUserExternalTagGroup getCorpTagList(String[] tagId) throws WxErrorException {
+  public WxCpUserExternalTagGroupList getCorpTagList(String[] tagId) throws WxErrorException {
     JsonObject json = new JsonObject();
     if(ArrayUtils.isNotEmpty(tagId)){
       json.add("tag_id",new Gson().toJsonTree(tagId).getAsJsonArray());
     }
     final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_CORP_TAG_LIST);
     final String result = this.mainService.post(url,json.toString());
-    return WxCpUserExternalTagGroup.fromJson(result);
+    return WxCpUserExternalTagGroupList.fromJson(result);
   }
 
   @Override
-  public WxCpUserExternalTagGroup addCorpTag(WxCpUserExternalTagGroup tagGroup) throws WxErrorException{
+  public WxCpUserExternalTagGroupInfo addCorpTag(WxCpUserExternalTagGroupInfo tagGroup) throws WxErrorException{
 
     final String url = this.mainService.getWxCpConfigStorage().getApiUrl(ADD_CORP_TAG);
     final String result = this.mainService.post(url,tagGroup.toJson());
-    return WxCpUserExternalTagGroup.fromJson(result);
+    return WxCpUserExternalTagGroupInfo.fromJson(result);
   }
 
   @Override
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroup.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroupInfo.java
similarity index 88%
rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroup.java
rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroupInfo.java
index 1dff12057..16d20d7ec 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroup.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroupInfo.java
@@ -13,7 +13,7 @@
  */
 @Getter
 @Setter
-public class WxCpUserExternalTagGroup extends WxCpBaseResp {
+public class WxCpUserExternalTagGroupInfo extends WxCpBaseResp {
 
   @SerializedName("group_id")
   private String groupId;
@@ -63,7 +63,7 @@ public String toJson() {
     return WxGsonBuilder.create().toJson(this);
   }
 
-  public static WxCpUserExternalTagGroup fromJson(String json) {
-    return WxCpGsonBuilder.create().fromJson(json, WxCpUserExternalTagGroup.class);
+  public static WxCpUserExternalTagGroupInfo fromJson(String json) {
+    return WxCpGsonBuilder.create().fromJson(json, WxCpUserExternalTagGroupInfo.class);
   }
 }
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroupList.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroupList.java
new file mode 100644
index 000000000..f77433cb4
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroupList.java
@@ -0,0 +1,75 @@
+package me.chanjar.weixin.cp.bean;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Getter;
+import lombok.Setter;
+import me.chanjar.weixin.common.util.json.WxGsonBuilder;
+import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
+
+import java.util.List;
+
+/**
+ *
+ */
+@Getter
+@Setter
+public class WxCpUserExternalTagGroupList extends WxCpBaseResp {
+
+  @SerializedName("tag_group")
+  private List tagGroupList;
+
+  @Getter
+  @Setter
+  public static class TagGroup{
+    @SerializedName("group_id")
+    private String groupId;
+
+    @SerializedName("group_name")
+    private String groupName;
+
+    @SerializedName("create_time")
+    private Long createTime;
+
+    @SerializedName("order")
+    private Integer order;
+
+    @SerializedName("deleted")
+    private Boolean deleted;
+
+
+    @SerializedName("tag")
+    private List tag;
+
+    @Getter
+    @Setter
+    public static class Tag {
+
+      /**
+       * 客户群ID
+       */
+      @SerializedName("id")
+      private String id;
+
+      @SerializedName("name")
+      private String name;
+
+      @SerializedName("create_time")
+      private Long  createTime;
+
+      @SerializedName("order")
+      private Integer  order;
+
+      @SerializedName("deleted")
+      private Boolean  deleted;
+
+    }
+  }
+
+  public String toJson() {
+    return WxGsonBuilder.create().toJson(this);
+  }
+
+  public static WxCpUserExternalTagGroupList fromJson(String json) {
+    return WxCpGsonBuilder.create().fromJson(json, WxCpUserExternalTagGroupList.class);
+  }
+}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
index d234116a4..eeb1749ac 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
@@ -5,10 +5,7 @@
 import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.cp.api.ApiTestModule;
 import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.bean.WxCpBaseResp;
-import me.chanjar.weixin.cp.bean.WxCpContactWayInfo;
-import me.chanjar.weixin.cp.bean.WxCpUserExternalContactInfo;
-import me.chanjar.weixin.cp.bean.WxCpUserExternalTagGroup;
+import me.chanjar.weixin.cp.bean.*;
 import org.apache.commons.lang3.time.DateFormatUtils;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
@@ -110,7 +107,7 @@ public void testGetContactDetail() throws WxErrorException {
   @Test
   public void testGetCorpTagList() throws WxErrorException {
     String tag[]={};
-    WxCpUserExternalTagGroup result = this.wxCpService.getExternalContactService().getCorpTagList(null);
+    WxCpUserExternalTagGroupList result = this.wxCpService.getExternalContactService().getCorpTagList(null);
     System.out.println(result);
     assertNotNull(result);
   }
@@ -118,19 +115,18 @@ public void testGetCorpTagList() throws WxErrorException {
   @Test
   public void testAddCorpTag() throws WxErrorException {
 
-    List list = new ArrayList<>();
-
-    WxCpUserExternalTagGroup.Tag  tag = new  WxCpUserExternalTagGroup.Tag();
-    tag.setName("测试标签1");
+    List list = new ArrayList<>();
+    WxCpUserExternalTagGroupInfo.Tag  tag = new  WxCpUserExternalTagGroupInfo.Tag();
+    tag.setName("测试标签2");
     tag.setOrder(1);
     list.add(tag);
 
-    WxCpUserExternalTagGroup tagGroup = new WxCpUserExternalTagGroup();
+    WxCpUserExternalTagGroupInfo tagGroup = new WxCpUserExternalTagGroupInfo();
     tagGroup.setGroupName("其他");
     tagGroup.setOrder(1);
     tagGroup.setTag(list);
 
-    WxCpUserExternalTagGroup result = this.wxCpService.getExternalContactService().addCorpTag(tagGroup);
+    WxCpUserExternalTagGroupInfo result = this.wxCpService.getExternalContactService().addCorpTag(tagGroup);
 
 
 
@@ -141,7 +137,7 @@ public void testAddCorpTag() throws WxErrorException {
   @Test
   public void testEditCorpTag() throws WxErrorException {
 
-    WxCpBaseResp result = this.wxCpService.getExternalContactService().editCorpTag("et2omCCwAArxYqGJQn4MNMS_zQKhIUfQ", "未知", 2);
+    WxCpBaseResp result = this.wxCpService.getExternalContactService().editCorpTag("et2omCCwAA6PtGsfeEOQMENl3Ub1FA6A", "未知6", 2);
 
     System.out.println(result);
     assertNotNull(result);
@@ -150,7 +146,7 @@ public void testEditCorpTag() throws WxErrorException {
   @Test
   public void testDelCorpTag() throws WxErrorException {
 
-    String tagId[] = {"et2omCCwAArxYqGJQn4MNMS_zQKhIUfQ"};
+    String tagId[] = {"et2omCCwAA6PtGsfeEOQMENl3Ub1FA6A"};
     String groupId[] = {};
 
     WxCpBaseResp result = this.wxCpService.getExternalContactService().delCorpTag(tagId,groupId);

From 03b33a965769cefa3820a3b0aa80e0926f9b88ab Mon Sep 17 00:00:00 2001
From: huangxiaoming 
Date: Thu, 30 Jul 2020 20:14:38 +0800
Subject: [PATCH 04/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95?=
 =?UTF-8?q?=E7=B1=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: huangxiaoming 
---
 .../weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
index eeb1749ac..2c63496f3 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
@@ -27,7 +27,7 @@ public class WxCpExternalContactServiceImplTest {
   @Test
   public void testGetExternalContact() throws WxErrorException {
     String externalUserId = this.configStorage.getExternalUserId();
-    WxCpUserExternalContactInfo result = this.wxCpService.getExternalContactService().getContactDetail(externalUserId);
+    WxCpUserExternalContactInfo result = this.wxCpService.getExternalContactService().getExternalContact(externalUserId);
     System.out.println(result);
     assertNotNull(result);
   }

From a570172c1179571598a5bdcae804e14bbcf4d1e8 Mon Sep 17 00:00:00 2001
From: huangxiaoming 
Date: Thu, 30 Jul 2020 20:20:52 +0800
Subject: [PATCH 05/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20add=5Fway=E5=AD=97?=
 =?UTF-8?q?=E6=AE=B5=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: huangxiaoming 
---
 .../me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java
index 9a1d07a7f..6e290ce06 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java
@@ -121,7 +121,7 @@ public static class FollowedUser {
     private Tag[] tags;
     @SerializedName("remark_corp_name")
     private String remarkCorpName;
-    @SerializedName("addWay")
+    @SerializedName("add_way")
     private String addWay;
     @SerializedName("oper_userid")
     private String operUserId;

From 2faa8704c2cad17cc7400d5dfd08a2873c0a6473 Mon Sep 17 00:00:00 2001
From: huangxiaoming 
Date: Mon, 3 Aug 2020 15:26:21 +0800
Subject: [PATCH 06/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B7=BB=E5=8A=A0?=
 =?UTF-8?q?=E4=BC=81=E4=B8=9A=E5=AE=A2=E6=88=B7=E6=A0=87=E7=AD=BE=E5=90=8E?=
 =?UTF-8?q?=E6=97=A0=E8=BF=94=E5=9B=9E=E4=BF=A1=E6=81=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: huangxiaoming 
---
 .../impl/WxCpExternalContactServiceImpl.java  |  2 +-
 .../cp/bean/WxCpUserExternalTagGroupInfo.java | 35 ++++++++++++-------
 .../WxCpExternalContactServiceImplTest.java   | 12 +++----
 3 files changed, 30 insertions(+), 19 deletions(-)

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 f9058f017..61e0c1ff8 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
@@ -239,7 +239,7 @@ public WxCpUserExternalTagGroupList getCorpTagList(String[] tagId) throws WxErro
   public WxCpUserExternalTagGroupInfo addCorpTag(WxCpUserExternalTagGroupInfo tagGroup) throws WxErrorException{
 
     final String url = this.mainService.getWxCpConfigStorage().getApiUrl(ADD_CORP_TAG);
-    final String result = this.mainService.post(url,tagGroup.toJson());
+    final String result = this.mainService.post(url,tagGroup.getTagGroup().toJson());
     return WxCpUserExternalTagGroupInfo.fromJson(result);
   }
 
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroupInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroupInfo.java
index 16d20d7ec..d0aa9fe32 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroupInfo.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroupInfo.java
@@ -15,24 +15,35 @@
 @Setter
 public class WxCpUserExternalTagGroupInfo extends WxCpBaseResp {
 
-  @SerializedName("group_id")
-  private String groupId;
+  @SerializedName("tag_group")
+  private TagGroup tagGroup;
 
-  @SerializedName("group_name")
-  private String groupName;
+  @Getter
+  @Setter
+  public static class TagGroup {
+
+    @SerializedName("group_id")
+    private String groupId;
+
+    @SerializedName("group_name")
+    private String groupName;
 
-  @SerializedName("create_time")
-  private Long createTime;
+    @SerializedName("create_time")
+    private Long createTime;
 
-  @SerializedName("order")
-  private Integer order;
+    @SerializedName("order")
+    private Integer order;
 
-  @SerializedName("deleted")
-  private Boolean deleted;
+    @SerializedName("deleted")
+    private Boolean deleted;
 
+    @SerializedName("tag")
+    private List tag;
 
-  @SerializedName("tag")
-  private List tag;
+    public String toJson() {
+      return WxGsonBuilder.create().toJson(this);
+    }
+  }
 
   @Getter
   @Setter
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
index 2c63496f3..3a35d1de4 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
@@ -117,20 +117,20 @@ public void testAddCorpTag() throws WxErrorException {
 
     List list = new ArrayList<>();
     WxCpUserExternalTagGroupInfo.Tag  tag = new  WxCpUserExternalTagGroupInfo.Tag();
-    tag.setName("测试标签2");
+    tag.setName("测试标签9");
     tag.setOrder(1);
     list.add(tag);
 
-    WxCpUserExternalTagGroupInfo tagGroup = new WxCpUserExternalTagGroupInfo();
+    WxCpUserExternalTagGroupInfo tagGroupInfo = new WxCpUserExternalTagGroupInfo();
+    WxCpUserExternalTagGroupInfo.TagGroup tagGroup = new WxCpUserExternalTagGroupInfo.TagGroup();
     tagGroup.setGroupName("其他");
     tagGroup.setOrder(1);
     tagGroup.setTag(list);
+    tagGroupInfo.setTagGroup(tagGroup);
 
-    WxCpUserExternalTagGroupInfo result = this.wxCpService.getExternalContactService().addCorpTag(tagGroup);
+    WxCpUserExternalTagGroupInfo result = this.wxCpService.getExternalContactService().addCorpTag(tagGroupInfo);
 
-
-
-    System.out.println(result);
+    System.out.println(result.toJson());
     assertNotNull(result);
   }
 

From 4e31ee4a6b0918174ea499737e7db5e36e8c8d5f Mon Sep 17 00:00:00 2001
From: huangxiaoming 
Date: Wed, 29 Jul 2020 17:27:59 +0800
Subject: [PATCH 07/25] =?UTF-8?q?=E5=A4=96=E9=83=A8=E8=81=94=E7=B3=BB?=
 =?UTF-8?q?=E4=BA=BA=E5=AE=A2=E6=88=B7=E8=AF=A6=E6=83=85=E6=96=B0=E5=A2=9E?=
 =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AD=97=E6=AE=B5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

增加字段:remark_corp_name,addWay,oper_userid

Signed-off-by: huangxiaoming 
---
 .../chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java   | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java
index 6e290ce06..85cb21289 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java
@@ -121,7 +121,11 @@ public static class FollowedUser {
     private Tag[] tags;
     @SerializedName("remark_corp_name")
     private String remarkCorpName;
+<<<<<<< HEAD
     @SerializedName("add_way")
+=======
+    @SerializedName("addWay")
+>>>>>>> 外部联系人客户详情新增增加字段
     private String addWay;
     @SerializedName("oper_userid")
     private String operUserId;

From 10f68f3e6b933a8132dbc75d93dee269a820278a Mon Sep 17 00:00:00 2001
From: huangxiaoming 
Date: Wed, 29 Jul 2020 17:29:25 +0800
Subject: [PATCH 08/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95?=
 =?UTF-8?q?=E7=B1=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: huangxiaoming 
---
 .../weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
index 2c63496f3..eeb1749ac 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
@@ -27,7 +27,7 @@ public class WxCpExternalContactServiceImplTest {
   @Test
   public void testGetExternalContact() throws WxErrorException {
     String externalUserId = this.configStorage.getExternalUserId();
-    WxCpUserExternalContactInfo result = this.wxCpService.getExternalContactService().getExternalContact(externalUserId);
+    WxCpUserExternalContactInfo result = this.wxCpService.getExternalContactService().getContactDetail(externalUserId);
     System.out.println(result);
     assertNotNull(result);
   }

From cf5bd2895f7b3a057f2bad7cb690e193e78bdc13 Mon Sep 17 00:00:00 2001
From: huangxiaoming 
Date: Thu, 30 Jul 2020 20:14:38 +0800
Subject: [PATCH 09/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95?=
 =?UTF-8?q?=E7=B1=BB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: huangxiaoming 
---
 .../weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
index eeb1749ac..2c63496f3 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
@@ -27,7 +27,7 @@ public class WxCpExternalContactServiceImplTest {
   @Test
   public void testGetExternalContact() throws WxErrorException {
     String externalUserId = this.configStorage.getExternalUserId();
-    WxCpUserExternalContactInfo result = this.wxCpService.getExternalContactService().getContactDetail(externalUserId);
+    WxCpUserExternalContactInfo result = this.wxCpService.getExternalContactService().getExternalContact(externalUserId);
     System.out.println(result);
     assertNotNull(result);
   }

From b410fa622545d842a0c77aefc1d434add885ea83 Mon Sep 17 00:00:00 2001
From: huangxiaoming 
Date: Thu, 30 Jul 2020 20:20:52 +0800
Subject: [PATCH 10/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=20add=5Fway=E5=AD=97?=
 =?UTF-8?q?=E6=AE=B5=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: huangxiaoming 
---
 .../chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java   | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java
index 85cb21289..caaabf5d3 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java
@@ -121,11 +121,15 @@ public static class FollowedUser {
     private Tag[] tags;
     @SerializedName("remark_corp_name")
     private String remarkCorpName;
+<<<<<<< HEAD
 <<<<<<< HEAD
     @SerializedName("add_way")
 =======
     @SerializedName("addWay")
 >>>>>>> 外部联系人客户详情新增增加字段
+=======
+    @SerializedName("add_way")
+>>>>>>> 修改 add_way字段错误
     private String addWay;
     @SerializedName("oper_userid")
     private String operUserId;

From d47d9dfeaad4105ba643864dd25dedf30b041871 Mon Sep 17 00:00:00 2001
From: huangxiaoming 
Date: Mon, 3 Aug 2020 15:26:21 +0800
Subject: [PATCH 11/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B7=BB=E5=8A=A0?=
 =?UTF-8?q?=E4=BC=81=E4=B8=9A=E5=AE=A2=E6=88=B7=E6=A0=87=E7=AD=BE=E5=90=8E?=
 =?UTF-8?q?=E6=97=A0=E8=BF=94=E5=9B=9E=E4=BF=A1=E6=81=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: huangxiaoming 
---
 .../impl/WxCpExternalContactServiceImpl.java  |  2 +-
 .../cp/bean/WxCpUserExternalTagGroupInfo.java | 35 ++++++++++++-------
 .../WxCpExternalContactServiceImplTest.java   | 12 +++----
 3 files changed, 30 insertions(+), 19 deletions(-)

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 f9058f017..61e0c1ff8 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
@@ -239,7 +239,7 @@ public WxCpUserExternalTagGroupList getCorpTagList(String[] tagId) throws WxErro
   public WxCpUserExternalTagGroupInfo addCorpTag(WxCpUserExternalTagGroupInfo tagGroup) throws WxErrorException{
 
     final String url = this.mainService.getWxCpConfigStorage().getApiUrl(ADD_CORP_TAG);
-    final String result = this.mainService.post(url,tagGroup.toJson());
+    final String result = this.mainService.post(url,tagGroup.getTagGroup().toJson());
     return WxCpUserExternalTagGroupInfo.fromJson(result);
   }
 
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroupInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroupInfo.java
index 16d20d7ec..d0aa9fe32 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroupInfo.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalTagGroupInfo.java
@@ -15,24 +15,35 @@
 @Setter
 public class WxCpUserExternalTagGroupInfo extends WxCpBaseResp {
 
-  @SerializedName("group_id")
-  private String groupId;
+  @SerializedName("tag_group")
+  private TagGroup tagGroup;
 
-  @SerializedName("group_name")
-  private String groupName;
+  @Getter
+  @Setter
+  public static class TagGroup {
+
+    @SerializedName("group_id")
+    private String groupId;
+
+    @SerializedName("group_name")
+    private String groupName;
 
-  @SerializedName("create_time")
-  private Long createTime;
+    @SerializedName("create_time")
+    private Long createTime;
 
-  @SerializedName("order")
-  private Integer order;
+    @SerializedName("order")
+    private Integer order;
 
-  @SerializedName("deleted")
-  private Boolean deleted;
+    @SerializedName("deleted")
+    private Boolean deleted;
 
+    @SerializedName("tag")
+    private List tag;
 
-  @SerializedName("tag")
-  private List tag;
+    public String toJson() {
+      return WxGsonBuilder.create().toJson(this);
+    }
+  }
 
   @Getter
   @Setter
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
index 2c63496f3..3a35d1de4 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
@@ -117,20 +117,20 @@ public void testAddCorpTag() throws WxErrorException {
 
     List list = new ArrayList<>();
     WxCpUserExternalTagGroupInfo.Tag  tag = new  WxCpUserExternalTagGroupInfo.Tag();
-    tag.setName("测试标签2");
+    tag.setName("测试标签9");
     tag.setOrder(1);
     list.add(tag);
 
-    WxCpUserExternalTagGroupInfo tagGroup = new WxCpUserExternalTagGroupInfo();
+    WxCpUserExternalTagGroupInfo tagGroupInfo = new WxCpUserExternalTagGroupInfo();
+    WxCpUserExternalTagGroupInfo.TagGroup tagGroup = new WxCpUserExternalTagGroupInfo.TagGroup();
     tagGroup.setGroupName("其他");
     tagGroup.setOrder(1);
     tagGroup.setTag(list);
+    tagGroupInfo.setTagGroup(tagGroup);
 
-    WxCpUserExternalTagGroupInfo result = this.wxCpService.getExternalContactService().addCorpTag(tagGroup);
+    WxCpUserExternalTagGroupInfo result = this.wxCpService.getExternalContactService().addCorpTag(tagGroupInfo);
 
-
-
-    System.out.println(result);
+    System.out.println(result.toJson());
     assertNotNull(result);
   }
 

From 5d054cd3b5418409c75ead2d5e145cceb51f7e79 Mon Sep 17 00:00:00 2001
From: huangxiaoming 
Date: Tue, 4 Aug 2020 16:30:31 +0800
Subject: [PATCH 12/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=94=99=E8=AF=AF?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: huangxiaoming 
---
 .../weixin/cp/api/impl/WxCpExternalContactServiceImpl.java      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

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 61e0c1ff8..b38c6b868 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
@@ -262,7 +262,7 @@ public WxCpBaseResp delCorpTag(String[] tagId, String[] groupId) throws WxErrorE
       json.add("tag_id",new Gson().toJsonTree(tagId).getAsJsonArray());
     }
     if(ArrayUtils.isNotEmpty(groupId)){
-      json.add("group_id",new Gson().toJsonTree(tagId).getAsJsonArray());
+      json.add("group_id",new Gson().toJsonTree(groupId).getAsJsonArray());
     }
 
     final String url = this.mainService.getWxCpConfigStorage().getApiUrl(DEL_CORP_TAG);

From eea345ab0549ee0a71e1e4580bdd4cb861ac14b0 Mon Sep 17 00:00:00 2001
From: huangxiaoming 
Date: Tue, 4 Aug 2020 16:39:59 +0800
Subject: [PATCH 13/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=86=B2=E7=AA=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: huangxiaoming 
---
 .../weixin/cp/bean/WxCpUserExternalContactInfo.java  | 12 ------------
 .../api/impl/WxCpExternalContactServiceImplTest.java |  6 +++---
 2 files changed, 3 insertions(+), 15 deletions(-)

diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java
index c1ed52193..6e290ce06 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUserExternalContactInfo.java
@@ -121,19 +121,7 @@ public static class FollowedUser {
     private Tag[] tags;
     @SerializedName("remark_corp_name")
     private String remarkCorpName;
-<<<<<<< HEAD
-<<<<<<< HEAD
-<<<<<<< HEAD
     @SerializedName("add_way")
-=======
-    @SerializedName("addWay")
->>>>>>> 外部联系人客户详情新增增加字段
-=======
-    @SerializedName("add_way")
->>>>>>> 修改 add_way字段错误
-=======
-    @SerializedName("add_way")
->>>>>>> origin/develop
     private String addWay;
     @SerializedName("oper_userid")
     private String operUserId;
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
index 3a35d1de4..df086037a 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java
@@ -117,7 +117,7 @@ public void testAddCorpTag() throws WxErrorException {
 
     List list = new ArrayList<>();
     WxCpUserExternalTagGroupInfo.Tag  tag = new  WxCpUserExternalTagGroupInfo.Tag();
-    tag.setName("测试标签9");
+    tag.setName("测试标签20");
     tag.setOrder(1);
     list.add(tag);
 
@@ -146,8 +146,8 @@ public void testEditCorpTag() throws WxErrorException {
   @Test
   public void testDelCorpTag() throws WxErrorException {
 
-    String tagId[] = {"et2omCCwAA6PtGsfeEOQMENl3Ub1FA6A"};
-    String groupId[] = {};
+    String tagId[] = {};
+    String groupId[] = {"et2omCCwAAM3WzL00QpK9xARab3HGkAg"};
 
     WxCpBaseResp result = this.wxCpService.getExternalContactService().delCorpTag(tagId,groupId);
 

From bf9841b480f10421eac98508e9ea21a3fb2a9e98 Mon Sep 17 00:00:00 2001
From: huangxiaoming 
Date: Thu, 13 Aug 2020 19:48:33 +0800
Subject: [PATCH 14/25] =?UTF-8?q?=E8=8E=B7=E5=8F=96=E4=BC=81=E4=B8=9A?=
 =?UTF-8?q?=E5=B7=B2=E9=85=8D=E7=BD=AE=E7=9A=84=E3=80=8C=E8=81=94=E7=B3=BB?=
 =?UTF-8?q?=E6=88=91=E3=80=8D=E6=96=B9=E5=BC=8F=EF=BC=9A=E6=B7=BB=E5=8A=A0?=
 =?UTF-8?q?=E4=BA=8C=E7=BB=B4=E7=A0=81=E5=AD=97=E6=AE=B5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: huangxiaoming 
---
 .../me/chanjar/weixin/cp/bean/WxCpContactWayInfo.java     | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpContactWayInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpContactWayInfo.java
index 3f62e4f0e..cd460053d 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpContactWayInfo.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpContactWayInfo.java
@@ -75,6 +75,14 @@ public class WxCpContactWayInfo {
    */
   private String state;
 
+  /**
+   * 
+   * 联系二维码的URL,仅在scene为2时返回
+   * 
+ */ + @SerializedName("qr_code") + private String qrCode; + /** *
    * 使用该联系方式的用户userID列表,在type为1时为必填,且只能有一个

From 4f726b4fb47ce7d0ed1e875fdc4499ab8fe6204f Mon Sep 17 00:00:00 2001
From: huangxiaoming 
Date: Fri, 14 Aug 2020 11:44:35 +0800
Subject: [PATCH 15/25] =?UTF-8?q?=E8=8E=B7=E5=8F=96=E4=BC=81=E4=B8=9A?=
 =?UTF-8?q?=E5=B7=B2=E9=85=8D=E7=BD=AE=E7=9A=84=E3=80=8C=E8=81=94=E7=B3=BB?=
 =?UTF-8?q?=E6=88=91=E3=80=8D=E6=96=B9=E5=BC=8F=E5=AF=B9=E8=B1=A1=E6=97=A0?=
 =?UTF-8?q?=E8=BF=94=E5=9B=9E=E4=BF=A1=E6=81=AFBUG?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: huangxiaoming 
---
 .../impl/WxCpExternalContactServiceImpl.java  |  11 +-
 .../weixin/cp/bean/WxCpContactWayInfo.java    | 309 ++++++++++--------
 .../cp/util/json/WxCpConclusionAdapter.java   |   8 +-
 .../WxCpExternalContactServiceImplTest.java   |  25 +-
 4 files changed, 188 insertions(+), 165 deletions(-)

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 b38c6b868..952391cf9 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
@@ -28,12 +28,12 @@ public class WxCpExternalContactServiceImpl implements WxCpExternalContactServic
   @Override
   public WxCpContactWayResult addContactWay(@NonNull WxCpContactWayInfo info) throws WxErrorException {
 
-    if (info.getUsers() != null && info.getUsers().size() > 100) {
+    if (info.getContactWay().getUsers() != null && info.getContactWay().getUsers().size() > 100) {
       throw new RuntimeException("「联系我」使用人数默认限制不超过100人(包括部门展开后的人数)");
     }
 
     final String url = this.mainService.getWxCpConfigStorage().getApiUrl(ADD_CONTACT_WAY);
-    String responseContent = this.mainService.post(url, info.toJson());
+    String responseContent = this.mainService.post(url, info.getContactWay().toJson());
 
     return WxCpContactWayResult.fromJson(responseContent);
   }
@@ -45,21 +45,20 @@ public WxCpContactWayInfo getContactWay(@NonNull String configId) throws WxError
 
     final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_CONTACT_WAY);
     String responseContent = this.mainService.post(url, json.toString());
-
     return WxCpContactWayInfo.fromJson(responseContent);
   }
 
   @Override
   public WxCpBaseResp updateContactWay(@NonNull WxCpContactWayInfo info) throws WxErrorException {
-    if (StringUtils.isBlank(info.getConfigId())) {
+    if (StringUtils.isBlank(info.getContactWay().getConfigId())) {
       throw new RuntimeException("更新「联系我」方式需要指定configId");
     }
-    if (info.getUsers() != null && info.getUsers().size() > 100) {
+    if (info.getContactWay().getUsers() != null && info.getContactWay().getUsers().size() > 100) {
       throw new RuntimeException("「联系我」使用人数默认限制不超过100人(包括部门展开后的人数)");
     }
 
     final String url = this.mainService.getWxCpConfigStorage().getApiUrl(UPDATE_CONTACT_WAY);
-    String responseContent = this.mainService.post(url, info.toJson());
+    String responseContent = this.mainService.post(url, info.getContactWay().toJson());
 
     return WxCpBaseResp.fromJson(responseContent);
   }
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpContactWayInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpContactWayInfo.java
index cd460053d..8ef22a587 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpContactWayInfo.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpContactWayInfo.java
@@ -3,7 +3,9 @@
 import com.google.gson.annotations.JsonAdapter;
 import com.google.gson.annotations.SerializedName;
 import lombok.Data;
+import lombok.Getter;
 import lombok.NoArgsConstructor;
+import lombok.Setter;
 import me.chanjar.weixin.cp.util.json.WxCpConclusionAdapter;
 import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
 
@@ -18,132 +20,168 @@
 @NoArgsConstructor
 public class WxCpContactWayInfo {
 
-  /**
-   * 联系方式的配置id
-   */
-  @SerializedName("config_id")
-  private String configId;
-
-  /**
-   * 
-   * 必填
-   * 联系方式类型,1-单人, 2-多人
-   * 
- */ - private TYPE type; - - /** - *
-   * 必填
-   * 场景,1-在小程序中联系,2-通过二维码联系
-   * 
- */ - private SCENE scene; - - /** - *
-   * 非必填
-   * 在小程序中联系时使用的控件样式
-   * 单人样式(type=1)时可选1,2,3
-   * 多人样式(type=2)时可选1,2
-   * 
- */ - private Integer style; - - /** - *
-   * 非必填
-   * 联系方式的备注信息,用于助记,不超过30个字符
-   * 
- */ - private String remark; - - /** - *
-   * 非必填
-   * 外部客户添加时是否无需验证,默认为true
-   * 
- */ - @SerializedName("skip_verify") - private Boolean skipVerify = Boolean.TRUE; - - /** - *
-   * 非必填
-   * 企业自定义的state参数,用于区分不同的添加渠道,在调用“获取外部联系人详情(WxCpExternalContactService.getContactDetail)”  时会返回该参数值,不超过30个字符
-   * 
- */ - private String state; - - /** - *
-   * 联系二维码的URL,仅在scene为2时返回
-   * 
- */ - @SerializedName("qr_code") - private String qrCode; - - /** - *
-   * 使用该联系方式的用户userID列表,在type为1时为必填,且只能有一个
-   * 
- */ - @SerializedName("user") - private List users; - - - /** - *
-   * 非必填
-   * 使用该联系方式的部门id列表,只在type为2时有效
-   * 
- */ - @SerializedName("party") - private List partys; - - /** - *
-   * 非必填
-   * 是否临时会话模式,true表示使用临时会话模式,默认为false
-   * 
- */ - @SerializedName("is_temp") - private Boolean isTemp = Boolean.FALSE; - - /** - *
-   * 非必填
-   * 临时会话二维码有效期,以秒为单位。该参数仅在is_temp为true时有效,默认7天
-   * 
- */ - @SerializedName("expires_in") - private Integer expiresIn; - - /** - *
-   * 非必填
-   * 临时会话有效期,以秒为单位。该参数仅在is_temp为true时有效,默认为添加好友后24小时
-   * 
- */ - @SerializedName("chat_expires_in") - private Integer chatExpiresIn; - - /** - *
-   * 非必填
-   * 可进行临时会话的客户unionid,该参数仅在is_temp为true时有效,如不指定则不进行限制
-   * 
- */ - @SerializedName("unionid") - private String unionId; - - /** - *
-   * 非必填
-   * 结束语,会话结束时自动发送给客户,可参考“结束语定义”,仅在is_temp为true时有效
-   * 
- */ - private Conclusion conclusions; + @SerializedName("contact_way") + private ContactWay contactWay; + + @Getter + @Setter + public static class ContactWay { + /** + * 联系方式的配置id + */ + @SerializedName("config_id") + private String configId; + + /** + *
+     * 必填
+     * 联系方式类型,1-单人, 2-多人
+     * 
+ */ + private TYPE type; + + /** + *
+     * 必填
+     * 场景,1-在小程序中联系,2-通过二维码联系
+     * 
+ */ + private SCENE scene; + + /** + *
+     * 非必填
+     * 在小程序中联系时使用的控件样式
+     * 单人样式(type=1)时可选1,2,3
+     * 多人样式(type=2)时可选1,2
+     * 
+ */ + private Integer style; + + /** + *
+     * 非必填
+     * 联系方式的备注信息,用于助记,不超过30个字符
+     * 
+ */ + private String remark; + + /** + *
+     * 非必填
+     * 外部客户添加时是否无需验证,默认为true
+     * 
+ */ + @SerializedName("skip_verify") + private Boolean skipVerify = Boolean.TRUE; + + /** + *
+     * 非必填
+     * 企业自定义的state参数,用于区分不同的添加渠道,在调用“获取外部联系人详情(WxCpExternalContactService.getContactDetail)”  时会返回该参数值,不超过30个字符
+     * 
+ */ + private String state; + + /** + *
+     * 联系二维码的URL,仅在scene为2时返回
+     * 
+ */ + @SerializedName("qr_code") + private String qrCode; + + /** + *
+     * 使用该联系方式的用户userID列表,在type为1时为必填,且只能有一个
+     * 
+ */ + @SerializedName("user") + private List users; + + + /** + *
+     * 非必填
+     * 使用该联系方式的部门id列表,只在type为2时有效
+     * 
+ */ + @SerializedName("party") + private List partys; + + /** + *
+     * 非必填
+     * 是否临时会话模式,true表示使用临时会话模式,默认为false
+     * 
+ */ + @SerializedName("is_temp") + private Boolean isTemp = Boolean.FALSE; + + /** + *
+     * 非必填
+     * 临时会话二维码有效期,以秒为单位。该参数仅在is_temp为true时有效,默认7天
+     * 
+ */ + @SerializedName("expires_in") + private Integer expiresIn; + + /** + *
+     * 非必填
+     * 临时会话有效期,以秒为单位。该参数仅在is_temp为true时有效,默认为添加好友后24小时
+     * 
+ */ + @SerializedName("chat_expires_in") + private Integer chatExpiresIn; + + /** + *
+     * 非必填
+     * 可进行临时会话的客户unionid,该参数仅在is_temp为true时有效,如不指定则不进行限制
+     * 
+ */ + @SerializedName("unionid") + private String unionId; + + /** + *
+     * 非必填
+     * 结束语,会话结束时自动发送给客户,可参考“结束语定义”,仅在is_temp为true时有效
+     * 
+ */ + private Conclusion conclusions; + + public static WxCpContactWayInfo.ContactWay fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpContactWayInfo.ContactWay.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + + /** + * 结束语定义 + */ + @Data + @JsonAdapter(WxCpConclusionAdapter.class) + public static class Conclusion { + private String textContent; + private String imgMediaId; + private String imgPicUrl; + private String linkTitle; + private String linkPicUrl; + private String linkDesc; + private String linkUrl; + private String miniProgramTitle; + private String miniProgramPicMediaId; + private String miniProgramAppId; + private String miniProgramPage; + } + + } + public static WxCpContactWayInfo fromJson(String json) { return WxCpGsonBuilder.create().fromJson(json, WxCpContactWayInfo.class); @@ -153,25 +191,6 @@ public String toJson() { return WxCpGsonBuilder.create().toJson(this); } - /** - * 结束语定义 - */ - @Data - @JsonAdapter(WxCpConclusionAdapter.class) - public static class Conclusion { - private String textContent; - private String imgMediaId; - private String imgPicUrl; - private String linkTitle; - private String linkPicUrl; - private String linkDesc; - private String linkUrl; - private String miniProgramTitle; - private String miniProgramPicMediaId; - private String miniProgramAppId; - private String miniProgramPage; - } - public enum TYPE { /** * 单人 diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpConclusionAdapter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpConclusionAdapter.java index 1a9aab8bf..2d7e27da9 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpConclusionAdapter.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpConclusionAdapter.java @@ -11,12 +11,12 @@ * * @author element */ -public class WxCpConclusionAdapter implements JsonSerializer, JsonDeserializer { +public class WxCpConclusionAdapter implements JsonSerializer, JsonDeserializer { @Override - public WxCpContactWayInfo.Conclusion deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + public WxCpContactWayInfo.ContactWay.Conclusion deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { JsonObject jsonObject = json.getAsJsonObject(); - WxCpContactWayInfo.Conclusion conclusion = new WxCpContactWayInfo.Conclusion(); + WxCpContactWayInfo.ContactWay.Conclusion conclusion = new WxCpContactWayInfo.ContactWay.Conclusion(); if (jsonObject.get("text") != null) { JsonObject jsonText = jsonObject.get("text").getAsJsonObject(); @@ -77,7 +77,7 @@ public WxCpContactWayInfo.Conclusion deserialize(JsonElement json, Type typeOfT, } @Override - public JsonElement serialize(WxCpContactWayInfo.Conclusion src, Type typeOfSrc, JsonSerializationContext context) { + public JsonElement serialize(WxCpContactWayInfo.ContactWay.Conclusion src, Type typeOfSrc, JsonSerializationContext context) { JsonObject json = new JsonObject(); if (StringUtils.isNotBlank(src.getTextContent())) { JsonObject jsonText = new JsonObject(); diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java index df086037a..8a5a76496 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java @@ -35,21 +35,24 @@ public void testGetExternalContact() throws WxErrorException { @Test public void testAddContactWay() throws WxErrorException { - final String concatUserId = "符合要求的userId"; + final String concatUserId = "HuangXiaoMing"; + + WxCpContactWayInfo.ContactWay wayInfo = new WxCpContactWayInfo.ContactWay(); + wayInfo.setType(WxCpContactWayInfo.TYPE.SIGLE); + wayInfo.setScene(WxCpContactWayInfo.SCENE.QRCODE); + wayInfo.setUsers(Lists.newArrayList(concatUserId)); + wayInfo.setRemark("CreateDate:" + DateFormatUtils.ISO_8601_EXTENDED_DATETIME_FORMAT.format(new Date())); WxCpContactWayInfo info = new WxCpContactWayInfo(); - info.setType(WxCpContactWayInfo.TYPE.SIGLE); - info.setScene(WxCpContactWayInfo.SCENE.MINIPROGRAM); - info.setUsers(Lists.newArrayList(concatUserId)); - info.setRemark("CreateDate:" + DateFormatUtils.ISO_8601_EXTENDED_DATETIME_FORMAT.format(new Date())); + info.setContactWay(wayInfo); this.wxCpService.getExternalContactService().addContactWay(info); } @Test public void testGetContactWay() throws WxErrorException { - final String configId = "2d7a68c657663afbd1d90db19a4b5ee9"; + final String configId = "39fea3d93e30faaa8c7a9edd4cfe4d08"; WxCpContactWayInfo contactWayInfo = this.wxCpService.getExternalContactService().getContactWay(configId); - System.out.println(contactWayInfo); + System.out.println(contactWayInfo.toJson()); assertNotNull(contactWayInfo); } @@ -57,10 +60,12 @@ public void testGetContactWay() throws WxErrorException { public void testUpdateContactWay() throws WxErrorException { final String configId = "2d7a68c657663afbd1d90db19a4b5ee9"; final String concatUserId = "符合要求的userId"; + WxCpContactWayInfo.ContactWay wayInfo = new WxCpContactWayInfo.ContactWay(); + wayInfo.setConfigId(configId); + wayInfo.setUsers(Lists.newArrayList(concatUserId)); + wayInfo.setRemark("CreateDate:" + DateFormatUtils.ISO_8601_EXTENDED_DATETIME_FORMAT.format(new Date())); WxCpContactWayInfo info = new WxCpContactWayInfo(); - info.setConfigId(configId); - info.setUsers(Lists.newArrayList(concatUserId)); - info.setRemark("CreateDate:" + DateFormatUtils.ISO_8601_EXTENDED_DATETIME_FORMAT.format(new Date())); + info.setContactWay(wayInfo); WxCpBaseResp resp = this.wxCpService.getExternalContactService().updateContactWay(info); System.out.println(resp); assertNotNull(resp); From 58189b8f1eacb660dc854556cf19d618374ca5ab Mon Sep 17 00:00:00 2001 From: huangxiaoming Date: Mon, 31 Aug 2020 19:07:36 +0800 Subject: [PATCH 16/25] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E8=AE=BF=E9=97=AE=E7=94=A8=E6=88=B7=E8=BA=AB=E4=BB=BD=E3=80=81?= =?UTF-8?q?=E8=8E=B7=E5=8F=96=E8=AE=BF=E9=97=AE=E7=94=A8=E6=88=B7=E6=95=8F?= =?UTF-8?q?=E6=84=9F=E4=BF=A1=E6=81=AF=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: huangxiaoming --- .../chanjar/weixin/cp/api/WxCpTpService.java | 19 ++++++-- .../cp/api/impl/BaseWxCpTpServiceImpl.java | 14 +++++- .../weixin/cp/bean/WxCpTpUserDetail.java | 43 +++++++++++++++++++ .../weixin/cp/bean/WxCpTpUserInfo.java | 43 +++++++++++++++++++ .../weixin/cp/constant/WxCpApiPathConsts.java | 2 + 5 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpUserDetail.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpUserInfo.java diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTpService.java index ad2f403af..83e81210b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTpService.java @@ -5,10 +5,7 @@ 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.WxCpMaJsCode2SessionResult; -import me.chanjar.weixin.cp.bean.WxCpTpAuthInfo; -import me.chanjar.weixin.cp.bean.WxCpTpCorp; -import me.chanjar.weixin.cp.bean.WxCpTpPermanentCodeInfo; +import me.chanjar.weixin.cp.bean.*; import me.chanjar.weixin.cp.config.WxCpTpConfigStorage; /** @@ -205,4 +202,18 @@ public interface WxCpTpService { */ RequestHttp getRequestHttp(); + /** + * 获取访问用户身份 + * @param code + * @return + */ + WxCpTpUserInfo getuserinfo3rd(String code) throws WxErrorException; + + /** + * 获取访问用户敏感信息 + * @param userTicket + * @return + */ + WxCpTpUserDetail getuserdetail3rd(String userTicket) throws WxErrorException; + } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java index 191bfec0d..8a85ff6c3 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java @@ -4,8 +4,8 @@ import com.google.gson.JsonObject; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import me.chanjar.weixin.common.enums.WxType; import me.chanjar.weixin.common.bean.WxAccessToken; +import me.chanjar.weixin.common.enums.WxType; import me.chanjar.weixin.common.error.WxCpErrorMsgEnum; import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.error.WxErrorException; @@ -273,4 +273,16 @@ public void setTmpDirFile(File tmpDirFile) { return this; } + @Override + public WxCpTpUserInfo getuserinfo3rd(String code) throws WxErrorException{ + String result = post(configStorage.getApiUrl(GET_USERINFO3RD), code); + return WxCpTpUserInfo.fromJson(result); + } + + @Override + public WxCpTpUserDetail getuserdetail3rd(String userTicket) throws WxErrorException{ + String result = post(configStorage.getApiUrl(GET_USERDETAIL3RD), userTicket); + return WxCpTpUserDetail.fromJson(result); + } + } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpUserDetail.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpUserDetail.java new file mode 100644 index 000000000..586b0a4b8 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpUserDetail.java @@ -0,0 +1,43 @@ +package me.chanjar.weixin.cp.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; + +/** + * 获取访问用户敏感信息 + * @author huangxiaoming + */ +@Data +public class WxCpTpUserDetail implements Serializable { + + private static final long serialVersionUID = -5028321625140879571L; + @SerializedName("CorpId") + private String corpId; + + @SerializedName("UserId") + private String userId; + + @SerializedName("DeviceId") + private String deviceId; + + @SerializedName("user_ticket") + private String userTicket; + + @SerializedName("expires_in") + private String expiresIn; + + @SerializedName("open_userid") + private String openUserId; + + public static WxCpTpUserDetail fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpTpUserDetail.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpUserInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpUserInfo.java new file mode 100644 index 000000000..448b32f7e --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpUserInfo.java @@ -0,0 +1,43 @@ +package me.chanjar.weixin.cp.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; + +/** + * 获取访问用户身份 + * @author huangxiaoming + */ +@Data +public class WxCpTpUserInfo implements Serializable { + + private static final long serialVersionUID = -5028321625140879571L; + @SerializedName("corpid") + private String corpId; + + @SerializedName("userid") + private String userId; + + @SerializedName("name") + private String name; + + @SerializedName("gender") + private String gender; + + @SerializedName("avatar") + private String avatar; + + @SerializedName("qr_code") + private String qrCode; + + public static WxCpTpUserInfo fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpTpUserInfo.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + +} 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 00e7616d1..df0b7ce6a 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 @@ -94,6 +94,8 @@ public static class Tp { public static final String GET_PROVIDER_TOKEN = "/cgi-bin/service/get_provider_token"; public static final String GET_PREAUTH_CODE = "/cgi-bin/service/get_pre_auth_code"; public static final String GET_AUTH_INFO = "/cgi-bin/service/get_auth_info"; + public static final String GET_USERINFO3RD = "/cgi-bin/service/getuserinfo3rd"; + public static final String GET_USERDETAIL3RD = "/cgi-bin/service/getuserdetail3rd"; } public static class User { From 6ce8b2d2c031cb6829c65e3ecd0a34f768164bc6 Mon Sep 17 00:00:00 2001 From: huangxiaoming Date: Thu, 3 Sep 2020 18:31:50 +0800 Subject: [PATCH 17/25] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E7=99=BB=E5=BD=95=E7=94=A8=E6=88=B7=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: huangxiaoming --- .../chanjar/weixin/cp/api/WxCpTpService.java | 9 ++ .../cp/api/impl/BaseWxCpTpServiceImpl.java | 5 + .../weixin/cp/bean/WxCpTpLoginInfo.java | 95 +++++++++++++++++++ .../weixin/cp/bean/WxCpTpUserDetail.java | 24 ++--- .../weixin/cp/bean/WxCpTpUserInfo.java | 24 ++--- .../weixin/cp/constant/WxCpApiPathConsts.java | 1 + 6 files changed, 134 insertions(+), 24 deletions(-) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpLoginInfo.java diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTpService.java index 83e81210b..59f071479 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTpService.java @@ -216,4 +216,13 @@ public interface WxCpTpService { */ WxCpTpUserDetail getuserdetail3rd(String userTicket) throws WxErrorException; + /** + * 获取登录用户信息 + * 通过扫码登陆获取auth_code,参考配置:https://work.weixin.qq.com/api/doc/90001/90143/91124 + * @param authCode + * @return + * @throws WxErrorException + */ + WxCpTpLoginInfo getLoginInfo(String authCode) throws WxErrorException; + } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java index 8a85ff6c3..971d73749 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java @@ -285,4 +285,9 @@ public WxCpTpUserDetail getuserdetail3rd(String userTicket) throws WxErrorExcept return WxCpTpUserDetail.fromJson(result); } + @Override + public WxCpTpLoginInfo getLoginInfo(String authCode) throws WxErrorException{ + String result = post(configStorage.getApiUrl(GET_LOGIN_INFO), authCode); + return WxCpTpLoginInfo.fromJson(result); + } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpLoginInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpLoginInfo.java new file mode 100644 index 000000000..520a906d8 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpLoginInfo.java @@ -0,0 +1,95 @@ +package me.chanjar.weixin.cp.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +/** + * 获取登录用户信息 + * @author huangxiaoming + */ +@Data +public class WxCpTpLoginInfo extends WxCpBaseResp { + + private static final long serialVersionUID = -5028321625140879571L; + + @SerializedName("usertype") + private Integer userType; + + @SerializedName("user_info") + private UserInfo userInfo; + + @SerializedName("corp_info") + private CorpInfo corpInfo; + + @SerializedName("agent") + private List agents; + + @SerializedName("auth_info") + private AuthInfo authInfo; + + @Getter + @Setter + public static class UserInfo { + @SerializedName("userid") + private String userid; + + @SerializedName("name") + private String name; + + @SerializedName("avatar") + private String avatar; + } + + @Getter + @Setter + public static class CorpInfo { + @SerializedName("corpid") + private String corpId; + } + + @Getter + @Setter + public static class Agent { + + @SerializedName("agentid") + private Integer agentId; + + @SerializedName("auth_type") + private Integer authType; + } + + @Getter + @Setter + public static class AuthInfo { + + @SerializedName("department") + private List departments; + + @Getter + @Setter + public static class department { + + @SerializedName("id") + private Integer id; + + @SerializedName("writable") + private Boolean writable; + + } + } + + public static WxCpTpLoginInfo fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpTpLoginInfo.class); + } + + public String toJson() { + return WxCpGsonBuilder.create().toJson(this); + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpUserDetail.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpUserDetail.java index 586b0a4b8..11ace18f4 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpUserDetail.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpUserDetail.java @@ -7,30 +7,30 @@ import java.io.Serializable; /** - * 获取访问用户敏感信息 + * 获取访问用户身份 * @author huangxiaoming */ @Data -public class WxCpTpUserDetail implements Serializable { +public class WxCpTpUserDetail extends WxCpBaseResp { private static final long serialVersionUID = -5028321625140879571L; - @SerializedName("CorpId") + @SerializedName("corpid") private String corpId; - @SerializedName("UserId") + @SerializedName("userid") private String userId; - @SerializedName("DeviceId") - private String deviceId; + @SerializedName("name") + private String name; - @SerializedName("user_ticket") - private String userTicket; + @SerializedName("gender") + private String gender; - @SerializedName("expires_in") - private String expiresIn; + @SerializedName("avatar") + private String avatar; - @SerializedName("open_userid") - private String openUserId; + @SerializedName("qr_code") + private String qrCode; public static WxCpTpUserDetail fromJson(String json) { return WxCpGsonBuilder.create().fromJson(json, WxCpTpUserDetail.class); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpUserInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpUserInfo.java index 448b32f7e..53fc2a174 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpUserInfo.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpUserInfo.java @@ -7,30 +7,30 @@ import java.io.Serializable; /** - * 获取访问用户身份 + * 获取访问用户敏感信息 * @author huangxiaoming */ @Data -public class WxCpTpUserInfo implements Serializable { +public class WxCpTpUserInfo extends WxCpBaseResp { private static final long serialVersionUID = -5028321625140879571L; - @SerializedName("corpid") + @SerializedName("CorpId") private String corpId; - @SerializedName("userid") + @SerializedName("UserId") private String userId; - @SerializedName("name") - private String name; + @SerializedName("DeviceId") + private String deviceId; - @SerializedName("gender") - private String gender; + @SerializedName("user_ticket") + private String userTicket; - @SerializedName("avatar") - private String avatar; + @SerializedName("expires_in") + private String expiresIn; - @SerializedName("qr_code") - private String qrCode; + @SerializedName("open_userid") + private String openUserId; public static WxCpTpUserInfo fromJson(String json) { return WxCpGsonBuilder.create().fromJson(json, WxCpTpUserInfo.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 7eddfc2a7..a179e098a 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 @@ -111,6 +111,7 @@ public static class Tp { public static final String GET_AUTH_INFO = "/cgi-bin/service/get_auth_info"; public static final String GET_USERINFO3RD = "/cgi-bin/service/getuserinfo3rd"; public static final String GET_USERDETAIL3RD = "/cgi-bin/service/getuserdetail3rd"; + public static final String GET_LOGIN_INFO = "/cgi-bin/service/get_login_info"; } public static class User { From 8953050ce9a833da1c7e68c5684b43f03abf0351 Mon Sep 17 00:00:00 2001 From: huangxiaoming Date: Thu, 17 Sep 2020 10:44:36 +0800 Subject: [PATCH 18/25] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E7=AC=AC=E4=B8=89=E6=96=B9=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E7=99=BB=E9=99=86=E4=BF=A1=E6=81=AF=EF=BC=8C=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BC=81=E4=B8=9AToken=E7=BC=93=E5=AD=98=E4=BF=9D=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: huangxiaoming --- .../weixin/cp/api/WxCpCorpService.java | 112 +++++++++++ .../chanjar/weixin/cp/api/WxCpTpService.java | 9 - .../cp/api/impl/BaseWxCpCorpServiceImpl.java | 177 ++++++++++++++++ .../cp/api/impl/BaseWxCpTpServiceImpl.java | 21 +- .../WxCpCorpServiceApacheHttpClientImpl.java | 116 +++++++++++ .../cp/api/impl/WxCpCorpServiceImpl.java | 10 + .../weixin/cp/api/impl/WxCpTpServiceImpl.java | 2 + .../weixin/cp/bean/WxCpTpLoginInfo.java | 5 +- .../cp/config/WxCpCorpConfigStorage.java | 74 +++++++ .../weixin/cp/config/WxCpTpConfigStorage.java | 1 + .../impl/WxCpCorpDefaultConfigImpl.java | 189 ++++++++++++++++++ .../config/impl/WxCpTpDefaultConfigImpl.java | 8 + 12 files changed, 705 insertions(+), 19 deletions(-) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpCorpService.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpCorpServiceImpl.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpServiceApacheHttpClientImpl.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpServiceImpl.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpCorpConfigStorage.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpDefaultConfigImpl.java diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpCorpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpCorpService.java new file mode 100644 index 000000000..62dcf17cd --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpCorpService.java @@ -0,0 +1,112 @@ +package me.chanjar.weixin.cp.api; + +import me.chanjar.weixin.common.bean.WxAccessToken; +import me.chanjar.weixin.common.error.WxErrorException; +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.config.WxCpCorpConfigStorage; +import me.chanjar.weixin.cp.config.WxCpTpConfigStorage; + +/** + * 微信第三方应用API的Service. + * + * @author huangxiaoming + */ +public interface WxCpCorpService { + + + /** + * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求. + * + * @param url 接口地址 + * @param queryParam 请求参数 + */ + String get(String url, String queryParam) throws WxErrorException; + + /** + * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求. + * + * @param url 接口地址 + * @param postData 请求body字符串 + */ + String post(String url, String postData) throws WxErrorException; + + /** + *
+   * Service没有实现某个API的时候,可以用这个,
+   * 比{@link #get}和{@link #post}方法更灵活,可以自己构造RequestExecutor用来处理不同的参数和不同的返回类型。
+   * 可以参考,{@link MediaUploadRequestExecutor}的实现方法
+   * 
+ * + * @param executor 执行器 + * @param uri 请求地址 + * @param data 参数 + * @param 请求值类型 + * @param 返回值类型 + */ + T execute(RequestExecutor executor, String uri, E data) throws WxErrorException; + + /** + *
+   * 设置当微信系统响应系统繁忙时,要等待多少 retrySleepMillis(ms) * 2^(重试次数 - 1) 再发起重试.
+   * 默认:1000ms
+   * 
+ * + * @param retrySleepMillis 重试休息时间 + */ + void setRetrySleepMillis(int retrySleepMillis); + + /** + *
+   * 设置当微信系统响应系统繁忙时,最大重试次数.
+   * 默认:5次
+   * 
+ * + * @param maxRetryTimes 最大重试次数 + */ + void setMaxRetryTimes(int maxRetryTimes); + + /** + * 初始化http请求对象 + */ + void initHttp(); + + /** + * 获取WxMpConfigStorage 对象. + * + * @return WxMpConfigStorage + */ + WxCpCorpConfigStorage getWxCpCorpConfigStorage(); + + /** + * 注入 {@link WxCpTpConfigStorage} 的实现. + * + * @param wxConfigProvider 配置对象 + */ + void setWxCpCorpConfigStorage(WxCpCorpConfigStorage wxConfigProvider); + + /** + * http请求对象. + */ + RequestHttp getRequestHttp(); + + /** + * 获取服务商的token + * @param forceRefresh + * @return + * @throws WxErrorException + */ + String getProviderToken(boolean forceRefresh) throws WxErrorException; + + /** + * 获取登录用户信息 + * 通过扫码登陆获取auth_code,参考配置:https://work.weixin.qq.com/api/doc/90001/90143/91124 + * @param authCode + * @return + * @throws WxErrorException + */ + WxCpTpLoginInfo getLoginInfo(String authCode) throws WxErrorException; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTpService.java index 59f071479..83e81210b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTpService.java @@ -216,13 +216,4 @@ public interface WxCpTpService { */ WxCpTpUserDetail getuserdetail3rd(String userTicket) throws WxErrorException; - /** - * 获取登录用户信息 - * 通过扫码登陆获取auth_code,参考配置:https://work.weixin.qq.com/api/doc/90001/90143/91124 - * @param authCode - * @return - * @throws WxErrorException - */ - WxCpTpLoginInfo getLoginInfo(String authCode) throws WxErrorException; - } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpCorpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpCorpServiceImpl.java new file mode 100644 index 000000000..f86c5fcb8 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpCorpServiceImpl.java @@ -0,0 +1,177 @@ +package me.chanjar.weixin.cp.api.impl; + +import com.google.common.base.Joiner; +import com.google.gson.JsonObject; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.bean.WxAccessToken; +import me.chanjar.weixin.common.enums.WxType; +import me.chanjar.weixin.common.error.WxCpErrorMsgEnum; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.DataUtils; +import me.chanjar.weixin.common.util.crypto.SHA1; +import me.chanjar.weixin.common.util.http.RequestExecutor; +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.common.util.json.GsonParser; +import me.chanjar.weixin.cp.api.WxCpCorpService; +import me.chanjar.weixin.cp.api.WxCpTpService; +import me.chanjar.weixin.cp.bean.*; +import me.chanjar.weixin.cp.config.WxCpCorpConfigStorage; +import me.chanjar.weixin.cp.config.WxCpTpConfigStorage; +import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.methods.HttpPost; + +import java.io.File; +import java.io.IOException; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.Map; + +import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Tp.*; + +/** + * + * @author huangxiaoming + */ +@Slf4j +public abstract class BaseWxCpCorpServiceImpl implements WxCpCorpService, RequestHttp { + + /** + * 全局服务商token + */ + protected final Object globalProviderTokenRefreshLock = new Object(); + + protected WxCpCorpConfigStorage configStorage; + + /** + * 临时文件目录. + */ + private File tmpDirFile; + private int retrySleepMillis = 1000; + private int maxRetryTimes = 5; + + + @Override + public String get(String url, String queryParam) throws WxErrorException { + return execute(SimpleGetRequestExecutor.create(this), url, queryParam); + } + + @Override + public String post(String url, String postData) throws WxErrorException { + return execute(SimplePostRequestExecutor.create(this), url, postData); + } + + /** + * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求. + */ + @Override + public T execute(RequestExecutor executor, String uri, E data) throws WxErrorException { + int retryTimes = 0; + do { + try { + return this.executeInternal(executor, uri, data); + } catch (WxErrorException e) { + if (retryTimes + 1 > this.maxRetryTimes) { + log.warn("重试达到最大次数【{}】", this.maxRetryTimes); + //最后一次重试失败后,直接抛出异常,不再等待 + throw new RuntimeException("微信服务端异常,超出重试次数"); + } + + WxError error = e.getError(); + /* + * -1 系统繁忙, 1000ms后重试 + */ + if (error.getErrorCode() == -1) { + int sleepMillis = this.retrySleepMillis * (1 << retryTimes); + try { + log.debug("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1); + Thread.sleep(sleepMillis); + } catch (InterruptedException e1) { + Thread.currentThread().interrupt(); + } + } else { + throw e; + } + } + } while (retryTimes++ < this.maxRetryTimes); + + log.warn("重试达到最大次数【{}】", this.maxRetryTimes); + throw new RuntimeException("微信服务端异常,超出重试次数"); + } + + protected T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException { + E dataForLog = DataUtils.handleDataWithSecret(data); + + if (uri.contains("access_token=")) { + throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri); + } + String providerAccessToken = getProviderToken(false); + + String uriWithAccessToken = uri + (uri.contains("?") ? "&" : "?") + "access_token=" + providerAccessToken; + + try { + T result = executor.execute(uriWithAccessToken, data, WxType.CP); + log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result); + return result; + } catch (WxErrorException e) { + WxError error = e.getError(); + /* + * 发生以下情况时尝试刷新suite_access_token + * 42009 suite_access_token已过期 + */ + if (error.getErrorCode() == WxCpErrorMsgEnum.CODE_42009.getCode()) { + // 强制设置wxCpTpConfigStorage它的suite access token过期了,这样在下一次请求里就会刷新suite access token + this.configStorage.getProviderToken(); + if (this.getWxCpCorpConfigStorage().autoRefreshToken()) { + log.warn("即将重新获取新的access_token,错误代码:{},错误信息:{}", error.getErrorCode(), error.getErrorMsg()); + return this.execute(executor, uri, data); + } + } + + if (error.getErrorCode() != 0) { + log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error); + throw new WxErrorException(error, e); + } + return null; + } catch (IOException e) { + log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage()); + throw new RuntimeException(e); + } + } + + @Override + public void setWxCpCorpConfigStorage(WxCpCorpConfigStorage wxConfigProvider) { + this.configStorage = wxConfigProvider; + this.initHttp(); + } + + @Override + public void setRetrySleepMillis(int retrySleepMillis) { + this.retrySleepMillis = retrySleepMillis; + } + + @Override + public void setMaxRetryTimes(int maxRetryTimes) { + this.maxRetryTimes = maxRetryTimes; + } + + @Override + public RequestHttp getRequestHttp() { + return this; + } + + @Override + public WxCpTpLoginInfo getLoginInfo(String authCode) throws WxErrorException{ + + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("auth_code", authCode); + String result = post(configStorage.getApiUrl(GET_LOGIN_INFO), jsonObject.toString()); + return WxCpTpLoginInfo.fromJson(result); + } + + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java index 971d73749..6ae1d2269 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java @@ -275,19 +275,26 @@ public void setTmpDirFile(File tmpDirFile) { @Override public WxCpTpUserInfo getuserinfo3rd(String code) throws WxErrorException{ - String result = post(configStorage.getApiUrl(GET_USERINFO3RD), code); + + JsonObject parms = new JsonObject(); + parms.addProperty("code", code); + + String url = configStorage.getApiUrl(GET_USERINFO3RD); + if (StringUtils.isNotBlank(code)) { + url += "?code=" + code; + } + String result = get(url,null); return WxCpTpUserInfo.fromJson(result); } @Override public WxCpTpUserDetail getuserdetail3rd(String userTicket) throws WxErrorException{ - String result = post(configStorage.getApiUrl(GET_USERDETAIL3RD), userTicket); + + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("user_ticket", userTicket); + String result = post(configStorage.getApiUrl(GET_USERDETAIL3RD), jsonObject.toString()); return WxCpTpUserDetail.fromJson(result); } - @Override - public WxCpTpLoginInfo getLoginInfo(String authCode) throws WxErrorException{ - String result = post(configStorage.getApiUrl(GET_LOGIN_INFO), authCode); - return WxCpTpLoginInfo.fromJson(result); - } + } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpServiceApacheHttpClientImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpServiceApacheHttpClientImpl.java new file mode 100644 index 000000000..90401700e --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpServiceApacheHttpClientImpl.java @@ -0,0 +1,116 @@ +package me.chanjar.weixin.cp.api.impl; + + +import com.google.gson.JsonObject; +import me.chanjar.weixin.common.enums.WxType; +import me.chanjar.weixin.common.error.WxError; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.http.HttpType; +import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; +import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder; +import me.chanjar.weixin.common.util.json.GsonParser; +import me.chanjar.weixin.cp.config.WxCpCorpConfigStorage; +import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; +import org.apache.http.Consts; +import org.apache.http.HttpHost; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicResponseHandler; +import org.apache.http.impl.client.CloseableHttpClient; + +import java.io.IOException; + +/** + * @author someone + */ +public class WxCpCorpServiceApacheHttpClientImpl extends BaseWxCpCorpServiceImpl { + private CloseableHttpClient httpClient; + private HttpHost httpProxy; + + @Override + public CloseableHttpClient getRequestHttpClient() { + return httpClient; + } + + @Override + public HttpHost getRequestHttpProxy() { + return httpProxy; + } + + @Override + public HttpType getRequestType() { + return HttpType.APACHE_HTTP; + } + + + @Override + public String getProviderToken(boolean forceRefresh) throws WxErrorException { + + if (!this.configStorage.isProviderTokenExpired() && !forceRefresh) { + return this.configStorage.getProviderToken(); + } + + synchronized (this.globalProviderTokenRefreshLock) { + try { + HttpPost httpPost = new HttpPost(configStorage.getApiUrl(WxCpApiPathConsts.Tp.GET_PROVIDER_TOKEN)); + if (this.httpProxy != null) { + RequestConfig config = RequestConfig.custom() + .setProxy(this.httpProxy).build(); + httpPost.setConfig(config); + } + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("corpid", this.configStorage.getCorpId()); + jsonObject.addProperty("provider_secret", this.configStorage.getProviderSecret()); + StringEntity entity = new StringEntity(jsonObject.toString(), Consts.UTF_8); + httpPost.setEntity(entity); + + String resultContent; + try (CloseableHttpClient httpclient = getRequestHttpClient(); + CloseableHttpResponse response = httpclient.execute(httpPost)) { + resultContent = new BasicResponseHandler().handleResponse(response); + } finally { + httpPost.releaseConnection(); + } + WxError error = WxError.fromJson(resultContent, WxType.CP); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + jsonObject = GsonParser.parse(resultContent); + String providerAccessToken = jsonObject.get("provider_access_token").getAsString(); + Integer expiresIn = jsonObject.get("expires_in").getAsInt(); + this.configStorage.updateProviderToken(providerAccessToken,expiresIn); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return this.configStorage.getProviderToken(); + } + + + @Override + public void initHttp() { + ApacheHttpClientBuilder apacheHttpClientBuilder = this.configStorage.getApacheHttpClientBuilder(); + if (null == apacheHttpClientBuilder) { + apacheHttpClientBuilder = DefaultApacheHttpClientBuilder.get(); + } + + apacheHttpClientBuilder.httpProxyHost(this.configStorage.getHttpProxyHost()) + .httpProxyPort(this.configStorage.getHttpProxyPort()) + .httpProxyUsername(this.configStorage.getHttpProxyUsername()) + .httpProxyPassword(this.configStorage.getHttpProxyPassword()); + + if (this.configStorage.getHttpProxyHost() != null && this.configStorage.getHttpProxyPort() > 0) { + this.httpProxy = new HttpHost(this.configStorage.getHttpProxyHost(), this.configStorage.getHttpProxyPort()); + } + + this.httpClient = apacheHttpClientBuilder.build(); + } + + @Override + public WxCpCorpConfigStorage getWxCpCorpConfigStorage() { + return this.configStorage; + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpServiceImpl.java new file mode 100644 index 000000000..0a19e5782 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpServiceImpl.java @@ -0,0 +1,10 @@ +package me.chanjar.weixin.cp.api.impl; + +/** + * 默认接口实现类,使用apache httpclient实现 + * @author huangxiaoming + */ +public class WxCpCorpServiceImpl extends WxCpCorpServiceApacheHttpClientImpl { + + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTpServiceImpl.java index f5582021e..cc1fcbc8a 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTpServiceImpl.java @@ -9,4 +9,6 @@ * @author zhenjun cai */ public class WxCpTpServiceImpl extends WxCpTpServiceApacheHttpClientImpl { + + } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpLoginInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpLoginInfo.java index 520a906d8..5ca1e5b6b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpLoginInfo.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTpLoginInfo.java @@ -1,19 +1,18 @@ package me.chanjar.weixin.cp.bean; import com.google.gson.annotations.SerializedName; -import lombok.Data; import lombok.Getter; import lombok.Setter; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; -import java.io.Serializable; import java.util.List; /** * 获取登录用户信息 * @author huangxiaoming */ -@Data +@Getter +@Setter public class WxCpTpLoginInfo extends WxCpBaseResp { private static final long serialVersionUID = -5028321625140879571L; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpCorpConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpCorpConfigStorage.java new file mode 100644 index 000000000..13bbf1db4 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpCorpConfigStorage.java @@ -0,0 +1,74 @@ +package me.chanjar.weixin.cp.config; + +import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; +import me.chanjar.weixin.cp.bean.WxCpProviderToken; + +import java.io.File; + +/** + * 微信客户端(第三方应用)配置存储 + * + * @author zhenjun cai + */ +public interface WxCpCorpConfigStorage { + + /** + * 设置企业微信服务器 baseUrl. + * 默认值是 https://qyapi.weixin.qq.com , 如果使用默认值,则不需要调用 setBaseApiUrl + * + * @param baseUrl 企业微信服务器 Url + */ + void setBaseApiUrl(String baseUrl); + + /** + * 读取企业微信 API Url. + * 支持私有化企业微信服务器. + */ + String getApiUrl(String path); + + String getCorpId(); + + String getProviderSecret(); + + String getToken(); + + String getAesKey(); + + String getHttpProxyHost(); + + int getHttpProxyPort(); + + String getHttpProxyUsername(); + + String getHttpProxyPassword(); + + public File getTmpDirFile(); + + /** + * http client builder. + * + * @return ApacheHttpClientBuilder + */ + ApacheHttpClientBuilder getApacheHttpClientBuilder(); + + /** + * 是否自动刷新token + * @return . + */ + boolean autoRefreshToken(); + + /** + * 服务商的token + * @return + */ + String getProviderToken(); + + boolean isProviderTokenExpired(); + + void expireProviderToken(); + + void updateProviderToken(WxCpProviderToken wxCpProviderToken); + + void updateProviderToken(String providerAccessToken, int expiresIn); + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpTpConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpTpConfigStorage.java index 40c29ed0c..958309e0a 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpTpConfigStorage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpTpConfigStorage.java @@ -89,4 +89,5 @@ public interface WxCpTpConfigStorage { * @return . */ boolean autoRefreshToken(); + } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpDefaultConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpDefaultConfigImpl.java new file mode 100644 index 000000000..29181e0a3 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpDefaultConfigImpl.java @@ -0,0 +1,189 @@ +package me.chanjar.weixin.cp.config.impl; + +import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; +import me.chanjar.weixin.cp.bean.WxCpProviderToken; +import me.chanjar.weixin.cp.config.WxCpCorpConfigStorage; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.File; +import java.io.Serializable; + +/** + * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化. + * + * @author someone + */ +public class WxCpCorpDefaultConfigImpl implements WxCpCorpConfigStorage, Serializable { + private static final long serialVersionUID = 6678780920621872824L; + + private volatile String corpId; + private volatile String providerSecret; + + private volatile String token; + private volatile String aesKey; + + private volatile String oauth2redirectUri; + + private volatile String httpProxyHost; + private volatile int httpProxyPort; + private volatile String httpProxyUsername; + private volatile String httpProxyPassword; + + private volatile File tmpDirFile; + + private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; + + private volatile String baseApiUrl; + + private volatile String providerToken; + + private volatile long providerTokenExpiresTime; + + + + + + @Override + public void setBaseApiUrl(String baseUrl) { + this.baseApiUrl = baseUrl; + } + + @Override + public String getApiUrl(String path) { + if (baseApiUrl == null) { + baseApiUrl = "https://qyapi.weixin.qq.com"; + } + return baseApiUrl + path; + } + + @Override + public String getCorpId() { + return this.corpId; + } + + @Override + public String getProviderSecret() { + return this.providerSecret; + } + + public void setProviderSecret(String providerSecret) { + this.providerSecret = providerSecret; + } + + public void setCorpId(String corpId) { + this.corpId = corpId; + } + + + @Override + public String getToken() { + return this.token; + } + + public void setToken(String token) { + this.token = token; + } + + @Override + public String getAesKey() { + return this.aesKey; + } + + public void setAesKey(String aesKey) { + this.aesKey = aesKey; + } + + public void setOauth2redirectUri(String oauth2redirectUri) { + this.oauth2redirectUri = oauth2redirectUri; + } + + @Override + public String getHttpProxyHost() { + return this.httpProxyHost; + } + + public void setHttpProxyHost(String httpProxyHost) { + this.httpProxyHost = httpProxyHost; + } + + @Override + public int getHttpProxyPort() { + return this.httpProxyPort; + } + + public void setHttpProxyPort(int httpProxyPort) { + this.httpProxyPort = httpProxyPort; + } + + @Override + public String getHttpProxyUsername() { + return this.httpProxyUsername; + } + + public void setHttpProxyUsername(String httpProxyUsername) { + this.httpProxyUsername = httpProxyUsername; + } + + @Override + public String getHttpProxyPassword() { + return this.httpProxyPassword; + } + + public void setHttpProxyPassword(String httpProxyPassword) { + this.httpProxyPassword = httpProxyPassword; + } + + @Override + public String toString() { + return WxCpGsonBuilder.create().toJson(this); + } + + @Override + public File getTmpDirFile() { + return this.tmpDirFile; + } + + public void setTmpDirFile(File tmpDirFile) { + this.tmpDirFile = tmpDirFile; + } + + @Override + public ApacheHttpClientBuilder getApacheHttpClientBuilder() { + return this.apacheHttpClientBuilder; + } + + @Override + public boolean autoRefreshToken() { + return true; + } + + @Override + public String getProviderToken() { + return this.providerToken; + } + + @Override + public boolean isProviderTokenExpired() { + return System.currentTimeMillis() > this.providerTokenExpiresTime; + } + + @Override + public void expireProviderToken() { + this.providerTokenExpiresTime = 0; + } + + @Override + public void updateProviderToken(WxCpProviderToken wxCpProviderToken) { + updateProviderToken(wxCpProviderToken.getProviderAccessToken(),wxCpProviderToken.getExpiresIn()); + } + + @Override + public void updateProviderToken(String providerAccessToken, int expiresIn) { + this.providerToken = providerAccessToken; + this.providerTokenExpiresTime = expiresIn; + } + + public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { + this.apacheHttpClientBuilder = apacheHttpClientBuilder; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpDefaultConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpDefaultConfigImpl.java index be4b046a4..908076e9a 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpDefaultConfigImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpDefaultConfigImpl.java @@ -43,6 +43,14 @@ public class WxCpTpDefaultConfigImpl implements WxCpTpConfigStorage, Serializabl private volatile String baseApiUrl; + private volatile String providerToken; + + private volatile long providerTokenExpiresTime; + + + + + @Override public void setBaseApiUrl(String baseUrl) { this.baseApiUrl = baseUrl; From 16eca5dd1dc65152e783faed122c62f3ea1c9701 Mon Sep 17 00:00:00 2001 From: huangxiaoming Date: Fri, 18 Sep 2020 10:42:12 +0800 Subject: [PATCH 19/25] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1Token=E6=8C=81=E4=B9=85=E5=8C=96Redis?= =?UTF-8?q?=E5=AD=98=E5=82=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: huangxiaoming --- .../cp/api/impl/BaseWxCpCorpServiceImpl.java | 6 +- .../impl/WxCpCorpDefaultConfigImpl.java | 6 +- .../config/impl/WxCpCorpRedisConfigImpl.java | 86 ++++++++++++ .../cp/config/impl/WxCpTpRedisConfigImpl.java | 127 ++++++++++++++++++ 4 files changed, 217 insertions(+), 8 deletions(-) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpRedisConfigImpl.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpRedisConfigImpl.java diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpCorpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpCorpServiceImpl.java index f86c5fcb8..3817df673 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpCorpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpCorpServiceImpl.java @@ -121,10 +121,10 @@ protected T executeInternal(RequestExecutor executor, String uri, E WxError error = e.getError(); /* * 发生以下情况时尝试刷新suite_access_token - * 42009 suite_access_token已过期 + * 40014 invalid access_token已过期 */ - if (error.getErrorCode() == WxCpErrorMsgEnum.CODE_42009.getCode()) { - // 强制设置wxCpTpConfigStorage它的suite access token过期了,这样在下一次请求里就会刷新suite access token + if (error.getErrorCode() == WxCpErrorMsgEnum.CODE_40014.getCode()) { + // 强制设置toekn过期了,这样在下一次请求里就会刷新access token this.configStorage.getProviderToken(); if (this.getWxCpCorpConfigStorage().autoRefreshToken()) { log.warn("即将重新获取新的access_token,错误代码:{},错误信息:{}", error.getErrorCode(), error.getErrorMsg()); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpDefaultConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpDefaultConfigImpl.java index 29181e0a3..493b22b2a 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpDefaultConfigImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpDefaultConfigImpl.java @@ -8,11 +8,7 @@ import java.io.File; import java.io.Serializable; -/** - * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化. - * - * @author someone - */ + public class WxCpCorpDefaultConfigImpl implements WxCpCorpConfigStorage, Serializable { private static final long serialVersionUID = 6678780920621872824L; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpRedisConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpRedisConfigImpl.java new file mode 100644 index 000000000..3a2717084 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpCorpRedisConfigImpl.java @@ -0,0 +1,86 @@ +package me.chanjar.weixin.cp.config.impl; + +import lombok.NonNull; +import me.chanjar.weixin.common.redis.RedissonWxRedisOps; +import me.chanjar.weixin.common.redis.WxRedisOps; +import me.chanjar.weixin.cp.bean.WxCpProviderToken; +import org.apache.commons.lang3.StringUtils; +import org.redisson.api.RedissonClient; + +import java.util.concurrent.TimeUnit; + + +public class WxCpCorpRedisConfigImpl extends WxCpCorpDefaultConfigImpl { + + protected final static String LOCK_KEY = "wechat_cp_corp_lock:"; + protected final static String CP_CORP_PROVIDER_ACCESS_TOKEN_KEY = "wechat_cp_corp_provider_access_token_key:"; + + + /** + * redis 存储的 key 的前缀,可为空 + */ + protected String keyPrefix; + protected String providerAccessTokenKey; + protected String lockKey; + + private final WxRedisOps redisOps; + + + public WxCpCorpRedisConfigImpl(WxRedisOps redisOps) { + this.redisOps = redisOps; + } + + + public WxCpCorpRedisConfigImpl(@NonNull RedissonClient redissonClient, String keyPrefix) { + this(new RedissonWxRedisOps(redissonClient), keyPrefix); + } + + public WxCpCorpRedisConfigImpl(@NonNull RedissonClient redissonClient) { + this(redissonClient, null); + } + + private WxCpCorpRedisConfigImpl(@NonNull WxRedisOps redisOps, String keyPrefix) { + this.redisOps = redisOps; + this.keyPrefix = keyPrefix; + } + + + @Override + public void setCorpId(String corpId) { + super.setCorpId(corpId); + String ukey = getCorpId(); + String prefix = StringUtils.isBlank(keyPrefix) ? "" : (StringUtils.endsWith(keyPrefix, ":") ? keyPrefix : (keyPrefix + ":")); + lockKey = prefix + LOCK_KEY.concat(ukey); + providerAccessTokenKey = prefix + CP_CORP_PROVIDER_ACCESS_TOKEN_KEY.concat(ukey); + } + + @Override + public String getProviderToken() { + + + return redisOps.getValue(this.providerAccessTokenKey); + } + + @Override + public boolean isProviderTokenExpired() { + Long expire = redisOps.getExpire(this.providerAccessTokenKey); + return expire == null || expire < 2; + } + + @Override + public void expireProviderToken() { + redisOps.expire(this.providerAccessTokenKey, 0, TimeUnit.SECONDS); + } + + @Override + public void updateProviderToken(WxCpProviderToken wxCpProviderToken) { + this.updateProviderToken(wxCpProviderToken.getProviderAccessToken(),wxCpProviderToken.getExpiresIn()); + } + + @Override + public void updateProviderToken(String providerAccessToken, int expiresIn) { + redisOps.setValue(this.providerAccessTokenKey, providerAccessToken, expiresIn, TimeUnit.SECONDS); + + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpRedisConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpRedisConfigImpl.java new file mode 100644 index 000000000..17318d10b --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpRedisConfigImpl.java @@ -0,0 +1,127 @@ +package me.chanjar.weixin.cp.config.impl; + +import lombok.NonNull; +import me.chanjar.weixin.common.bean.WxAccessToken; +import me.chanjar.weixin.common.redis.RedissonWxRedisOps; +import me.chanjar.weixin.common.redis.WxRedisOps; +import org.apache.commons.lang3.StringUtils; +import org.redisson.api.RedissonClient; + +import java.util.concurrent.TimeUnit; + +public class WxCpTpRedisConfigImpl extends WxCpTpDefaultConfigImpl { + + protected final static String LOCK_KEY = "wechat_cp_tp_lock:"; + protected final static String CP_SUITE_ACCESS_TOKEN_KEY = "wechat_cp_tp_suite_access_token_key:"; + protected final static String CP_SUITE_TICKET_KEY = "wechat_cp_tp_suite_ticket_key:"; + protected final static String CP_SUITE_JSAPI_TICKET_KEY = "wechat_cp_tp_suite_jsapi_ticket_key:"; + + /** + * redis 存储的 key 的前缀,可为空 + */ + protected String keyPrefix; + protected String suiteAccessTokenKey; + protected String suiteTicketKey; + protected String agentJsapiTicketKey; + protected String lockKey; + + private final WxRedisOps redisOps; + + + public WxCpTpRedisConfigImpl(WxRedisOps redisOps) { + this.redisOps = redisOps; + } + + + public WxCpTpRedisConfigImpl(@NonNull RedissonClient redissonClient, String keyPrefix) { + this(new RedissonWxRedisOps(redissonClient), keyPrefix); + } + + public WxCpTpRedisConfigImpl(@NonNull RedissonClient redissonClient) { + this(redissonClient, null); + } + + private WxCpTpRedisConfigImpl(@NonNull WxRedisOps redisOps, String keyPrefix) { + this.redisOps = redisOps; + this.keyPrefix = keyPrefix; + } + + @Override + public void setSuiteId(String suiteId) { + super.setSuiteId(suiteId); + String ukey = getCorpId().concat(":").concat(String.valueOf(suiteId)); + String prefix = StringUtils.isBlank(keyPrefix) ? "" : (StringUtils.endsWith(keyPrefix, ":") ? keyPrefix : (keyPrefix + ":")); + lockKey = prefix + LOCK_KEY.concat(ukey); + suiteAccessTokenKey = prefix + CP_SUITE_ACCESS_TOKEN_KEY.concat(ukey); + suiteTicketKey = prefix + CP_SUITE_TICKET_KEY.concat(ukey); + agentJsapiTicketKey = prefix + CP_SUITE_JSAPI_TICKET_KEY.concat(ukey); + } + + @Override + public String getSuiteAccessToken() { + return redisOps.getValue(this.suiteAccessTokenKey); + } + + @Override + public void setSuiteAccessToken(String suiteAccessToken) { + redisOps.setValue(this.suiteAccessTokenKey,suiteAccessToken,9000, TimeUnit.SECONDS); + } + + @Override + public boolean isSuiteAccessTokenExpired() { + Long expire = redisOps.getExpire(this.suiteAccessTokenKey); + return expire == null || expire < 2; + } + + @Override + public void expireSuiteAccessToken() { + redisOps.expire(this.suiteAccessTokenKey, 0, TimeUnit.SECONDS); + } + + @Override + public synchronized void updateSuiteAccessToken(WxAccessToken suiteAccessToken) { + redisOps.setValue(this.suiteAccessTokenKey, suiteAccessToken.getAccessToken(), suiteAccessToken.getExpiresIn(), TimeUnit.SECONDS); + } + + @Override + public synchronized void updateSuiteAccessToken(String suiteAccessToken, int expiresInSeconds) { + redisOps.setValue(this.suiteAccessTokenKey,suiteAccessToken,expiresInSeconds, TimeUnit.SECONDS); + } + + @Override + public String getSuiteTicket() { + return redisOps.getValue(this.suiteTicketKey); + } + + @Override + public void setSuiteTicket(String suiteTicket) { + redisOps.setValue(this.suiteTicketKey,suiteTicket,9000, TimeUnit.SECONDS); + } + + @Override + public long getSuiteTicketExpiresTime() { + Long expire = redisOps.getExpire(this.suiteTicketKey); + return expire; + } + + @Override + public void setSuiteTicketExpiresTime(long suiteTicketExpiresTime) { + redisOps.expire(this.suiteAccessTokenKey, 0, TimeUnit.SECONDS); + } + + @Override + public boolean isSuiteTicketExpired() { + Long expire = redisOps.getExpire(this.suiteTicketKey); + return expire == null || expire < 2; + } + + @Override + public synchronized void updateSuiteTicket(String suiteTicket, int expiresInSeconds) { + redisOps.setValue(this.suiteTicketKey,suiteTicket,expiresInSeconds, TimeUnit.SECONDS); + } + + @Override + public void expireSuiteTicket() { + redisOps.expire(this.suiteAccessTokenKey, 0, TimeUnit.SECONDS); + } +} From c3d52a7fbc0918b61571f48260f15aad32c4ea96 Mon Sep 17 00:00:00 2001 From: huangxiaoming Date: Mon, 21 Sep 2020 16:22:43 +0800 Subject: [PATCH 20/25] =?UTF-8?q?=20=E4=BC=98=E5=8C=96=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E9=83=A8=E5=88=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: huangxiaoming --- .../WxCpCorpServiceApacheHttpClientImpl.java | 1 + .../{api => tp/service}/WxCpCorpService.java | 2 +- .../weixin/cp/tp/service/WxCpTpService.java | 5 +---- .../impl/BaseWxCpCorpServiceImpl.java | 21 ++++--------------- .../service/impl/BaseWxCpTpServiceImpl.java | 5 ----- 5 files changed, 7 insertions(+), 27 deletions(-) rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/{api => tp/service}/WxCpCorpService.java (98%) rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/{api => tp/service}/impl/BaseWxCpCorpServiceImpl.java (89%) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpServiceApacheHttpClientImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpServiceApacheHttpClientImpl.java index 90401700e..49a6bbde0 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpServiceApacheHttpClientImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpCorpServiceApacheHttpClientImpl.java @@ -11,6 +11,7 @@ import me.chanjar.weixin.common.util.json.GsonParser; import me.chanjar.weixin.cp.config.WxCpCorpConfigStorage; import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; +import me.chanjar.weixin.cp.tp.service.impl.BaseWxCpCorpServiceImpl; import org.apache.http.Consts; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpCorpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpCorpService.java similarity index 98% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpCorpService.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpCorpService.java index 62dcf17cd..db20e9ab6 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpCorpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpCorpService.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.cp.api; +package me.chanjar.weixin.cp.tp.service; import me.chanjar.weixin.common.bean.WxAccessToken; import me.chanjar.weixin.common.error.WxErrorException; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpService.java index 0c2e99f8c..7c3eb804b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpService.java @@ -225,7 +225,6 @@ public interface WxCpTpService { RequestHttp getRequestHttp(); /** -<<<<<<< HEAD:weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTpService.java * 获取访问用户身份 * @param code * @return @@ -239,11 +238,9 @@ public interface WxCpTpService { */ WxCpTpUserDetail getuserdetail3rd(String userTicket) throws WxErrorException; -======= + /** * 获取WxSessionManager 对象 - * * @return WxSessionManager session manager */ WxSessionManager getSessionManager(); ->>>>>>> parnet/develop:weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/WxCpTpService.java } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpCorpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpCorpServiceImpl.java similarity index 89% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpCorpServiceImpl.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpCorpServiceImpl.java index 3817df673..fe76f7833 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpCorpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpCorpServiceImpl.java @@ -1,37 +1,24 @@ -package me.chanjar.weixin.cp.api.impl; +package me.chanjar.weixin.cp.tp.service.impl; -import com.google.common.base.Joiner; import com.google.gson.JsonObject; -import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import me.chanjar.weixin.common.bean.WxAccessToken; import me.chanjar.weixin.common.enums.WxType; import me.chanjar.weixin.common.error.WxCpErrorMsgEnum; import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.DataUtils; -import me.chanjar.weixin.common.util.crypto.SHA1; import me.chanjar.weixin.common.util.http.RequestExecutor; 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.common.util.json.GsonParser; -import me.chanjar.weixin.cp.api.WxCpCorpService; -import me.chanjar.weixin.cp.api.WxCpTpService; -import me.chanjar.weixin.cp.bean.*; +import me.chanjar.weixin.cp.tp.service.WxCpCorpService; +import me.chanjar.weixin.cp.bean.WxCpTpLoginInfo; import me.chanjar.weixin.cp.config.WxCpCorpConfigStorage; -import me.chanjar.weixin.cp.config.WxCpTpConfigStorage; -import me.chanjar.weixin.cp.constant.WxCpApiPathConsts; -import org.apache.commons.lang3.StringUtils; -import org.apache.http.client.methods.HttpPost; import java.io.File; import java.io.IOException; -import java.net.URLEncoder; -import java.util.HashMap; -import java.util.Map; -import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Tp.*; +import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Tp.GET_LOGIN_INFO; /** * diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImpl.java index 14ddff18a..f547daeae 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImpl.java @@ -279,7 +279,6 @@ public void setTmpDirFile(File tmpDirFile) { } @Override -<<<<<<< HEAD:weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java public WxCpTpUserInfo getuserinfo3rd(String code) throws WxErrorException{ JsonObject parms = new JsonObject(); @@ -302,11 +301,7 @@ public WxCpTpUserDetail getuserdetail3rd(String userTicket) throws WxErrorExcept return WxCpTpUserDetail.fromJson(result); } - -======= public WxSessionManager getSessionManager() { return this.sessionManager; } - ->>>>>>> parnet/develop:weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImpl.java } From d0422cc157ebfdc728c998c1a96e0ea46141746b Mon Sep 17 00:00:00 2001 From: huangxiaoming Date: Fri, 30 Oct 2020 20:08:17 +0800 Subject: [PATCH 21/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E7=AC=AC=E4=B8=89=E6=96=B9=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E5=92=8C=E9=83=A8=E5=88=86bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: huangxiaoming --- .../bean/external/WxCpContactWayResult.java | 3 + .../cp/bean/message/WxCpTpXmlMessage.java | 6 +- .../cp/bean/message/WxCpTpXmlOutMessage.java | 18 +++ .../weixin/cp/config/WxCpTpConfigStorage.java | 2 + .../config/impl/WxCpTpDefaultConfigImpl.java | 5 + .../weixin/cp/constant/WxCpConsts.java | 11 ++ .../weixin/cp/tp/constant/WxCpTpConsts.java | 52 ++++++++ .../cp/tp/message/WxCpTpMessageHandler.java | 11 +- .../tp/message/WxCpTpMessageInterceptor.java | 4 +- .../cp/tp/message/WxCpTpMessageMatcher.java | 4 +- .../cp/tp/message/WxCpTpMessageRouter.java | 79 ++++++++---- .../tp/message/WxCpTpMessageRouterRule.java | 117 ++++++++++++++---- .../service/impl/BaseWxCpTpServiceImpl.java | 14 +-- 13 files changed, 260 insertions(+), 66 deletions(-) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpTpXmlOutMessage.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/constant/WxCpTpConsts.java diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpContactWayResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpContactWayResult.java index 609673a19..6bb9c4139 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpContactWayResult.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpContactWayResult.java @@ -13,6 +13,9 @@ public class WxCpContactWayResult extends WxCpBaseResp { @SerializedName("config_id") private String configId; + @SerializedName("qr_code") + private String qrCode; + public static WxCpContactWayResult fromJson(String json) { return WxCpGsonBuilder.create().fromJson(json, WxCpContactWayResult.class); } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpTpXmlMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpTpXmlMessage.java index 6ee139538..e200e39c0 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpTpXmlMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpTpXmlMessage.java @@ -20,7 +20,7 @@ @XStreamAlias("xml") @Slf4j @Data -public class WxCpTpXmlMessage implements Serializable { +public class WxCpTpXmlMessage implements Serializable{ private static final long serialVersionUID = 6031833682211475786L; /** @@ -36,6 +36,10 @@ public class WxCpTpXmlMessage implements Serializable { @XStreamConverter(value = XStreamCDataConverter.class) protected String infoType; + @XStreamAlias("ChangeType") + @XStreamConverter(value = XStreamCDataConverter.class) + protected String changeType; + @XStreamAlias("TimeStamp") @XStreamConverter(value = XStreamCDataConverter.class) protected String timeStamp; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpTpXmlOutMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpTpXmlOutMessage.java new file mode 100644 index 000000000..72b48aa53 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpTpXmlOutMessage.java @@ -0,0 +1,18 @@ +package me.chanjar.weixin.cp.bean.message; + + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.Data; + +/** + * 被动回复消息. + * https://work.weixin.qq.com/api/doc#12975 + * + * @author huangxiaoming + */ +@XStreamAlias("xml") +@Data +public class WxCpTpXmlOutMessage extends WxCpXmlOutMessage{ + + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpTpConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpTpConfigStorage.java index 958309e0a..f10c6265b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpTpConfigStorage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpTpConfigStorage.java @@ -90,4 +90,6 @@ public interface WxCpTpConfigStorage { */ boolean autoRefreshToken(); + public String getOauth2redirectUri(); + } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpDefaultConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpDefaultConfigImpl.java index 908076e9a..2f67077c2 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpDefaultConfigImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpDefaultConfigImpl.java @@ -195,6 +195,11 @@ public void setOauth2redirectUri(String oauth2redirectUri) { this.oauth2redirectUri = oauth2redirectUri; } + @Override + public String getOauth2redirectUri() { + return this.oauth2redirectUri; + } + @Override public String getHttpProxyHost() { return this.httpProxyHost; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java index 6e8fbb468..8448727b4 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java @@ -139,6 +139,12 @@ public static class ExternalContactChangeType { * 新增外部联系人 */ public static final String ADD_EXTERNAL_CONTACT = "add_external_contact"; + + /** + * 编辑外部联系人事件 + */ + public static final String EDIT_EXTERNAL_CONTACT = "edit_external_contact"; + /** * 删除外部联系人 */ @@ -152,6 +158,11 @@ public static class ExternalContactChangeType { * 删除跟进成员事件 */ public static final String DEL_FOLLOW_USER = "del_follow_user"; + + /** + * 客户接替失败事件 + */ + public static final String TRANSFER_FAIL = "transfer_fail"; } /** diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/constant/WxCpTpConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/constant/WxCpTpConsts.java new file mode 100644 index 000000000..87d4edd9a --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/constant/WxCpTpConsts.java @@ -0,0 +1,52 @@ +package me.chanjar.weixin.cp.tp.constant; + +import lombok.experimental.UtilityClass; + +/** + *
+ * 企业微信第三方应用常量
+ * Created by xiaoming huang on 2020/10/16.
+ * 
+ * + * @author Binary Wang + */ +@UtilityClass +public class WxCpTpConsts { + /** + * 企业微信端推送过来的事件类型. + * 参考文档:https://work.weixin.qq.com/api/doc/10982 + */ + @UtilityClass + public static class InfoType { + /** + * 授权成功通知. + */ + public static final String CREATE_AUTH = "create_auth"; + + /** + * 变更授权通知 + */ + public static final String CHANGE_AUTH = "change_auth"; + + /** + * 取消授权通知 + */ + public static final String CANCEL_AUTH = "cancel_auth"; + + /** + * 成员事件通知 + */ + public static final String CHANGE_CONTACT = "change_contact"; + + /** + * 推送suite_ticket + */ + public static final String SUITE_TICKET = "suite_ticket"; + + /** + * 外部联系人事件 + */ + public static final String CHANGE_EXTERNAL_CONTACT = "change_external_contact"; + + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageHandler.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageHandler.java index 9ab718180..dd3646737 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageHandler.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageHandler.java @@ -2,7 +2,8 @@ import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; -import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpTpXmlOutMessage; import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; import me.chanjar.weixin.cp.tp.service.WxCpTpService; @@ -25,9 +26,9 @@ public interface WxCpTpMessageHandler { * @return xml格式的消息 ,如果在异步规则里处理的话,可以返回null * @throws WxErrorException the wx error exception */ - WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, - Map context, - WxCpTpService wxCpService, - WxSessionManager sessionManager) throws WxErrorException; + WxCpTpXmlOutMessage handle(WxCpTpXmlMessage wxMessage, + Map context, + WxCpTpService wxCpService, + WxSessionManager sessionManager) throws WxErrorException; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageInterceptor.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageInterceptor.java index fe5ceefa0..feac10dbb 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageInterceptor.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageInterceptor.java @@ -2,7 +2,7 @@ import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; -import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; import me.chanjar.weixin.cp.tp.service.WxCpTpService; import java.util.Map; @@ -24,7 +24,7 @@ public interface WxCpTpMessageInterceptor { * @return true代表OK ,false代表不OK * @throws WxErrorException the wx error exception */ - boolean intercept(WxCpXmlMessage wxMessage, + boolean intercept(WxCpTpXmlMessage wxMessage, Map context, WxCpTpService wxCpService, WxSessionManager sessionManager) throws WxErrorException; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageMatcher.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageMatcher.java index 8f7decf4b..882e330b8 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageMatcher.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageMatcher.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.cp.tp.message; -import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; /** * 消息匹配器,用在消息路由的时候 @@ -15,6 +15,6 @@ public interface WxCpTpMessageMatcher { * @param message the message * @return the boolean */ - boolean match(WxCpXmlMessage message); + boolean match(WxCpTpXmlMessage message); } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouter.java index 147f324db..a64e4c834 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouter.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouter.java @@ -9,6 +9,7 @@ import me.chanjar.weixin.common.session.InternalSessionManager; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.common.util.LogExceptionHandler; +import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; import me.chanjar.weixin.cp.message.WxCpMessageRouterRule; @@ -131,7 +132,7 @@ public WxCpTpMessageRouterRule rule() { /** * 处理微信消息. */ - public WxCpXmlOutMessage route(final WxCpXmlMessage wxMessage, final Map context) { + public WxCpXmlOutMessage route(final WxCpTpXmlMessage wxMessage, final Map context) { if (isMsgDuplicated(wxMessage)) { // 如果是重复消息,那么就不做处理 return null; @@ -165,7 +166,13 @@ public WxCpXmlOutMessage route(final WxCpXmlMessage wxMessage, final Map(2)); } - private boolean isMsgDuplicated(WxCpXmlMessage wxMessage) { + private boolean isMsgDuplicated(WxCpTpXmlMessage wxMessage) { StringBuilder messageId = new StringBuilder(); - if (wxMessage.getMsgId() == null) { - messageId.append(wxMessage.getCreateTime()) - .append("-").append(StringUtils.trimToEmpty(String.valueOf(wxMessage.getAgentId()))) - .append("-").append(wxMessage.getFromUserName()) - .append("-").append(StringUtils.trimToEmpty(wxMessage.getEventKey())) - .append("-").append(StringUtils.trimToEmpty(wxMessage.getEvent())); - } else { - messageId.append(wxMessage.getMsgId()) - .append("-").append(wxMessage.getCreateTime()) - .append("-").append(wxMessage.getFromUserName()); - } - if (StringUtils.isNotEmpty(wxMessage.getUserId())) { - messageId.append("-").append(wxMessage.getUserId()); + if(StringUtils.isNotEmpty(wxMessage.getAuthCorpId())){ + messageId.append("-").append(wxMessage.getAuthCorpId()); } - - if (StringUtils.isNotEmpty(wxMessage.getChangeType())) { + if(StringUtils.isNotEmpty(wxMessage.getSuiteId())){ + messageId.append("-").append(wxMessage.getSuiteId()); + } + if(StringUtils.isNotEmpty(wxMessage.getInfoType())){ + messageId.append("-").append(wxMessage.getInfoType()); + } + if(StringUtils.isNotEmpty(wxMessage.getChangeType())){ messageId.append("-").append(wxMessage.getChangeType()); } +// if(wxMessage.getAgentId() != null){ +// messageId.append("-").append(wxMessage.getAgentId()); +// } + +// if(StringUtils.isNotEmpty(wxMessage.getEvent())){ +// messageId.append("-").append(wxMessage.getEvent()); +// } + +// if(StringUtils.isNotEmpty(wxMessage.getFromUserName())){ +// messageId.append("-").append(wxMessage.getFromUserName()); +// } + +// if (StringUtils.isNotEmpty(wxMessage.getUserId())) { +// messageId.append("-").append(wxMessage.getUserId()); +// } +// +// if (wxMessage.getCreateTime() != null) { +// messageId.append("-").append(wxMessage.getCreateTime()); +// } + return this.messageDuplicateChecker.isDuplicate(messageId.toString()); } /** - * 对session的访问结束. + *对session的访问结束. */ - private void sessionEndAccess(WxCpXmlMessage wxMessage) { - InternalSession session = ((InternalSessionManager) this.sessionManager).findSession(wxMessage.getFromUserName()); + private void sessionEndAccess(WxCpTpXmlMessage wxMessage) { + InternalSession session = ((InternalSessionManager) this.sessionManager).findSession(wxMessage.getTimeStamp() + .concat(StringUtils.trimToEmpty(wxMessage.getAuthCorpId())) + .concat(wxMessage.getSuiteId()) + .concat(wxMessage.getInfoType()) + .concat(StringUtils.trimToEmpty(wxMessage.getChangeType())) + //.concat(StringUtils.trimToEmpty(wxMessage.getFromUserName())) + ); if (session != null) { session.endAccess(); } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouterRule.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouterRule.java index 8494978e2..426991d5e 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouterRule.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouterRule.java @@ -4,9 +4,12 @@ import me.chanjar.weixin.common.api.WxErrorExceptionHandler; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpTpXmlOutMessage; import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; import me.chanjar.weixin.cp.message.WxCpMessageMatcher; +import me.chanjar.weixin.cp.message.WxCpMessageRouterRule; import me.chanjar.weixin.cp.tp.service.WxCpTpService; import org.apache.commons.lang3.StringUtils; @@ -26,6 +29,14 @@ public class WxCpTpMessageRouterRule { private String fromUser; + private String authCorpId; + + private String suiteId; + + private String infoType; + + private String changeType; + private String msgType; private String event; @@ -38,11 +49,12 @@ public class WxCpTpMessageRouterRule { private String rContent; - private WxCpMessageMatcher matcher; + private Integer agentId; + + private WxCpTpMessageMatcher matcher; private boolean reEnter = false; - private Integer agentId; private List handlers = new ArrayList<>(); @@ -57,6 +69,7 @@ protected WxCpTpMessageRouterRule(WxCpTpMessageRouter routerBuilder) { this.routerBuilder = routerBuilder; } + /** * 设置是否异步执行,默认是true * @@ -68,6 +81,53 @@ public WxCpTpMessageRouterRule async(boolean async) { return this; } + + + /** + * 如果authCorpId匹配 + * + * @param authCorpId the authCorpId id + * @return the wx cp message router rule + */ + public WxCpTpMessageRouterRule authCorpId(String authCorpId) { + this.authCorpId = authCorpId; + return this; + } + + + /** + * 如果suiteId匹配 + * + * @param suiteId the suiteId id + * @return the wx cp message router rule + */ + public WxCpTpMessageRouterRule suiteId(String suiteId) { + this.suiteId = suiteId; + return this; + } + + /** + * 如果infoType匹配 + * + * @param infoType the msg infoType + * @return the wx cp message router rule + */ + public WxCpTpMessageRouterRule infoType(String infoType) { + this.infoType = infoType; + return this; + } + + /** + * 如果changeType匹配 + * + * @param changeType the msg changeType + * @return the wx cp message router rule + */ + public WxCpTpMessageRouterRule changeType(String changeType) { + this.changeType = changeType; + return this; + } + /** * 如果agentId匹配 * @@ -79,6 +139,7 @@ public WxCpTpMessageRouterRule agentId(Integer agentId) { return this; } + /** * 如果msgType等于某值 * @@ -162,7 +223,7 @@ public WxCpTpMessageRouterRule fromUser(String fromUser) { * @param matcher the matcher * @return the wx cp message router rule */ - public WxCpTpMessageRouterRule matcher(WxCpMessageMatcher matcher) { + public WxCpTpMessageRouterRule matcher(WxCpTpMessageMatcher matcher) { this.matcher = matcher; return this; } @@ -243,26 +304,34 @@ public WxCpTpMessageRouter next() { * @param wxMessage the wx message * @return the boolean */ - protected boolean test(WxCpXmlMessage wxMessage) { + protected boolean test(WxCpTpXmlMessage wxMessage) { return - (this.fromUser == null || this.fromUser.equals(wxMessage.getFromUserName())) - && - (this.agentId == null || this.agentId.equals(wxMessage.getAgentId())) - && - (this.msgType == null || this.msgType.equalsIgnoreCase(wxMessage.getMsgType())) - && - (this.event == null || this.event.equalsIgnoreCase(wxMessage.getEvent())) - && - (this.eventKey == null || this.eventKey.equalsIgnoreCase(wxMessage.getEventKey())) + (this.authCorpId == null || this.authCorpId.equals(wxMessage.getAuthCorpId())) && - (this.eventKeyRegex == null || Pattern.matches(this.eventKeyRegex, StringUtils.trimToEmpty(wxMessage.getEventKey()))) + (this.suiteId == null || this.suiteId.equals(wxMessage.getSuiteId())) && - (this.content == null || this.content.equals(StringUtils.trimToNull(wxMessage.getContent()))) + (this.infoType == null || this.infoType.equalsIgnoreCase(wxMessage.getInfoType())) && - (this.rContent == null || Pattern.matches(this.rContent, StringUtils.trimToEmpty(wxMessage.getContent()))) + (this.changeType == null || this.changeType.equalsIgnoreCase(wxMessage.getChangeType()) + // && + // (this.fromUser == null || this.fromUser.equals(wxMessage.getFromUserName())) + // && + // (this.agentId == null || this.agentId.equals(wxMessage.getAgentId())) + // && + // (this.msgType == null || this.msgType.equalsIgnoreCase(wxMessage.getMsgType())) + //&& + //(this.event == null || this.event.equalsIgnoreCase(wxMessage.getEvent())) + //&& + //(this.eventKey == null || this.eventKey.equalsIgnoreCase(wxMessage.getEventKey())) + //&& + //(this.eventKeyRegex == null || Pattern.matches(this.eventKeyRegex, StringUtils.trimToEmpty(wxMessage.getEventKey()))) + //&& + //(this.content == null || this.content.equals(StringUtils.trimToNull(wxMessage.getContent()))) + //&& + //(this.rContent == null || Pattern.matches(this.rContent, StringUtils.trimToEmpty(wxMessage.getContent()))) && (this.matcher == null || this.matcher.match(wxMessage)) - ; + ); } /** @@ -273,13 +342,13 @@ protected boolean test(WxCpXmlMessage wxMessage) { * @param wxCpService the wx cp service * @param sessionManager the session manager * @param exceptionHandler the exception handler - * @return true 代表继续执行别的router,false 代表停止执行别的router + * @return true 代表继续执行别的router,false 代表停止执别的router */ - protected WxCpXmlOutMessage service(WxCpXmlMessage wxMessage, - Map context, - WxCpTpService wxCpService, - WxSessionManager sessionManager, - WxErrorExceptionHandler exceptionHandler) { + protected WxCpTpXmlOutMessage service(WxCpTpXmlMessage wxMessage, + Map context, + WxCpTpService wxCpService, + WxSessionManager sessionManager, + WxErrorExceptionHandler exceptionHandler) { if (context == null) { context = new HashMap<>(2); @@ -294,7 +363,7 @@ protected WxCpXmlOutMessage service(WxCpXmlMessage wxMessage, } // 交给handler处理 - WxCpXmlOutMessage res = null; + WxCpTpXmlOutMessage res = null; for (WxCpTpMessageHandler handler : this.handlers) { // 返回最后handler的结果 res = handler.handle(wxMessage, context, wxCpService, sessionManager); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImpl.java index f547daeae..081a8f7d0 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/service/impl/BaseWxCpTpServiceImpl.java @@ -280,24 +280,20 @@ public void setTmpDirFile(File tmpDirFile) { @Override public WxCpTpUserInfo getuserinfo3rd(String code) throws WxErrorException{ - - JsonObject parms = new JsonObject(); - parms.addProperty("code", code); - + log.info("parm:{}",code); String url = configStorage.getApiUrl(GET_USERINFO3RD); - if (StringUtils.isNotBlank(code)) { - url += "?code=" + code; - } - String result = get(url,null); + String result = get(url+"?code="+code,null); + log.info("result:{}",result); return WxCpTpUserInfo.fromJson(result); } @Override public WxCpTpUserDetail getuserdetail3rd(String userTicket) throws WxErrorException{ - + log.info("parm:{}",userTicket); JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("user_ticket", userTicket); String result = post(configStorage.getApiUrl(GET_USERDETAIL3RD), jsonObject.toString()); + log.info("parm:{}",result); return WxCpTpUserDetail.fromJson(result); } From 33724f9ede1e0b4913070b372dcf1a7ab0f857b5 Mon Sep 17 00:00:00 2001 From: huangxiaoming Date: Mon, 2 Nov 2020 10:31:58 +0800 Subject: [PATCH 22/25] =?UTF-8?q?BUG=20=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: huangxiaoming --- .../bean/external/WxCpContactWayResult.java | 7 -- .../cp/bean/message/WxCpTpXmlOutMessage.java | 18 ----- .../cp/tp/message/WxCpTpMessageHandler.java | 9 ++- .../cp/tp/message/WxCpTpMessageRouter.java | 1 - .../tp/message/WxCpTpMessageRouterRule.java | 10 +-- .../bean/message/WxMpXmlOutDeviceMessage.java | 71 +++++++++---------- 6 files changed, 41 insertions(+), 75 deletions(-) delete mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpTpXmlOutMessage.java diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpContactWayResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpContactWayResult.java index 593932235..6bb9c4139 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpContactWayResult.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/external/WxCpContactWayResult.java @@ -12,17 +12,10 @@ public class WxCpContactWayResult extends WxCpBaseResp { @SerializedName("config_id") private String configId; -<<<<<<< HEAD @SerializedName("qr_code") private String qrCode; -======= - - @SerializedName("qr_code") - private String qrCode; - ->>>>>>> parnet/develop public static WxCpContactWayResult fromJson(String json) { return WxCpGsonBuilder.create().fromJson(json, WxCpContactWayResult.class); } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpTpXmlOutMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpTpXmlOutMessage.java deleted file mode 100644 index 72b48aa53..000000000 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/message/WxCpTpXmlOutMessage.java +++ /dev/null @@ -1,18 +0,0 @@ -package me.chanjar.weixin.cp.bean.message; - - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import lombok.Data; - -/** - * 被动回复消息. - * https://work.weixin.qq.com/api/doc#12975 - * - * @author huangxiaoming - */ -@XStreamAlias("xml") -@Data -public class WxCpTpXmlOutMessage extends WxCpXmlOutMessage{ - - -} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageHandler.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageHandler.java index dd3646737..639a74335 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageHandler.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageHandler.java @@ -3,7 +3,6 @@ import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; -import me.chanjar.weixin.cp.bean.message.WxCpTpXmlOutMessage; import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; import me.chanjar.weixin.cp.tp.service.WxCpTpService; @@ -26,9 +25,9 @@ public interface WxCpTpMessageHandler { * @return xml格式的消息 ,如果在异步规则里处理的话,可以返回null * @throws WxErrorException the wx error exception */ - WxCpTpXmlOutMessage handle(WxCpTpXmlMessage wxMessage, - Map context, - WxCpTpService wxCpService, - WxSessionManager sessionManager) throws WxErrorException; + WxCpXmlOutMessage handle(WxCpTpXmlMessage wxMessage, + Map context, + WxCpTpService wxCpService, + WxSessionManager sessionManager) throws WxErrorException; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouter.java index a64e4c834..4e8c22a14 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouter.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouter.java @@ -10,7 +10,6 @@ import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.common.util.LogExceptionHandler; import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; -import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; import me.chanjar.weixin.cp.message.WxCpMessageRouterRule; import me.chanjar.weixin.cp.tp.service.WxCpTpService; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouterRule.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouterRule.java index 426991d5e..df2a4dff5 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouterRule.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouterRule.java @@ -5,16 +5,10 @@ import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; -import me.chanjar.weixin.cp.bean.message.WxCpTpXmlOutMessage; -import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; -import me.chanjar.weixin.cp.message.WxCpMessageMatcher; -import me.chanjar.weixin.cp.message.WxCpMessageRouterRule; import me.chanjar.weixin.cp.tp.service.WxCpTpService; -import org.apache.commons.lang3.StringUtils; import java.util.*; -import java.util.regex.Pattern; /** * The type Wx cp message router rule. @@ -344,7 +338,7 @@ protected boolean test(WxCpTpXmlMessage wxMessage) { * @param exceptionHandler the exception handler * @return true 代表继续执行别的router,false 代表停止执别的router */ - protected WxCpTpXmlOutMessage service(WxCpTpXmlMessage wxMessage, + protected WxCpXmlOutMessage service(WxCpTpXmlMessage wxMessage, Map context, WxCpTpService wxCpService, WxSessionManager sessionManager, @@ -363,7 +357,7 @@ protected WxCpTpXmlOutMessage service(WxCpTpXmlMessage wxMessage, } // 交给handler处理 - WxCpTpXmlOutMessage res = null; + WxCpXmlOutMessage res = null; for (WxCpTpMessageHandler handler : this.handlers) { // 返回最后handler的结果 res = handler.handle(wxMessage, context, wxCpService, sessionManager); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutDeviceMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutDeviceMessage.java index b32935a10..86b162526 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutDeviceMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutDeviceMessage.java @@ -1,36 +1,35 @@ -package me.chanjar.weixin.mp.bean.message; - -import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.annotations.XStreamConverter; - -import lombok.Data; -import lombok.EqualsAndHashCode; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; - -@XStreamAlias("xml") -@Data -@EqualsAndHashCode(callSuper = true) -public class WxMpXmlOutDeviceMessage extends WxMpXmlOutMessage { - private static final long serialVersionUID = -3093843149649157587L; - - @XStreamAlias("DeviceType") - @XStreamConverter(value = XStreamCDataConverter.class) - private String deviceType; - - @XStreamAlias("DeviceID") - @XStreamConverter(value = XStreamCDataConverter.class) - private String deviceId; - - @XStreamAlias("Content") - @XStreamConverter(value = XStreamCDataConverter.class) - private String content; - - @XStreamAlias("SessionID") - @XStreamConverter(value = XStreamCDataConverter.class) - private String sessionId; - - public WxMpXmlOutDeviceMessage() { - this.msgType = WxConsts.XmlMsgType.DEVICE_TEXT; - } -} +package me.chanjar.weixin.mp.bean.message; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; +import lombok.Data; +import lombok.EqualsAndHashCode; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; + +@XStreamAlias("xml") +@Data +@EqualsAndHashCode(callSuper = true) +public class WxMpXmlOutDeviceMessage extends WxMpXmlOutMessage { + private static final long serialVersionUID = -3093843149649157587L; + + @XStreamAlias("DeviceType") + @XStreamConverter(value = XStreamCDataConverter.class) + private String deviceType; + + @XStreamAlias("DeviceID") + @XStreamConverter(value = XStreamCDataConverter.class) + private String deviceId; + + @XStreamAlias("Content") + @XStreamConverter(value = XStreamCDataConverter.class) + private String content; + + @XStreamAlias("SessionID") + @XStreamConverter(value = XStreamCDataConverter.class) + private String sessionId; + + public WxMpXmlOutDeviceMessage() { + this.msgType = WxConsts.XmlMsgType.DEVICE_TEXT; + } +} From 4e41a63590236a05a6035fc23e3cd2d73c6c8a9a Mon Sep 17 00:00:00 2001 From: huangxiaoming Date: Mon, 2 Nov 2020 11:27:57 +0800 Subject: [PATCH 23/25] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=89=B9=E9=87=8F=E8=8E=B7=E5=8F=96=E5=AE=A2?= =?UTF-8?q?=E6=88=B7=E8=AF=A6=E6=83=85=20follow=5Finfo=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=20tag=5Fid=E8=BF=94=E5=9B=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: huangxiaoming --- .../WxCpUserExternalContactBatchInfo.java | 5 + .../cp/tp/message/WxCpTpMessageHandler.java | 3 - .../tp/message/WxCpTpMessageInterceptor.java | 3 - .../cp/tp/message/WxCpTpMessageMatcher.java | 4 +- .../cp/tp/message/WxCpTpMessageRouter.java | 70 +----- .../tp/message/WxCpTpMessageRouterRule.java | 219 +----------------- 6 files changed, 13 insertions(+), 291 deletions(-) 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 index 5275dc9dd..10499dc6d 100644 --- 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 @@ -136,6 +136,10 @@ public static class FollowedUser { private String remarkCompany; @SerializedName("remark_mobiles") private String[] remarkMobiles; + + @SerializedName("tag_id") + private String[] tagIds; + private Tag[] tags; @SerializedName("remark_corp_name") private String remarkCorpName; @@ -153,6 +157,7 @@ public static WxCpUserExternalContactBatchInfo fromJson(String json) { @Setter @Getter public static class Tag { + @SerializedName("group_name") private String groupName; @SerializedName("tag_name") diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageHandler.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageHandler.java index d066bb34e..eea6bd966 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageHandler.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageHandler.java @@ -3,10 +3,7 @@ import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; -<<<<<<< HEAD -======= import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; ->>>>>>> parnet/develop import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; import me.chanjar.weixin.cp.tp.service.WxCpTpService; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageInterceptor.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageInterceptor.java index 800ab1fbd..62975951b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageInterceptor.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageInterceptor.java @@ -3,10 +3,7 @@ import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; -<<<<<<< HEAD -======= import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; ->>>>>>> parnet/develop import me.chanjar.weixin.cp.tp.service.WxCpTpService; import java.util.Map; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageMatcher.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageMatcher.java index 882e330b8..8f7decf4b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageMatcher.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageMatcher.java @@ -1,6 +1,6 @@ package me.chanjar.weixin.cp.tp.message; -import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; /** * 消息匹配器,用在消息路由的时候 @@ -15,6 +15,6 @@ public interface WxCpTpMessageMatcher { * @param message the message * @return the boolean */ - boolean match(WxCpTpXmlMessage message); + boolean match(WxCpXmlMessage message); } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouter.java index d46512410..ad9d0ff0a 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouter.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouter.java @@ -10,10 +10,7 @@ import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.common.util.LogExceptionHandler; import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; -<<<<<<< HEAD -======= import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; ->>>>>>> parnet/develop import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; import me.chanjar.weixin.cp.message.WxCpMessageRouterRule; import me.chanjar.weixin.cp.tp.service.WxCpTpService; @@ -169,17 +166,7 @@ public WxCpXmlOutMessage route(final WxCpTpXmlMessage wxMessage, final Map>>>>>> parnet/develop sessionEndAccess(wxMessage); } } @@ -189,17 +176,7 @@ public WxCpXmlOutMessage route(final WxCpTpXmlMessage wxMessage, final Map>>>>>> parnet/develop // 异步操作结束,session访问结束 sessionEndAccess(wxMessage); } catch (InterruptedException e) { @@ -223,20 +200,6 @@ public WxCpXmlOutMessage route(final WxCpTpXmlMessage wxMessage) { private boolean isMsgDuplicated(WxCpTpXmlMessage wxMessage) { StringBuilder messageId = new StringBuilder(); -<<<<<<< HEAD - - if(StringUtils.isNotEmpty(wxMessage.getAuthCorpId())){ - messageId.append("-").append(wxMessage.getAuthCorpId()); - } - if(StringUtils.isNotEmpty(wxMessage.getSuiteId())){ - messageId.append("-").append(wxMessage.getSuiteId()); - } - if(StringUtils.isNotEmpty(wxMessage.getInfoType())){ - messageId.append("-").append(wxMessage.getInfoType()); - } - if(StringUtils.isNotEmpty(wxMessage.getChangeType())){ - messageId.append("-").append(wxMessage.getChangeType()); -======= if (StringUtils.isNotEmpty(wxMessage.getSuiteId())) { messageId.append("-").append(wxMessage.getSuiteId()); } @@ -247,47 +210,16 @@ private boolean isMsgDuplicated(WxCpTpXmlMessage wxMessage) { if (StringUtils.isNotEmpty(wxMessage.getTimeStamp())) { messageId.append("-").append(wxMessage.getTimeStamp()); ->>>>>>> parnet/develop } -// if(wxMessage.getAgentId() != null){ -// messageId.append("-").append(wxMessage.getAgentId()); -// } - -// if(StringUtils.isNotEmpty(wxMessage.getEvent())){ -// messageId.append("-").append(wxMessage.getEvent()); -// } - -// if(StringUtils.isNotEmpty(wxMessage.getFromUserName())){ -// messageId.append("-").append(wxMessage.getFromUserName()); -// } - -// if (StringUtils.isNotEmpty(wxMessage.getUserId())) { -// messageId.append("-").append(wxMessage.getUserId()); -// } -// -// if (wxMessage.getCreateTime() != null) { -// messageId.append("-").append(wxMessage.getCreateTime()); -// } - return this.messageDuplicateChecker.isDuplicate(messageId.toString()); } /** - *对session的访问结束. + * 对session的访问结束. */ private void sessionEndAccess(WxCpTpXmlMessage wxMessage) { -<<<<<<< HEAD - InternalSession session = ((InternalSessionManager) this.sessionManager).findSession(wxMessage.getTimeStamp() - .concat(StringUtils.trimToEmpty(wxMessage.getAuthCorpId())) - .concat(wxMessage.getSuiteId()) - .concat(wxMessage.getInfoType()) - .concat(StringUtils.trimToEmpty(wxMessage.getChangeType())) - //.concat(StringUtils.trimToEmpty(wxMessage.getFromUserName())) - ); -======= InternalSession session = ((InternalSessionManager) this.sessionManager).findSession(wxMessage.getSuiteId()); ->>>>>>> parnet/develop if (session != null) { session.endAccess(); } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouterRule.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouterRule.java index ce1fea681..fa21a1451 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouterRule.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouterRule.java @@ -5,14 +5,14 @@ import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; -<<<<<<< HEAD -======= import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; ->>>>>>> parnet/develop import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import me.chanjar.weixin.cp.message.WxCpMessageMatcher; import me.chanjar.weixin.cp.tp.service.WxCpTpService; +import org.apache.commons.lang3.StringUtils; import java.util.*; +import java.util.regex.Pattern; /** * The type Wx cp message router rule. @@ -25,42 +25,10 @@ public class WxCpTpMessageRouterRule { private boolean async = true; -<<<<<<< HEAD - private String fromUser; - - private String authCorpId; - - private String suiteId; - - private String infoType; - - private String changeType; - - private String msgType; - - private String event; - - private String eventKey; - - private String eventKeyRegex; - - private String content; - - private String rContent; - - private Integer agentId; - - private WxCpTpMessageMatcher matcher; - - private boolean reEnter = false; - - -======= private WxCpMessageMatcher matcher; private boolean reEnter = false; ->>>>>>> parnet/develop private List handlers = new ArrayList<>(); private List interceptors = new ArrayList<>(); @@ -78,7 +46,6 @@ protected WxCpTpMessageRouterRule(WxCpTpMessageRouter routerBuilder) { this.routerBuilder = routerBuilder; } - /** * 设置是否异步执行,默认是true * @@ -90,152 +57,13 @@ public WxCpTpMessageRouterRule async(boolean async) { return this; } - - - /** - * 如果authCorpId匹配 - * - * @param authCorpId the authCorpId id - * @return the wx cp message router rule - */ - public WxCpTpMessageRouterRule authCorpId(String authCorpId) { - this.authCorpId = authCorpId; - return this; - } - - - /** - * 如果suiteId匹配 - * - * @param suiteId the suiteId id - * @return the wx cp message router rule - */ - public WxCpTpMessageRouterRule suiteId(String suiteId) { - this.suiteId = suiteId; - return this; - } - - /** - * 如果infoType匹配 - * - * @param infoType the msg infoType - * @return the wx cp message router rule - */ - public WxCpTpMessageRouterRule infoType(String infoType) { - this.infoType = infoType; - return this; - } - - /** - * 如果changeType匹配 - * - * @param changeType the msg changeType - * @return the wx cp message router rule - */ - public WxCpTpMessageRouterRule changeType(String changeType) { - this.changeType = changeType; - return this; - } - - /** -<<<<<<< HEAD - * 如果agentId匹配 - * - * @param agentId the agent id - * @return the wx cp message router rule - */ - public WxCpTpMessageRouterRule agentId(Integer agentId) { - this.agentId = agentId; - return this; - } - - - /** - * 如果msgType等于某值 - * - * @param msgType the msg type - * @return the wx cp message router rule - */ - public WxCpTpMessageRouterRule msgType(String msgType) { - this.msgType = msgType; - return this; - } - - /** - * 如果event等于某值 - * - * @param event the event - * @return the wx cp message router rule - */ - public WxCpTpMessageRouterRule event(String event) { - this.event = event; - return this; - } - - /** - * 如果eventKey等于某值 - * - * @param eventKey the event key - * @return the wx cp message router rule - */ - public WxCpTpMessageRouterRule eventKey(String eventKey) { - this.eventKey = eventKey; - return this; - } - - /** - * 如果eventKey匹配该正则表达式 - * - * @param regex the regex - * @return the wx cp message router rule - */ - public WxCpTpMessageRouterRule eventKeyRegex(String regex) { - this.eventKeyRegex = regex; - return this; - } - - /** - * 如果content等于某值 - * - * @param content the content - * @return the wx cp message router rule - */ - public WxCpTpMessageRouterRule content(String content) { - this.content = content; - return this; - } - - /** - * 如果content匹配该正则表达式 - * - * @param regex the regex - * @return the wx cp message router rule - */ - public WxCpTpMessageRouterRule rContent(String regex) { - this.rContent = regex; - return this; - } - - /** - * 如果fromUser等于某值 - * - * @param fromUser the from user - * @return the wx cp message router rule - */ - public WxCpTpMessageRouterRule fromUser(String fromUser) { - this.fromUser = fromUser; - return this; - } - /** -======= ->>>>>>> parnet/develop * 如果消息匹配某个matcher,用在用户需要自定义更复杂的匹配规则的时候 * * @param matcher the matcher * @return the wx cp message router rule */ - public WxCpTpMessageRouterRule matcher(WxCpTpMessageMatcher matcher) { + public WxCpTpMessageRouterRule matcher(WxCpMessageMatcher matcher) { this.matcher = matcher; return this; } @@ -318,34 +146,6 @@ public WxCpTpMessageRouter next() { */ protected boolean test(WxCpTpXmlMessage wxMessage) { return -<<<<<<< HEAD - (this.authCorpId == null || this.authCorpId.equals(wxMessage.getAuthCorpId())) - && - (this.suiteId == null || this.suiteId.equals(wxMessage.getSuiteId())) - && - (this.infoType == null || this.infoType.equalsIgnoreCase(wxMessage.getInfoType())) - && - (this.changeType == null || this.changeType.equalsIgnoreCase(wxMessage.getChangeType()) - // && - // (this.fromUser == null || this.fromUser.equals(wxMessage.getFromUserName())) - // && - // (this.agentId == null || this.agentId.equals(wxMessage.getAgentId())) - // && - // (this.msgType == null || this.msgType.equalsIgnoreCase(wxMessage.getMsgType())) - //&& - //(this.event == null || this.event.equalsIgnoreCase(wxMessage.getEvent())) - //&& - //(this.eventKey == null || this.eventKey.equalsIgnoreCase(wxMessage.getEventKey())) - //&& - //(this.eventKeyRegex == null || Pattern.matches(this.eventKeyRegex, StringUtils.trimToEmpty(wxMessage.getEventKey()))) - //&& - //(this.content == null || this.content.equals(StringUtils.trimToNull(wxMessage.getContent()))) - //&& - //(this.rContent == null || Pattern.matches(this.rContent, StringUtils.trimToEmpty(wxMessage.getContent()))) - && - (this.matcher == null || this.matcher.match(wxMessage)) - ); -======= (this.suiteId == null || this.suiteId.equals(wxMessage.getSuiteId())) && (this.infoType == null || this.infoType.equals(wxMessage.getInfoType())) @@ -354,7 +154,6 @@ protected boolean test(WxCpTpXmlMessage wxMessage) { && (this.authCode == null || this.authCode.equalsIgnoreCase(wxMessage.getAuthCode())) ; ->>>>>>> parnet/develop } /** @@ -365,21 +164,13 @@ protected boolean test(WxCpTpXmlMessage wxMessage) { * @param wxCpService the wx cp service * @param sessionManager the session manager * @param exceptionHandler the exception handler - * @return true 代表继续执行别的router,false 代表停止执别的router + * @return true 代表继续执行别的router,false 代表停止执行别的router */ protected WxCpXmlOutMessage service(WxCpTpXmlMessage wxMessage, -<<<<<<< HEAD - Map context, - WxCpTpService wxCpService, - WxSessionManager sessionManager, - WxErrorExceptionHandler exceptionHandler) { - -======= Map context, WxCpTpService wxCpService, WxSessionManager sessionManager, WxErrorExceptionHandler exceptionHandler) { ->>>>>>> parnet/develop if (context == null) { context = new HashMap<>(2); } From d6f913e1c50a0411ea72eeae9f169d55bed78506 Mon Sep 17 00:00:00 2001 From: huangxiaoming Date: Mon, 2 Nov 2020 11:45:53 +0800 Subject: [PATCH 24/25] =?UTF-8?q?=E6=B7=BB=E5=8A=A0CP=20=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E5=8C=B9=E9=85=8DinfoType?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: huangxiaoming --- .../weixin/cp/tp/message/WxCpTpMessageRouterRule.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouterRule.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouterRule.java index fa21a1451..e749191c8 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouterRule.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/tp/message/WxCpTpMessageRouterRule.java @@ -68,6 +68,15 @@ public WxCpTpMessageRouterRule matcher(WxCpMessageMatcher matcher) { return this; } + /** + * 匹配 Message infoType + * @param infoType + */ + public WxCpTpMessageRouterRule infoType(String infoType) { + this.infoType = infoType; + return this; + } + /** * 设置微信消息拦截器 * From 2a0c78f6b6c7fc57f2a43950dd1e6b7cf432eccb Mon Sep 17 00:00:00 2001 From: huangxiaoming Date: Mon, 2 Nov 2020 14:16:01 +0800 Subject: [PATCH 25/25] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E7=AC=AC=E4=B8=89=E6=96=B9=E5=BA=94=E7=94=A8?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: huangxiaoming --- spring-boot-starters/pom.xml | 1 + .../wx-java-cp-spring-boot-starter/README.md | 39 +++++ .../wx-java-cp-spring-boot-starter/pom.xml | 54 +++++++ .../wxjava/cp/builder/AbstractBuilder.java | 16 ++ .../wxjava/cp/builder/ImageBuilder.java | 25 +++ .../wxjava/cp/builder/TextBuilder.java | 23 +++ .../wxjava/cp/config/WxCpConfiguration.java | 128 ++++++++++++++++ .../wxjava/cp/config/WxCpTpConfiguration.java | 143 ++++++++++++++++++ .../wxjava/cp/handler/AbstractHandler.java | 14 ++ .../wxjava/cp/handler/AbstractTpHandler.java | 14 ++ .../cp/handler/ContactChangeHandler.java | 30 ++++ .../wxjava/cp/handler/EnterAgentHandler.java | 31 ++++ .../wxjava/cp/handler/LocationHandler.java | 44 ++++++ .../starter/wxjava/cp/handler/LogHandler.java | 26 ++++ .../wxjava/cp/handler/MenuHandler.java | 36 +++++ .../starter/wxjava/cp/handler/MsgHandler.java | 39 +++++ .../wxjava/cp/handler/NullHandler.java | 25 +++ .../wxjava/cp/handler/ScanHandler.java | 9 ++ .../wxjava/cp/handler/SubscribeHandler.java | 63 ++++++++ .../wxjava/cp/handler/UnsubscribeHandler.java | 28 ++++ .../handler/tp/TpExternalContactHandler.java | 27 ++++ .../wxjava/cp/handler/tp/TpLogHandler.java | 27 ++++ .../wxjava/cp/handler/tp/TpNullHandler.java | 26 ++++ .../handler/tp/TpSuiteCancelAuthHandler.java | 30 ++++ .../handler/tp/TpSuiteChangeAuthHandler.java | 36 +++++ .../handler/tp/TpSuiteCreateAuthHandler.java | 33 ++++ .../wxjava/cp/handler/tp/TpUserHandler.java | 29 ++++ .../wxjava/cp/properties/WxCpProperties.java | 49 ++++++ .../cp/properties/WxCpTpProperties.java | 102 +++++++++++++ .../main/resources/META-INF/spring.factories | 1 + 30 files changed, 1148 insertions(+) create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/README.md create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/pom.xml create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/builder/AbstractBuilder.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/builder/ImageBuilder.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/builder/TextBuilder.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/config/WxCpConfiguration.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/config/WxCpTpConfiguration.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/AbstractHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/AbstractTpHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/ContactChangeHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/EnterAgentHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/LocationHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/LogHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/MenuHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/MsgHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/NullHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/ScanHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/SubscribeHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/UnsubscribeHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpExternalContactHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpLogHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpNullHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpSuiteCancelAuthHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpSuiteChangeAuthHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpSuiteCreateAuthHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpUserHandler.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpProperties.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpTpProperties.java create mode 100644 spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/resources/META-INF/spring.factories diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml index 013e127e5..dfe9501c3 100644 --- a/spring-boot-starters/pom.xml +++ b/spring-boot-starters/pom.xml @@ -21,6 +21,7 @@ wx-java-miniapp-spring-boot-starter wx-java-mp-spring-boot-starter wx-java-pay-spring-boot-starter + wx-java-cp-spring-boot-starter wx-java-open-spring-boot-starter diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/README.md b/spring-boot-starters/wx-java-cp-spring-boot-starter/README.md new file mode 100644 index 000000000..724adcee4 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/README.md @@ -0,0 +1,39 @@ +# 使用说明 +1. 在自己的Spring Boot项目里,引入maven依赖 +```xml + + com.github.binarywang + wx-java-cp-spring-boot-starter + ${version} + + ``` +2. 添加配置(application.yml) +```yml +wechat: + cp: + suite: + corpId: + providerSecret: + token: + aesKey: + suites: # 企业第三方标准应用服务中的SuiteID + - suiteId: + suiteSecret: + token: + aesKey: + redirectUri: + agent: + corpId: + appConfigs: + - agentId: + secret: + token: + aesKey: +``` + + + + + + + diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-cp-spring-boot-starter/pom.xml new file mode 100644 index 000000000..7cb25c03c --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/pom.xml @@ -0,0 +1,54 @@ + + + + wx-java-spring-boot-starters + com.github.binarywang + 3.9.7.B + + 4.0.0 + + wx-java-cp-spring-boot-starter + WxJava - Spring Boot Starter for WxCp + 微信支付开发的 Spring Boot Starter + + + + com.github.binarywang + weixin-java-cp + ${project.version} + + + + org.redisson + redisson-spring-boot-starter + 3.13.3 + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + + + diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/builder/AbstractBuilder.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/builder/AbstractBuilder.java new file mode 100644 index 000000000..e472c2e42 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/builder/AbstractBuilder.java @@ -0,0 +1,16 @@ +package com.binarywang.spring.starter.wxjava.cp.builder; + +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +public abstract class AbstractBuilder { + protected final Logger logger = LoggerFactory.getLogger(getClass()); + + public abstract WxCpXmlOutMessage build(String content, WxCpXmlMessage wxMessage, WxCpService service); +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/builder/ImageBuilder.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/builder/ImageBuilder.java new file mode 100644 index 000000000..60fb7ab87 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/builder/ImageBuilder.java @@ -0,0 +1,25 @@ +package com.binarywang.spring.starter.wxjava.cp.builder; + +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutImageMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; + + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +public class ImageBuilder extends AbstractBuilder { + + @Override + public WxCpXmlOutMessage build(String content, WxCpXmlMessage wxMessage, + WxCpService service) { + + WxCpXmlOutImageMessage m = WxCpXmlOutMessage.IMAGE().mediaId(content) + .fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()) + .build(); + + return m; + } + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/builder/TextBuilder.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/builder/TextBuilder.java new file mode 100644 index 000000000..1ceb65e9e --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/builder/TextBuilder.java @@ -0,0 +1,23 @@ +package com.binarywang.spring.starter.wxjava.cp.builder; + +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage; + + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +public class TextBuilder extends AbstractBuilder { + + @Override + public WxCpXmlOutMessage build(String content, WxCpXmlMessage wxMessage, + WxCpService service) { + WxCpXmlOutTextMessage m = WxCpXmlOutMessage.TEXT().content(content) + .fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()) + .build(); + return m; + } + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/config/WxCpConfiguration.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/config/WxCpConfiguration.java new file mode 100644 index 000000000..9ba0ce591 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/config/WxCpConfiguration.java @@ -0,0 +1,128 @@ +package com.binarywang.spring.starter.wxjava.cp.config; + +import com.binarywang.spring.starter.wxjava.cp.handler.*; +import com.binarywang.spring.starter.wxjava.cp.properties.WxCpProperties; +import com.google.common.collect.Maps; +import lombok.val; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl; +import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl; +import me.chanjar.weixin.cp.constant.WxCpConsts; +import me.chanjar.weixin.cp.message.WxCpMessageRouter; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; + + +import javax.annotation.PostConstruct; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Configuration +@EnableConfigurationProperties(WxCpProperties.class) +public class WxCpConfiguration { + private LogHandler logHandler; + private NullHandler nullHandler; + private LocationHandler locationHandler; + private MenuHandler menuHandler; + private MsgHandler msgHandler; + private UnsubscribeHandler unsubscribeHandler; + private SubscribeHandler subscribeHandler; + + private WxCpProperties properties; + + private static Map routers = Maps.newHashMap(); + private static Map cpServices = Maps.newHashMap(); + + @Autowired + public WxCpConfiguration(LogHandler logHandler, NullHandler nullHandler, LocationHandler locationHandler, + MenuHandler menuHandler, MsgHandler msgHandler, UnsubscribeHandler unsubscribeHandler, + SubscribeHandler subscribeHandler, WxCpProperties properties) { + this.logHandler = logHandler; + this.nullHandler = nullHandler; + this.locationHandler = locationHandler; + this.menuHandler = menuHandler; + this.msgHandler = msgHandler; + this.unsubscribeHandler = unsubscribeHandler; + this.subscribeHandler = subscribeHandler; + this.properties = properties; + } + + + public static Map getRouters() { + return routers; + } + + public static WxCpService getCpService(Integer agentId) { + return cpServices.get(agentId); + } + + @PostConstruct + public void initServices() { + cpServices = this.properties.getAppConfigs().stream().map(a -> { + val configStorage = new WxCpDefaultConfigImpl(); + configStorage.setCorpId(this.properties.getCorpId()); + configStorage.setAgentId(a.getAgentId()); + configStorage.setCorpSecret(a.getSecret()); + configStorage.setToken(a.getToken()); + configStorage.setAesKey(a.getAesKey()); + val service = new WxCpServiceImpl(); + service.setWxCpConfigStorage(configStorage); + routers.put(a.getAgentId(), this.newRouter(service)); + return service; + }).collect(Collectors.toMap(service -> service.getWxCpConfigStorage().getAgentId(), a -> a)); + } + + private WxCpMessageRouter newRouter(WxCpService wxCpService) { + final val newRouter = new WxCpMessageRouter(wxCpService); + + // 记录所有事件的日志 (异步执行) + newRouter.rule().handler(this.logHandler).next(); + + // 自定义菜单事件 + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) + .event(WxConsts.MenuButtonType.CLICK).handler(this.menuHandler).end(); + + // 点击菜单链接事件(这里使用了一个空的处理器,可以根据自己需要进行扩展) + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) + .event(WxConsts.MenuButtonType.VIEW).handler(this.nullHandler).end(); + + // 关注事件 + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) + .event(WxConsts.EventType.SUBSCRIBE).handler(this.subscribeHandler) + .end(); + + // 取消关注事件 + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) + .event(WxConsts.EventType.UNSUBSCRIBE) + .handler(this.unsubscribeHandler).end(); + + // 上报地理位置事件 + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) + .event(WxConsts.EventType.LOCATION).handler(this.locationHandler) + .end(); + + // 接收地理位置消息 + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.LOCATION) + .handler(this.locationHandler).end(); + + // 扫码事件(这里使用了一个空的处理器,可以根据自己需要进行扩展) + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) + .event(WxConsts.EventType.SCAN).handler(this.nullHandler).end(); + + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) + .event(WxCpConsts.EventType.CHANGE_CONTACT).handler(new ContactChangeHandler()).end(); + + newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT) + .event(WxCpConsts.EventType.ENTER_AGENT).handler(new EnterAgentHandler()).end(); + + // 默认 + newRouter.rule().async(false).handler(this.msgHandler).end(); + + return newRouter; + } +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/config/WxCpTpConfiguration.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/config/WxCpTpConfiguration.java new file mode 100644 index 000000000..1d0edc301 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/config/WxCpTpConfiguration.java @@ -0,0 +1,143 @@ +package com.binarywang.spring.starter.wxjava.cp.config; + +import com.binarywang.spring.starter.wxjava.cp.handler.tp.*; +import com.binarywang.spring.starter.wxjava.cp.properties.WxCpTpProperties; +import com.google.common.collect.Maps; +import lombok.val; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.api.impl.WxCpCorpServiceImpl; +import me.chanjar.weixin.cp.api.impl.WxCpServiceOnTpImpl; +import me.chanjar.weixin.cp.config.impl.WxCpCorpRedisConfigImpl; +import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl; +import me.chanjar.weixin.cp.config.impl.WxCpTpRedisConfigImpl; +import me.chanjar.weixin.cp.tp.constant.WxCpTpConsts; +import me.chanjar.weixin.cp.tp.message.WxCpTpMessageRouter; +import me.chanjar.weixin.cp.tp.service.WxCpCorpService; +import me.chanjar.weixin.cp.tp.service.WxCpTpService; +import me.chanjar.weixin.cp.tp.service.impl.WxCpTpServiceImpl; +import org.redisson.api.RedissonClient; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import javax.annotation.PostConstruct; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Configuration +@EnableConfigurationProperties(WxCpTpProperties.class) +public class WxCpTpConfiguration { + + private final TpLogHandler logHandler; + private final TpExternalContactHandler tpExternalContactHandler; + private final TpUserHandler tpUserHandler; + private final TpNullHandler nullHandler; + + //应用事件 + private final TpSuiteCancelAuthHandler tpSuiteCancelAuthHandler; + private final TpSuiteChangeAuthHandler tpSuiteChangeAuthHandler; + private final TpSuiteCreateAuthHandler tpSuiteCreateAuthHandler; + + private WxCpTpProperties properties; + private static WxCpCorpService wxCpCorpService; + private final RedissonClient redisson; + private static Map routers = Maps.newHashMap(); + private static Map cpTpServices = Maps.newHashMap(); + + public WxCpTpConfiguration(TpLogHandler logHandler, TpExternalContactHandler tpExternalContactHandler, TpUserHandler tpUserHandler, TpNullHandler nullHandler, TpSuiteCancelAuthHandler tpSuiteCancelAuthHandler, TpSuiteChangeAuthHandler tpSuiteChangeAuthHandler, TpSuiteCreateAuthHandler tpSuiteCreateAuthHandler, WxCpTpProperties properties, RedissonClient redisson) { + this.logHandler = logHandler; + this.tpExternalContactHandler = tpExternalContactHandler; + this.tpUserHandler = tpUserHandler; + this.nullHandler = nullHandler; + this.tpSuiteCancelAuthHandler = tpSuiteCancelAuthHandler; + this.tpSuiteChangeAuthHandler = tpSuiteChangeAuthHandler; + this.tpSuiteCreateAuthHandler = tpSuiteCreateAuthHandler; + this.properties = properties; + this.redisson = redisson; + } + + + public static WxCpTpService getCpTpService(String suiteId) { + + return cpTpServices.get(suiteId); + } + + public static WxCpCorpService getCpCorpService(){ + + return wxCpCorpService; + } + + public static WxCpService getCpService(String suiteId, String corpId, String corpSecret){ + + WxCpTpService wxCpTpService = cpTpServices.get(suiteId); + WxCpService wxCpService = new WxCpServiceOnTpImpl(wxCpTpService); + val configStorage = new WxCpDefaultConfigImpl(); + configStorage.setCorpId(corpId); + configStorage.setCorpSecret(corpSecret); + wxCpService.setWxCpConfigStorage(configStorage); + + return wxCpService; + } + + + + public static Map getRouters() { + return routers; + } + + + @PostConstruct + public void initServices() { + + val corpConfigStorage = new WxCpCorpRedisConfigImpl(redisson); + corpConfigStorage.setCorpId(properties.getCorpId()); + corpConfigStorage.setProviderSecret(properties.getProviderSecret()); + + wxCpCorpService = new WxCpCorpServiceImpl(); + wxCpCorpService.setWxCpCorpConfigStorage(corpConfigStorage); + + cpTpServices = this.properties.getSuites().stream().map(a -> { + val configStorage = new WxCpTpRedisConfigImpl(redisson); + configStorage.setCorpId(this.properties.getCorpId()); + configStorage.setSuiteId(a.getSuiteId()); + configStorage.setSuiteSecret(a.getSuiteSecret()); + configStorage.setToken(a.getToken()); + configStorage.setAesKey(a.getAesKey()); + configStorage.setOauth2redirectUri(a.getRedirectUri()); + val service = new WxCpTpServiceImpl(); + service.setWxCpTpConfigStorage(configStorage); + + routers.put(a.getSuiteId(), this.newRouter(service)); + return service; + }).collect(Collectors.toMap(service -> service.getWxCpTpConfigStorage().getSuiteId(), a -> a)); + + } + + private WxCpTpMessageRouter newRouter(WxCpTpService wxCpTpService) { + final val newRouter = new WxCpTpMessageRouter(wxCpTpService); + + newRouter.rule().handler(this.logHandler).next(); + + //创建授权事件 + newRouter.rule().async(false).infoType(WxCpTpConsts.InfoType.CREATE_AUTH).handler(this.tpSuiteCreateAuthHandler).end(); + + //取消授权事件 + newRouter.rule().async(false).infoType(WxCpTpConsts.InfoType.CANCEL_AUTH).handler(this.tpSuiteCancelAuthHandler).end(); + + //变更授权事件 + newRouter.rule().async(false).infoType(WxCpTpConsts.InfoType.CHANGE_AUTH).handler(this.tpSuiteChangeAuthHandler).end(); + + //外部联系人相关事件 + newRouter.rule().async(false).infoType(WxCpTpConsts.InfoType.CHANGE_EXTERNAL_CONTACT).handler(this.tpExternalContactHandler).end(); + + //内部人员相关事件 + newRouter.rule().async(false).infoType(WxCpTpConsts.InfoType.CHANGE_CONTACT).handler(this.tpUserHandler).end(); + ; + + return newRouter; + } + + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/AbstractHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/AbstractHandler.java new file mode 100644 index 000000000..e41b72fe6 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/AbstractHandler.java @@ -0,0 +1,14 @@ +package com.binarywang.spring.starter.wxjava.cp.handler; + +import me.chanjar.weixin.cp.message.WxCpMessageHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +public abstract class AbstractHandler implements WxCpMessageHandler { + + protected Logger logger = LoggerFactory.getLogger(getClass()); + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/AbstractTpHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/AbstractTpHandler.java new file mode 100644 index 000000000..77456b728 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/AbstractTpHandler.java @@ -0,0 +1,14 @@ +package com.binarywang.spring.starter.wxjava.cp.handler; + +import me.chanjar.weixin.cp.tp.message.WxCpTpMessageHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +public abstract class AbstractTpHandler implements WxCpTpMessageHandler { + + protected Logger logger = LoggerFactory.getLogger(getClass()); + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/ContactChangeHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/ContactChangeHandler.java new file mode 100644 index 000000000..2d41285f0 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/ContactChangeHandler.java @@ -0,0 +1,30 @@ +package com.binarywang.spring.starter.wxjava.cp.handler; + +import com.binarywang.spring.starter.wxjava.cp.builder.TextBuilder; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import org.springframework.stereotype.Component; + +import java.util.Map; + + +/** + * 通讯录变更事件处理器. + * + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class ContactChangeHandler extends AbstractHandler { + + + @Override + public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context, WxCpService cpService, + WxSessionManager sessionManager) { + String content = "收到通讯录变更事件,内容:" + wxMessage.toString(); + //this.logger.info(content); + return new TextBuilder().build(content, wxMessage, cpService); + } + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/EnterAgentHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/EnterAgentHandler.java new file mode 100644 index 000000000..572a51107 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/EnterAgentHandler.java @@ -0,0 +1,31 @@ +package com.binarywang.spring.starter.wxjava.cp.handler; + +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; + +import java.util.Map; + + +/** + *
+ *
+ * Created by Binary Wang on 2018/8/27.
+ * 
+ * + * @author Binary Wang + */ +@Slf4j +public class EnterAgentHandler extends AbstractHandler { + + private static final int TEST_AGENT = 1000002; + + @Override + public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context, WxCpService wxCpService, WxSessionManager sessionManager) throws WxErrorException { + // do something + return null; + } +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/LocationHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/LocationHandler.java new file mode 100644 index 000000000..0f359a1c7 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/LocationHandler.java @@ -0,0 +1,44 @@ +package com.binarywang.spring.starter.wxjava.cp.handler; + +import com.binarywang.spring.starter.wxjava.cp.builder.TextBuilder; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import org.springframework.stereotype.Component; + +import java.util.Map; + + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class LocationHandler extends AbstractHandler { + + @Override + public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context, WxCpService cpService, + WxSessionManager sessionManager) { + if (wxMessage.getMsgType().equals(WxConsts.XmlMsgType.LOCATION)) { + //TODO 接收处理用户发送的地理位置消息 + try { + String content = "感谢反馈,您的的地理位置已收到!"; + return new TextBuilder().build(content, wxMessage, null); + } catch (Exception e) { + this.logger.error("位置消息接收处理失败", e); + return null; + } + } + + + //上报地理位置事件 + this.logger.info("\n上报地理位置,纬度 : {}\n经度 : {}\n精度 : {}", + wxMessage.getLatitude(), wxMessage.getLongitude(), String.valueOf(wxMessage.getPrecision())); + + //TODO 可以将用户地理位置信息保存到本地数据库,以便以后使用 + + return null; + } + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/LogHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/LogHandler.java new file mode 100644 index 000000000..ab9cdf697 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/LogHandler.java @@ -0,0 +1,26 @@ +package com.binarywang.spring.starter.wxjava.cp.handler; + +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import org.springframework.stereotype.Component; + +import java.util.Map; + + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class LogHandler extends AbstractHandler { + + @Override + public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context, WxCpService cpService, + WxSessionManager sessionManager) { + this.logger.info("\n接收到请求消息,内容:{}", wxMessage.getAllFieldsMap()); + + return null; + } + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/MenuHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/MenuHandler.java new file mode 100644 index 000000000..9471f763d --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/MenuHandler.java @@ -0,0 +1,36 @@ +package com.binarywang.spring.starter.wxjava.cp.handler; + +import me.chanjar.weixin.common.api.WxConsts.MenuButtonType; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import org.springframework.stereotype.Component; + +import java.util.Map; + + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class MenuHandler extends AbstractHandler { + + @Override + public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context, WxCpService cpService, + WxSessionManager sessionManager) { + + String msg = String.format("type:%s, event:%s, key:%s", + wxMessage.getMsgType(), wxMessage.getEvent(), + wxMessage.getEventKey()); + if (MenuButtonType.VIEW.equals(wxMessage.getEvent())) { + return null; + } + + return WxCpXmlOutMessage.TEXT().content(msg) + .fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName()) + .build(); + } + + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/MsgHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/MsgHandler.java new file mode 100644 index 000000000..c9a260dee --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/MsgHandler.java @@ -0,0 +1,39 @@ +package com.binarywang.spring.starter.wxjava.cp.handler; + +import com.binarywang.spring.starter.wxjava.cp.builder.TextBuilder; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class MsgHandler extends AbstractHandler { + + @Override + public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context, WxCpService cpService, + WxSessionManager sessionManager) { + final String msgType = wxMessage.getMsgType(); + if (msgType == null) { + // 如果msgType没有,就自己根据具体报文内容做处理 + } + + if (!msgType.equals(WxConsts.XmlMsgType.EVENT)) { + //TODO 可以选择将消息保存到本地 + } + + //TODO 组装回复消息 + String content = "收到信息内容:" + wxMessage.toString(); + + return new TextBuilder().build(content, wxMessage, cpService); + + + } + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/NullHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/NullHandler.java new file mode 100644 index 000000000..693bcb796 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/NullHandler.java @@ -0,0 +1,25 @@ +package com.binarywang.spring.starter.wxjava.cp.handler; + +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import org.springframework.stereotype.Component; + +import java.util.Map; + + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class NullHandler extends AbstractHandler { + + + @Override + public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context, WxCpService cpService, + WxSessionManager sessionManager) { + return null; + } + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/ScanHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/ScanHandler.java new file mode 100644 index 000000000..643a8c00f --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/ScanHandler.java @@ -0,0 +1,9 @@ +package com.binarywang.spring.starter.wxjava.cp.handler; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +public abstract class ScanHandler extends AbstractHandler { + + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/SubscribeHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/SubscribeHandler.java new file mode 100644 index 000000000..824726143 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/SubscribeHandler.java @@ -0,0 +1,63 @@ +package com.binarywang.spring.starter.wxjava.cp.handler; + +import com.binarywang.spring.starter.wxjava.cp.builder.TextBuilder; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.WxCpUser; +import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import org.springframework.stereotype.Component; + +import java.util.Map; + + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class SubscribeHandler extends AbstractHandler { + + + @Override + public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context, WxCpService cpService, + WxSessionManager sessionManager) throws WxErrorException { + + this.logger.info("新关注用户 OPENID: " + wxMessage.getFromUserName()); + + // 获取微信用户基本信息 + WxCpUser userWxInfo = cpService.getUserService().getById(wxMessage.getFromUserName()); + + if (userWxInfo != null) { + // TODO 可以添加关注用户到本地 + } + + WxCpXmlOutMessage responseResult = null; + try { + responseResult = handleSpecial(wxMessage); + } catch (Exception e) { + this.logger.error(e.getMessage(), e); + } + + if (responseResult != null) { + return responseResult; + } + + try { + return new TextBuilder().build("感谢关注", wxMessage, cpService); + } catch (Exception e) { + this.logger.error(e.getMessage(), e); + } + + return null; + } + + /** + * 处理特殊请求,比如如果是扫码进来的,可以做相应处理 + */ + private WxCpXmlOutMessage handleSpecial(WxCpXmlMessage wxMessage) { + //TODO + return null; + } + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/UnsubscribeHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/UnsubscribeHandler.java new file mode 100644 index 000000000..999088c8f --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/UnsubscribeHandler.java @@ -0,0 +1,28 @@ +package com.binarywang.spring.starter.wxjava.cp.handler; + +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import org.springframework.stereotype.Component; + +import java.util.Map; + + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class UnsubscribeHandler extends AbstractHandler { + + + @Override + public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map context, WxCpService cpService, + WxSessionManager sessionManager) { + String openId = wxMessage.getFromUserName(); + this.logger.info("取消关注用户 OPENID: " + openId); + // TODO 可以更新本地数据库为取消关注状态 + return null; + } + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpExternalContactHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpExternalContactHandler.java new file mode 100644 index 000000000..736d4784a --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpExternalContactHandler.java @@ -0,0 +1,27 @@ +package com.binarywang.spring.starter.wxjava.cp.handler.tp; + +import com.binarywang.spring.starter.wxjava.cp.handler.AbstractTpHandler; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import me.chanjar.weixin.cp.tp.service.WxCpTpService; +import org.springframework.stereotype.Component; + +import java.util.Map; + +/** + * 外部联系人事件 + * @author huangxiaoming + */ +@Component +public class TpExternalContactHandler extends AbstractTpHandler { + + @Override + public WxCpXmlOutMessage handle(WxCpTpXmlMessage wxMessage, Map context, WxCpTpService cpService, + WxSessionManager sessionManager) throws WxErrorException { + logger.info("收到添加外部联系人事件,内容:{}" + wxMessage.getAllFieldsMap()); + + return null; + } +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpLogHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpLogHandler.java new file mode 100644 index 000000000..22dbe89f5 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpLogHandler.java @@ -0,0 +1,27 @@ +package com.binarywang.spring.starter.wxjava.cp.handler.tp; + +import com.binarywang.spring.starter.wxjava.cp.handler.AbstractTpHandler; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import me.chanjar.weixin.cp.tp.service.WxCpTpService; +import org.springframework.stereotype.Component; + +import java.util.Map; + + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class TpLogHandler extends AbstractTpHandler { + + @Override + public WxCpXmlOutMessage handle(WxCpTpXmlMessage wxMessage, Map context, WxCpTpService service, + WxSessionManager sessionManager) { + this.logger.info("\n接收到请求消息,内容:{}", wxMessage.getAllFieldsMap()); + + return null; + } + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpNullHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpNullHandler.java new file mode 100644 index 000000000..3dd599201 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpNullHandler.java @@ -0,0 +1,26 @@ +package com.binarywang.spring.starter.wxjava.cp.handler.tp; + +import com.binarywang.spring.starter.wxjava.cp.handler.AbstractTpHandler; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import me.chanjar.weixin.cp.tp.service.WxCpTpService; +import org.springframework.stereotype.Component; + +import java.util.Map; + + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class TpNullHandler extends AbstractTpHandler { + + + @Override + public WxCpXmlOutMessage handle(WxCpTpXmlMessage wxMessage, Map context, WxCpTpService service, + WxSessionManager sessionManager) { + return null; + } + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpSuiteCancelAuthHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpSuiteCancelAuthHandler.java new file mode 100644 index 000000000..8aefc94e1 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpSuiteCancelAuthHandler.java @@ -0,0 +1,30 @@ +package com.binarywang.spring.starter.wxjava.cp.handler.tp; + +import com.binarywang.spring.starter.wxjava.cp.handler.AbstractTpHandler; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import me.chanjar.weixin.cp.tp.service.WxCpTpService; +import org.springframework.stereotype.Component; + +import java.util.Map; + + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Slf4j +@Component +public class TpSuiteCancelAuthHandler extends AbstractTpHandler { + + + @Override + public WxCpXmlOutMessage handle(WxCpTpXmlMessage wxMessage, Map context, WxCpTpService service, + WxSessionManager sessionManager) { + + logger.info("\n收到应用取消授权事件,内容:" + wxMessage.getAllFieldsMap()); + return null; + } + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpSuiteChangeAuthHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpSuiteChangeAuthHandler.java new file mode 100644 index 000000000..f2e5a31f0 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpSuiteChangeAuthHandler.java @@ -0,0 +1,36 @@ +package com.binarywang.spring.starter.wxjava.cp.handler.tp; + + +import com.binarywang.spring.starter.wxjava.cp.handler.AbstractTpHandler; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import me.chanjar.weixin.cp.tp.service.WxCpTpService; +import org.springframework.stereotype.Component; + +import java.util.Map; + + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Slf4j +@Component +public class TpSuiteChangeAuthHandler extends AbstractTpHandler { + + + + + @Override + public WxCpXmlOutMessage handle(WxCpTpXmlMessage wxMessage, Map context, WxCpTpService service, + WxSessionManager sessionManager) { + + logger.info("收到变更授权事件,内容:{}", wxMessage.getAllFieldsMap()); + + + + return null; + } + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpSuiteCreateAuthHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpSuiteCreateAuthHandler.java new file mode 100644 index 000000000..dca6ec9b6 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpSuiteCreateAuthHandler.java @@ -0,0 +1,33 @@ +package com.binarywang.spring.starter.wxjava.cp.handler.tp; + + +import com.binarywang.spring.starter.wxjava.cp.config.WxCpTpConfiguration; +import com.binarywang.spring.starter.wxjava.cp.handler.AbstractTpHandler; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.bean.WxCpTpPermanentCodeInfo; +import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import me.chanjar.weixin.cp.tp.service.WxCpTpService; +import org.springframework.stereotype.Component; + +import java.util.Map; + + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class TpSuiteCreateAuthHandler extends AbstractTpHandler { + + + + + @Override + public WxCpXmlOutMessage handle(WxCpTpXmlMessage wxMessage, Map context, WxCpTpService service, + WxSessionManager sessionManager) { + logger.info("收到创建授权事件,内容:" ,wxMessage.getAllFieldsMap()); + + return null; + } + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpUserHandler.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpUserHandler.java new file mode 100644 index 000000000..fc66c5ed7 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/handler/tp/TpUserHandler.java @@ -0,0 +1,29 @@ +package com.binarywang.spring.starter.wxjava.cp.handler.tp; + +import com.binarywang.spring.starter.wxjava.cp.handler.AbstractTpHandler; +import me.chanjar.weixin.common.session.WxSessionManager; +import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage; +import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage; +import me.chanjar.weixin.cp.tp.service.WxCpTpService; +import org.springframework.stereotype.Component; + +import java.util.Map; + + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Component +public class TpUserHandler extends AbstractTpHandler { + + @Override + public WxCpXmlOutMessage handle(WxCpTpXmlMessage wxMessage, Map context, WxCpTpService service, + WxSessionManager sessionManager) { + + + return null; + } + + + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpProperties.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpProperties.java new file mode 100644 index 000000000..4b851a564 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpProperties.java @@ -0,0 +1,49 @@ +package com.binarywang.spring.starter.wxjava.cp.properties; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.util.List; + +/** + * @author Binary Wang(https://github.com/binarywang) + */ +@Getter +@Setter +@ConfigurationProperties(prefix = "wechat.cp.agent") +public class WxCpProperties { + /** + * 设置微信企业号的corpId + */ + private String corpId; + + private List appConfigs; + + @Getter + @Setter + public static class AppConfig { + /** + * 设置微信企业应用的AgentId + */ + private Integer agentId; + + /** + * 设置微信企业应用的Secret + */ + private String secret; + + /** + * 设置微信企业号的token + */ + private String token; + + /** + * 设置微信企业号的EncodingAESKey + */ + private String aesKey; + + } + + +} diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpTpProperties.java b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpTpProperties.java new file mode 100644 index 000000000..0f961f289 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/cp/properties/WxCpTpProperties.java @@ -0,0 +1,102 @@ +package com.binarywang.spring.starter.wxjava.cp.properties; + +import lombok.Data; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.io.Serializable; +import java.util.List; + +/** + * * @author Binary Wang(https://github.com/binarywang) + */ +@Data +@ConfigurationProperties(prefix = "wechat.cp.suite") +public class WxCpTpProperties { + /** + * 设置微信企业号的corpId + */ + private String corpId; + + /** + * 设置微信企业的Secret + */ + private String secret; + + /** + * ProviderSecret + * */ + private String providerSecret; + + + /** + * 设置微信企业号的token + */ + private String token; + + /** + * 设置微信企业号的EncodingAESKey + */ + private String aesKey; + + /** + * 系统默认的SuiteId + */ + private String defaultSuiteId; + + /** + * 是否提醒管理员 + * */ + private Boolean reminderAdmin; + + @Value(value = "30") + private Integer suiteDefaultMember; + + private List suites; + + @Getter + @Setter + public static class SuiteConfig implements Serializable { + + /** + * 设置微信企业号的suiteId + */ + private String suiteId; + + /** + * 设置微信企业应用的Secret + */ + private String suiteSecret; + + /** + * 设置微信企业号的token + */ + private String token; + + /** + * 设置微信企业号的EncodingAESKey + */ + private String aesKey; + + /** + * 设置微信企业的授权回调URL + */ + private String redirectUri; + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } + + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE); + } +} + diff --git a/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/resources/META-INF/spring.factories b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 000000000..9d76ccbe9 --- /dev/null +++ b/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.binarywang.spring.starter.wxjava.cp.config.WxPayAutoConfiguration