From e7dd7429233b58df55940c6680ff82a64b9df7df Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Tue, 25 Dec 2018 18:49:20 +0800 Subject: [PATCH 01/81] =?UTF-8?q?=E4=BF=AE=E6=94=B9totalFee=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=E7=B1=BB=E5=9E=8B=E4=B8=BAInteger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bean/result/WxPayMicropayResult.java | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayMicropayResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayMicropayResult.java index 87aad5f436..36f910be63 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayMicropayResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayMicropayResult.java @@ -18,9 +18,11 @@ @NoArgsConstructor @XStreamAlias("xml") public class WxPayMicropayResult extends BaseWxPayResult { + private static final long serialVersionUID = 529670965722059189L; + /** *
-   * 用户标识
+   * 用户标识.
    * openid
    * 是
    * String(128)
@@ -33,7 +35,7 @@ public class WxPayMicropayResult extends BaseWxPayResult {
 
   /**
    * 
-   * 是否关注公众账号
+   * 是否关注公众账号.
    * is_subscribe
    * 是
    * String(1)
@@ -46,7 +48,7 @@ public class WxPayMicropayResult extends BaseWxPayResult {
 
   /**
    * 
-   * 交易类型
+   * 交易类型.
    * trade_type
    * 是
    * String(16)
@@ -59,7 +61,7 @@ public class WxPayMicropayResult extends BaseWxPayResult {
 
   /**
    * 
-   * 付款银行
+   * 付款银行.
    * bank_type
    * 是
    * String(32)
@@ -72,7 +74,7 @@ public class WxPayMicropayResult extends BaseWxPayResult {
 
   /**
    * 
-   * 货币类型
+   * 货币类型.
    * fee_type
    * 否
    * String(16)
@@ -85,7 +87,7 @@ public class WxPayMicropayResult extends BaseWxPayResult {
 
   /**
    * 
-   * 订单金额
+   * 订单金额.
    * total_fee
    * 是
    * Int
@@ -94,11 +96,11 @@ public class WxPayMicropayResult extends BaseWxPayResult {
    * 
**/ @XStreamAlias("total_fee") - private String totalFee; + private Integer totalFee; /** *
-   * 应结订单金额
+   * 应结订单金额.
    * settlement_total_fee
    * 否
    * Int
@@ -111,7 +113,7 @@ public class WxPayMicropayResult extends BaseWxPayResult {
 
   /**
    * 
-   * 代金券金额
+   * 代金券金额.
    * coupon_fee
    * 否
    * Int
@@ -124,7 +126,7 @@ public class WxPayMicropayResult extends BaseWxPayResult {
 
   /**
    * 
-   * 现金支付货币类型
+   * 现金支付货币类型.
    * cash_fee_type
    * 否
    * String(16)
@@ -137,7 +139,7 @@ public class WxPayMicropayResult extends BaseWxPayResult {
 
   /**
    * 
-   * 现金支付金额
+   * 现金支付金额.
    * cash_fee
    * 是
    * Int
@@ -150,7 +152,7 @@ public class WxPayMicropayResult extends BaseWxPayResult {
 
   /**
    * 
-   * 微信支付订单号
+   * 微信支付订单号.
    * transaction_id
    * 是
    * String(32)
@@ -163,7 +165,7 @@ public class WxPayMicropayResult extends BaseWxPayResult {
 
   /**
    * 
-   * 商户订单号
+   * 商户订单号.
    * out_trade_no
    * 是
    * String(32)
@@ -176,7 +178,7 @@ public class WxPayMicropayResult extends BaseWxPayResult {
 
   /**
    * 
-   * 商家数据包
+   * 商家数据包.
    * attach
    * 否
    * String(128)
@@ -189,7 +191,7 @@ public class WxPayMicropayResult extends BaseWxPayResult {
 
   /**
    * 
-   * 支付完成时间
+   * 支付完成时间.
    * time_end
    * 是
    * String(14)
@@ -202,7 +204,7 @@ public class WxPayMicropayResult extends BaseWxPayResult {
 
   /**
    * 
-   * 营销详情
+   * 营销详情.
    * promotion_detail
    * 否
    * String(6000)

From 5af4059970d280328e35b80d0a04a472906c20fb Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Wed, 26 Dec 2018 16:24:30 +0800
Subject: [PATCH 02/81] =?UTF-8?q?=E4=BC=81=E4=B8=9A=E5=BE=AE=E4=BF=A1?=
 =?UTF-8?q?=E9=83=A8=E9=97=A8=E5=88=9B=E5=BB=BA=E6=8E=A5=E5=8F=A3create?=
 =?UTF-8?q?=E8=BF=94=E5=9B=9E=E5=80=BC=E6=94=B9=E4=B8=BAlong=E7=B1=BB?=
 =?UTF-8?q?=E5=9E=8B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../java/me/chanjar/weixin/cp/api/WxCpDepartmentService.java  | 2 +-
 .../chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImpl.java | 4 ++--
 .../weixin/cp/api/impl/WxCpDepartmentServiceImplTest.java     | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpDepartmentService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpDepartmentService.java
index 8a8ca054d3..82e571ac5b 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpDepartmentService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpDepartmentService.java
@@ -26,7 +26,7 @@ public interface WxCpDepartmentService {
    * @return 部门id
    * @throws WxErrorException 异常
    */
-  Integer create(WxCpDepart depart) throws WxErrorException;
+  Long create(WxCpDepart depart) throws WxErrorException;
 
   /**
    * 
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImpl.java
index 5d623b2ad4..481115fa51 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImpl.java
@@ -28,11 +28,11 @@ public WxCpDepartmentServiceImpl(WxCpService mainService) {
   }
 
   @Override
-  public Integer create(WxCpDepart depart) throws WxErrorException {
+  public Long create(WxCpDepart depart) throws WxErrorException {
     String url = "https://qyapi.weixin.qq.com/cgi-bin/department/create";
     String responseContent = this.mainService.post(url, depart.toJson());
     JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
-    return GsonHelper.getAsInteger(tmpJsonElement.getAsJsonObject().get("id"));
+    return GsonHelper.getAsLong(tmpJsonElement.getAsJsonObject().get("id"));
   }
 
   @Override
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImplTest.java
index 097a6ee71f..57957d3fb6 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImplTest.java
@@ -31,7 +31,7 @@ public void testCreate() throws Exception {
     cpDepart.setName("子部门" + System.currentTimeMillis());
     cpDepart.setParentId(1L);
     cpDepart.setOrder(1L);
-    Integer departId = this.wxCpService.getDepartmentService().create(cpDepart);
+    Long departId = this.wxCpService.getDepartmentService().create(cpDepart);
     System.out.println(departId);
   }
 

From 556085997da3250a484cd898f62c5e4e10bea88c Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Fri, 28 Dec 2018 21:43:57 +0800
Subject: [PATCH 03/81] =?UTF-8?q?#899=20WxCpXmlMessage=E5=A2=9E=E5=8A=A0?=
 =?UTF-8?q?=E5=AD=98=E6=94=BExml=E6=B6=88=E6=81=AF=E7=9A=84=E6=89=80?=
 =?UTF-8?q?=E6=9C=89=E5=B1=9E=E6=80=A7=E5=80=BC=E7=9A=84allFieldsMap?=
 =?UTF-8?q?=E5=B1=9E=E6=80=A7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../me/chanjar/weixin/cp/bean/WxCpXmlMessage.java     | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java
index 3fc2137f3e..90d67b07bc 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java
@@ -6,6 +6,7 @@
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.commons.io.IOUtils;
 
@@ -14,6 +15,7 @@
 import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
 import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.common.util.XmlUtils;
 import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
 import me.chanjar.weixin.cp.config.WxCpConfigStorage;
 import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil;
@@ -36,6 +38,11 @@
 public class WxCpXmlMessage implements Serializable {
   private static final long serialVersionUID = -1042994982179476410L;
 
+  /**
+   * 使用dom4j解析的存放所有xml属性和值的map.
+   */
+  private Map allFieldsMap;
+
   ///////////////////////
   // 以下都是微信推送过来的消息的xml的element所对应的属性
   ///////////////////////
@@ -349,7 +356,9 @@ public class WxCpXmlMessage implements Serializable {
   protected static WxCpXmlMessage fromXml(String xml) {
     //修改微信变态的消息内容格式,方便解析
     xml = xml.replace("", "");
-    return XStreamTransformer.fromXml(WxCpXmlMessage.class, xml);
+    final WxCpXmlMessage xmlMessage = XStreamTransformer.fromXml(WxCpXmlMessage.class, xml);
+    xmlMessage.setAllFieldsMap(XmlUtils.xml2Map(xml));
+    return xmlMessage;
   }
 
   protected static WxCpXmlMessage fromXml(InputStream is) {

From 6a2ff801f03e50890571bf167b15f9daae9f5654 Mon Sep 17 00:00:00 2001
From: IOMan 
Date: Sat, 29 Dec 2018 19:45:52 +0800
Subject: [PATCH 04/81] =?UTF-8?q?#900=20=E5=A2=9E=E5=8A=A0=E6=96=B0?=
 =?UTF-8?q?=E5=A2=9E=E5=9B=A2=E8=B4=AD=E5=88=B8=E3=80=81=E7=8E=B0=E9=87=91?=
 =?UTF-8?q?=E6=8A=B5=E6=89=A3=E5=88=B8=E3=80=81=E6=8A=98=E6=89=A3=E5=88=B8?=
 =?UTF-8?q?=E3=80=81=E5=85=91=E6=8D=A2=E5=88=B8=E4=BB=A5=E5=8F=8A=E6=99=AE?=
 =?UTF-8?q?=E9=80=9A=E4=BC=98=E6=83=A0=E5=88=B8=E7=9A=84=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../weixin/mp/api/WxMpCardService.java        | 13 ++-
 .../mp/api/impl/WxMpCardServiceImpl.java      | 11 ++-
 .../me/chanjar/weixin/mp/bean/card/Card.java  | 31 ++++++
 .../mp/bean/card/CardCreateRequest.java       | 13 +++
 .../chanjar/weixin/mp/bean/card/CashCard.java | 39 ++++++++
 .../mp/bean/card/CashCardCreateRequest.java   | 25 +++++
 .../weixin/mp/bean/card/DiscountCard.java     | 32 +++++++
 .../bean/card/DiscountCardCreateRequest.java  | 25 +++++
 .../weixin/mp/bean/card/GeneralCard.java      | 33 +++++++
 .../bean/card/GeneralCardCreateRequest.java   | 26 +++++
 .../chanjar/weixin/mp/bean/card/GiftCard.java | 32 +++++++
 .../mp/bean/card/GiftCardCreateRequest.java   | 25 +++++
 .../weixin/mp/bean/card/GrouponCard.java      | 33 +++++++
 .../bean/card/GrouponCardCreateRequest.java   | 25 +++++
 .../mp/bean/card/WxMpCardCreateMessage.java   | 23 +++++
 .../mp/api/impl/WxMpCardServiceImplTest.java  | 96 +++++++++++++++++++
 .../open/api/WxOpenComponentService.java      | 14 +++
 .../api/impl/WxOpenComponentServiceImpl.java  | 11 +++
 .../weixin/open/bean/WxOpenCreateResult.java  | 36 +++++++
 19 files changed, 537 insertions(+), 6 deletions(-)
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Card.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CardCreateRequest.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CashCard.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CashCardCreateRequest.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DiscountCard.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DiscountCardCreateRequest.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GeneralCard.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GeneralCardCreateRequest.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GiftCard.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GiftCardCreateRequest.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GrouponCard.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GrouponCardCreateRequest.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCreateMessage.java
 create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenCreateResult.java

diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java
index af6cefcff8..d0f06c13b8 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java
@@ -2,9 +2,7 @@
 
 import me.chanjar.weixin.common.bean.WxCardApiSignature;
 import me.chanjar.weixin.common.error.WxErrorException;
-import me.chanjar.weixin.mp.bean.card.WxMpCardLandingPageCreateRequest;
-import me.chanjar.weixin.mp.bean.card.WxMpCardLandingPageCreateResult;
-import me.chanjar.weixin.mp.bean.card.WxMpCardQrcodeCreateResult;
+import me.chanjar.weixin.mp.bean.card.*;
 import me.chanjar.weixin.mp.bean.result.WxMpCardResult;
 
 /**
@@ -14,6 +12,7 @@
  * @author yuanqixun 2018-08-29
  */
 public interface WxMpCardService {
+  String CARD_CREATE = "https://api.weixin.qq.com/card/create";
   String CARD_GET = "https://api.weixin.qq.com/card/get";
   String CARD_GET_TICKET = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=wx_card";
   String CARD_CODE_DECRYPT = "https://api.weixin.qq.com/card/code/decrypt";
@@ -142,6 +141,14 @@ void markCardCode(String code, String cardId, String openId, boolean isMark) thr
    */
   String addTestWhiteList(String openid) throws WxErrorException;
 
+  /**
+   *
+   * @param cardCreateMessage
+   * @return
+   * @throws WxErrorException
+   */
+  WxMpCardCreateResult createCard(WxMpCardCreateMessage cardCreateMessage) throws WxErrorException;
+
   /**
    * 创建卡券二维码
    *
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java
index bfd58856d0..5237fd6d2a 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java
@@ -3,6 +3,7 @@
 import java.util.Arrays;
 import java.util.concurrent.locks.Lock;
 
+import me.chanjar.weixin.mp.bean.card.*;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -22,9 +23,6 @@
 import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
 import me.chanjar.weixin.mp.api.WxMpCardService;
 import me.chanjar.weixin.mp.api.WxMpService;
-import me.chanjar.weixin.mp.bean.card.WxMpCardLandingPageCreateRequest;
-import me.chanjar.weixin.mp.bean.card.WxMpCardLandingPageCreateResult;
-import me.chanjar.weixin.mp.bean.card.WxMpCardQrcodeCreateResult;
 import me.chanjar.weixin.mp.bean.result.WxMpCardResult;
 import me.chanjar.weixin.mp.enums.TicketType;
 import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
@@ -265,6 +263,13 @@ public String addTestWhiteList(String openid) throws WxErrorException {
     return respone;
   }
 
+  @Override
+  public WxMpCardCreateResult createCard(WxMpCardCreateMessage cardCreateMessage) throws WxErrorException {
+
+    String response = this.wxMpService.post(CARD_CREATE, GSON.toJson(cardCreateMessage));
+    return WxMpCardCreateResult.fromJson(response);
+  }
+
   /**
    * 创建卡券二维码.
    */
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Card.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Card.java
new file mode 100644
index 0000000000..c97f88f2fc
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/Card.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
+import java.io.Serializable;
+
+/**
+ * .
+ * @author leeis
+ * @Date 2018/12/29
+ */
+@Data
+public class Card implements Serializable {
+
+  private static final long serialVersionUID = -3697110761983756780L;
+
+  /**
+   * 基本信息.
+   */
+  @SerializedName("base_info")
+  private BaseInfo baseInfo;
+
+  /**
+   * 创建优惠券特有的高级字段.
+   */
+  @SerializedName("advanced_info")
+  private AdvancedInfo advancedInfo;
+
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CardCreateRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CardCreateRequest.java
new file mode 100644
index 0000000000..8cb16bc7b2
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CardCreateRequest.java
@@ -0,0 +1,13 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Author leeis
+ * @Date 2018/12/29
+ */
+@Data
+public class CardCreateRequest implements Serializable {
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CashCard.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CashCard.java
new file mode 100644
index 0000000000..3d4de40c0b
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CashCard.java
@@ -0,0 +1,39 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
+import java.io.Serializable;
+
+/**
+ * .
+ * @author leeis
+ * @Date 2018/12/29
+ */
+@Data
+public final class CashCard extends Card implements Serializable {
+
+  private static final long serialVersionUID = 6965491956462769745L;
+
+  /**
+   * 代金券专用,表示起用金额(单位为分),如果无起用门槛则填0
+   */
+  @SerializedName("least_cost")
+  private int leastCost;
+
+  /**
+   * 代金券专用,表示减免金额。(单位为分)
+   */
+  @SerializedName("reduce_cost")
+  private int reduceCost;
+
+  @Override
+  public String toString() {
+    return WxMpGsonBuilder.create().toJson(this);
+  }
+
+  public static CashCard fromJson(String json) {
+    return WxMpGsonBuilder.create().fromJson(json, CashCard.class);
+  }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CashCardCreateRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CashCardCreateRequest.java
new file mode 100644
index 0000000000..dcefab0e29
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CashCardCreateRequest.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
+import java.io.Serializable;
+
+/**
+ * .
+ * @author leeis
+ * @Date 2018/12/29
+ */
+@Data
+public class CashCardCreateRequest extends CardCreateRequest implements Serializable {
+  @SerializedName("card_type")
+  private String cardType = "CASH";
+
+  private CashCard cash;
+
+  @Override
+  public String toString() {
+    return WxMpGsonBuilder.create().toJson(this);
+  }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DiscountCard.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DiscountCard.java
new file mode 100644
index 0000000000..b2c3a13ffc
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DiscountCard.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
+import java.io.Serializable;
+
+/**
+ * .
+ * @author leeis
+ * @Date 2018/12/29
+ */
+@Data
+public final class DiscountCard extends Card implements Serializable {
+
+  private static final long serialVersionUID = 1704610082472315077L;
+
+  /**
+   * 折扣券专用,表示打折额度(百分比)。填30就是七折。
+   */
+  private int discount;
+
+  @Override
+  public String toString() {
+    return WxMpGsonBuilder.create().toJson(this);
+  }
+
+  public static DiscountCard fromJson(String json) {
+    return WxMpGsonBuilder.create().fromJson(json, DiscountCard.class);
+  }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DiscountCardCreateRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DiscountCardCreateRequest.java
new file mode 100644
index 0000000000..869c487c92
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DiscountCardCreateRequest.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
+import java.io.Serializable;
+
+/**
+ * .
+ * @author leeis
+ * @Date 2018/12/29
+ */
+@Data
+public class DiscountCardCreateRequest extends CardCreateRequest implements Serializable {
+  @SerializedName("card_type")
+  private String cardType = "DISCOUNT";
+
+  private DiscountCard discount;
+
+  @Override
+  public String toString() {
+    return WxMpGsonBuilder.create().toJson(this);
+  }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GeneralCard.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GeneralCard.java
new file mode 100644
index 0000000000..dcfba74da7
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GeneralCard.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
+import java.io.Serializable;
+
+/**
+ * .
+ * @author leeis
+ * @Date 2018/12/29
+ */
+@Data
+public final class GeneralCard extends Card implements Serializable {
+
+  private static final long serialVersionUID = -1577656733441132585L;
+
+  /**
+   * 兑换券专用,填写兑换内容的名称。
+   */
+  @SerializedName("default_detail")
+  private String defaultDetail;
+
+  @Override
+  public String toString() {
+    return WxMpGsonBuilder.create().toJson(this);
+  }
+
+  public static GeneralCard fromJson(String json) {
+    return WxMpGsonBuilder.create().fromJson(json, GeneralCard.class);
+  }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GeneralCardCreateRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GeneralCardCreateRequest.java
new file mode 100644
index 0000000000..8a9c3d1801
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GeneralCardCreateRequest.java
@@ -0,0 +1,26 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
+import java.io.Serializable;
+
+/**
+ * .
+ * @author leeis
+ * @Date 2018/12/29
+ */
+@Data
+public class GeneralCardCreateRequest extends CardCreateRequest implements Serializable {
+  @SerializedName("card_type")
+  private String cardType = "GENERAL_COUPON";
+
+  @SerializedName("general_coupon")
+  private GeneralCard generalCoupon;
+
+  @Override
+  public String toString() {
+    return WxMpGsonBuilder.create().toJson(this);
+  }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GiftCard.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GiftCard.java
new file mode 100644
index 0000000000..0bfb5359ba
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GiftCard.java
@@ -0,0 +1,32 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
+import java.io.Serializable;
+
+/**
+ * .
+ * @author leeis
+ * @Date 2018/12/29
+ */
+@Data
+public final class GiftCard extends Card implements Serializable {
+
+  private static final long serialVersionUID = -6168739707511792266L;
+
+  /**
+   * 兑换券专用,填写兑换内容的名称。
+   */
+  private String gift;
+
+  @Override
+  public String toString() {
+    return WxMpGsonBuilder.create().toJson(this);
+  }
+
+  public static GiftCard fromJson(String json) {
+    return WxMpGsonBuilder.create().fromJson(json, GiftCard.class);
+  }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GiftCardCreateRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GiftCardCreateRequest.java
new file mode 100644
index 0000000000..8791b70a9d
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GiftCardCreateRequest.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
+import java.io.Serializable;
+
+/**
+ * .
+ * @author leeis
+ * @Date 2018/12/29
+ */
+@Data
+public class GiftCardCreateRequest extends CardCreateRequest implements Serializable {
+  @SerializedName("card_type")
+  private String cardType = "GIFT";
+
+  private GiftCard gift;
+
+  @Override
+  public String toString() {
+    return WxMpGsonBuilder.create().toJson(this);
+  }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GrouponCard.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GrouponCard.java
new file mode 100644
index 0000000000..b0df7262bb
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GrouponCard.java
@@ -0,0 +1,33 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
+import java.io.Serializable;
+
+/**
+ * .
+ * @author leeis
+ * @Date 2018/12/29
+ */
+@Data
+public final class GrouponCard extends Card implements Serializable {
+
+  private static final long serialVersionUID = 3221312561666697005L;
+
+  /**
+   * 团购券专用,团购详情
+   */
+  @SerializedName("deal_detail")
+  private String dealDetail;
+
+  @Override
+  public String toString() {
+    return WxMpGsonBuilder.create().toJson(this);
+  }
+
+  public static GrouponCard fromJson(String json) {
+    return WxMpGsonBuilder.create().fromJson(json, GrouponCard.class);
+  }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GrouponCardCreateRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GrouponCardCreateRequest.java
new file mode 100644
index 0000000000..48b1e3e7da
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GrouponCardCreateRequest.java
@@ -0,0 +1,25 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
+import java.io.Serializable;
+
+/**
+ * .
+ * @author leeis
+ * @Date 2018/12/29
+ */
+@Data
+public class GrouponCardCreateRequest extends CardCreateRequest implements Serializable {
+  @SerializedName("card_type")
+  private String cardType = "GROUPON";
+
+  private GrouponCard groupon;
+
+  @Override
+  public String toString() {
+    return WxMpGsonBuilder.create().toJson(this);
+  }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCreateMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCreateMessage.java
new file mode 100644
index 0000000000..760002cb52
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardCreateMessage.java
@@ -0,0 +1,23 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
+import java.io.Serializable;
+
+@Data
+public final class WxMpCardCreateMessage implements Serializable {
+
+  @SerializedName("card")
+  private CardCreateRequest cardCreateRequest;
+
+  @Override
+  public String toString() {
+    return WxMpGsonBuilder.create().toJson(this);
+  }
+
+  public static WxMpCardCreateMessage fromJson(String json) {
+    return WxMpGsonBuilder.create().fromJson(json, WxMpCardCreateMessage.class);
+  }
+}
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java
index 06945d9a08..5623299394 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java
@@ -2,8 +2,10 @@
 
 import com.google.inject.Inject;
 import me.chanjar.weixin.common.bean.WxCardApiSignature;
+import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.mp.api.WxMpService;
 import me.chanjar.weixin.mp.api.test.ApiTestModule;
+import me.chanjar.weixin.mp.bean.card.*;
 import me.chanjar.weixin.mp.bean.result.WxMpCardResult;
 import org.testng.annotations.*;
 
@@ -100,4 +102,98 @@ public void testUnavailableCardCode() throws Exception {
     assertNotNull(result);
     System.out.println(result);
   }
+
+  @Test
+  public void testCreateGrouponCard() throws WxErrorException {
+
+    BaseInfo base = new BaseInfo();
+    base.setLogoUrl("http://mmbiz.qpic.cn/mmbiz/iaL1LJM1mF9aRKPZJkmG8xXhiaHqkKSVMMWeN3hLut7X7hicFNjakmxibMLGWpXrEXB33367o7zHN0CwngnQY7zb7g/0");
+    base.setBrandName("测试优惠券");
+    base.setCodeType("CODE_TYPE_QRCODE");
+    base.setTitle("测试标题");
+    base.setColor("Color010");
+    base.setNotice("测试Notice");
+    base.setServicePhone("020-88888888");
+    base.setDescription("不可与其他优惠同享\\n如需团购券发票,请在消费时向商户提出\\n店内均可使用,仅限堂食");
+    DateInfo info = new DateInfo();
+    info.setType("DATE_TYPE_FIX_TERM");
+    info.setFixedBeginTerm(0);
+    info.setFixedTerm(30);
+    base.setDateInfo(info);
+    Sku sku = new Sku();
+    sku.setQuantity(100);
+    base.setSku(sku);
+    base.setGetLimit(1);
+    base.setCanShare(true);
+    base.setCanGiveFriend(true);
+    base.setUseAllLocations(true);
+    base.setCenterTitle("顶部居中按钮");
+    base.setCenterSubTitle("按钮下方的wording");
+    base.setCenterUrl("www.qq.com");
+    base.setCustomUrl("http://www.qq.com");
+    base.setCustomUrlName("立即使用");
+    base.setCustomUrlSubTitle("副标题tip");
+    base.setPromotionUrlName("更多优惠");
+    base.setPromotionUrl("http://www.qq.com");
+    base.setLocationIdList("1234");
+
+    //团购券
+    WxMpCardCreateMessage grouponMessage = new WxMpCardCreateMessage();
+    GrouponCardCreateRequest grouponCardCreateRequest = new GrouponCardCreateRequest();
+    GrouponCard grouponCard = new GrouponCard();
+    grouponCard.setBaseInfo(base);
+    grouponCard.setDealDetail("deal detail");
+
+    grouponCardCreateRequest.setGroupon(grouponCard);
+    grouponMessage.setCardCreateRequest(grouponCardCreateRequest);
+
+    System.out.println(this.wxService.getCardService().createCard(grouponMessage));
+
+    //现金券
+    WxMpCardCreateMessage cashMessage = new WxMpCardCreateMessage();
+    CashCardCreateRequest cashCardCreateRequest = new CashCardCreateRequest();
+    CashCard cashCard = new CashCard();
+    cashCard.setBaseInfo(base);
+    cashCard.setLeastCost(1000);
+    cashCard.setReduceCost(100);
+
+    cashCardCreateRequest.setCash(cashCard);
+    cashMessage.setCardCreateRequest(cashCardCreateRequest);
+
+    System.out.println(this.wxService.getCardService().createCard(cashMessage));
+
+    //折扣券
+    WxMpCardCreateMessage discountMessage = new WxMpCardCreateMessage();
+    DiscountCardCreateRequest discountCardCreateRequest = new DiscountCardCreateRequest();
+    DiscountCard discountCard = new DiscountCard();
+    discountCard.setBaseInfo(base);
+    discountCard.setDiscount(30);
+
+    discountCardCreateRequest.setDiscount(discountCard);
+    discountMessage.setCardCreateRequest(discountCardCreateRequest);
+
+    System.out.println(this.wxService.getCardService().createCard(discountMessage));
+
+    //兑换券
+    WxMpCardCreateMessage giftMessage = new WxMpCardCreateMessage();
+    GiftCardCreateRequest giftCardCreateRequest = new GiftCardCreateRequest();
+    GiftCard giftCard = new GiftCard();
+    giftCard.setBaseInfo(base);
+    giftCard.setGift("星巴克雪瑞纳咖啡大杯");
+
+    giftCardCreateRequest.setGift(giftCard);
+    giftMessage.setCardCreateRequest(giftCardCreateRequest);
+    System.out.println(this.wxService.getCardService().createCard(giftMessage));
+
+    //普通兑换券
+    WxMpCardCreateMessage generalMessage = new WxMpCardCreateMessage();
+    GeneralCardCreateRequest generalCardCreateRequest = new GeneralCardCreateRequest();
+    GeneralCard generalCard = new GeneralCard();
+    generalCard.setBaseInfo(base);
+    generalCard.setDefaultDetail("音乐木盒");
+
+    generalCardCreateRequest.setGeneralCoupon(generalCard);
+    generalMessage.setCardCreateRequest(generalCardCreateRequest);
+    System.out.println(this.wxService.getCardService().createCard(generalMessage));
+  }
 }
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java
index 69a3aeba56..0ae803fccf 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java
@@ -4,6 +4,7 @@
 import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.mp.api.WxMpService;
 import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
+import me.chanjar.weixin.open.bean.WxOpenCreateResult;
 import me.chanjar.weixin.open.bean.WxOpenMaCodeTemplate;
 import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage;
 import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult;
@@ -42,6 +43,8 @@ public interface WxOpenComponentService {
 
   String MINIAPP_JSCODE_2_SESSION = "https://api.weixin.qq.com/sns/component/jscode2session?appid=%s&js_code=%s&grant_type=authorization_code&component_appid=%s";
 
+  String CREATE_OPEN_URL= "https://api.weixin.qq.com/cgi-bin/open/create";
+
   WxMpService getWxMpServiceByAppid(String appid);
 
   /**
@@ -168,4 +171,15 @@ public interface WxOpenComponentService {
    * @see #getTemplateList
    */
   void deleteTemplate(long templateId) throws WxErrorException;
+
+  /**
+   * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1498704199_1bcax&token=6df5e3650041eff2cd3ec3662425ad8d7beec8d9&lang=zh_CN
+   * 创建 开放平台帐号并绑定公众号/小程序
+   *
+   * https://api.weixin.qq.com/cgi-bin/open/create
+   *
+   * @param appId 公众号/小程序的appId
+   * @return
+   */
+  WxOpenCreateResult createOpenAccount(String appId) throws WxErrorException;
 }
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java
index 93155690c9..4c2a0ee275 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java
@@ -17,6 +17,7 @@
 import me.chanjar.weixin.open.api.WxOpenService;
 import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken;
 import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken;
+import me.chanjar.weixin.open.bean.WxOpenCreateResult;
 import me.chanjar.weixin.open.bean.WxOpenMaCodeTemplate;
 import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo;
 import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage;
@@ -387,4 +388,14 @@ public void deleteTemplate(long templateId) throws WxErrorException {
     param.addProperty("template_id", templateId);
     post(DELETE_TEMPLATE_URL, param.toString(), "access_token");
   }
+
+  @Override
+  public WxOpenCreateResult createOpenAccount(String appId) throws WxErrorException {
+    JsonObject param = new JsonObject();
+    param.addProperty("appid", appId);
+
+    String json = post(CREATE_OPEN_URL, param.toString(), "access_token");
+
+    return WxOpenCreateResult.fromJson(json);
+  }
 }
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenCreateResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenCreateResult.java
new file mode 100644
index 0000000000..6e06a16d4a
--- /dev/null
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/WxOpenCreateResult.java
@@ -0,0 +1,36 @@
+package me.chanjar.weixin.open.bean;
+
+import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import me.chanjar.weixin.common.util.json.WxGsonBuilder;
+
+import java.io.Serializable;
+
+/**
+ * 
+ * code换取session_key接口的响应
+ * 文档地址:https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html#wxloginobject
+ * 微信返回报文:{"session_key":"nzoqhc3OnwHzeTxJs+inbQ==","openid":"oVBkZ0aYgDMDIywRdgPW8-joxXc4"}
+ * 
+ * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = false) +public class WxOpenCreateResult implements Serializable { + + @SerializedName("open_appid") + private String openAppid; + + @SerializedName("errcode") + private String errcode; + + @SerializedName("errmsg") + private String errmsg; + + public static WxOpenCreateResult fromJson(String json) { + return WxGsonBuilder.create().fromJson(json, WxOpenCreateResult.class); + } + +} From 8c45021d32dc5d425552b60168354ca95ccccc22 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 29 Dec 2018 22:01:04 +0800 Subject: [PATCH 05/81] =?UTF-8?q?=E5=8F=91=E5=B8=833.3.1.B=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- weixin-java-common/pom.xml | 2 +- weixin-java-cp/pom.xml | 2 +- weixin-java-miniapp/pom.xml | 2 +- weixin-java-mp/pom.xml | 2 +- weixin-java-open/pom.xml | 2 +- weixin-java-pay/pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 961b9eab18..8dc48d8325 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.github.binarywang wx-java - 3.3.0 + 3.3.1.B pom WxJava - Weixin/Wechat Java SDK 微信开发Java SDK diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 152c7dabfe..ec968d3afa 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.0 + 3.3.1.B weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index a1808f2d50..e7c02c7c14 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.0 + 3.3.1.B weixin-java-cp diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index 0e0c45e2a6..7c0b2ce85c 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.0 + 3.3.1.B weixin-java-miniapp WxJava - MiniApp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 90cb71c8b3..5c50e83a5b 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.0 + 3.3.1.B weixin-java-mp WxJava - MP diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index 3507ad53c5..b15ef92834 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -8,7 +8,7 @@ com.github.binarywang wx-java - 3.3.0 + 3.3.1.B weixin-java-open WxJava - Open diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index 9f6b3cd71f..bb354af507 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ com.github.binarywang wx-java - 3.3.0 + 3.3.1.B 4.0.0 From 83112620376ca41da2a8f43e9aa0b292d9c28cba Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 3 Jan 2019 19:49:24 +0800 Subject: [PATCH 06/81] =?UTF-8?q?=E8=A7=84=E8=8C=83=E7=B1=BB=E5=91=BD?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{WxCpServiceAbstractImpl.java => BaseWxCpServiceImpl.java} | 2 +- .../weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java | 2 +- .../me/chanjar/weixin/cp/api/impl/WxCpServiceJoddHttpImpl.java | 2 +- .../me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/{WxCpServiceAbstractImpl.java => BaseWxCpServiceImpl.java} (99%) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceAbstractImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java similarity index 99% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceAbstractImpl.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java index f0c15109b9..0000c9529c 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceAbstractImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java @@ -37,7 +37,7 @@ import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; import me.chanjar.weixin.cp.config.WxCpConfigStorage; -public abstract class WxCpServiceAbstractImpl implements WxCpService, RequestHttp { +public abstract class BaseWxCpServiceImpl implements WxCpService, RequestHttp { protected final Logger log = LoggerFactory.getLogger(this.getClass()); private WxCpUserService userService = new WxCpUserServiceImpl(this); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java index 7081272793..cbf570ce59 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java @@ -18,7 +18,7 @@ import java.io.IOException; -public class WxCpServiceApacheHttpClientImpl extends WxCpServiceAbstractImpl { +public class WxCpServiceApacheHttpClientImpl extends BaseWxCpServiceImpl { protected CloseableHttpClient httpClient; protected HttpHost httpProxy; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceJoddHttpImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceJoddHttpImpl.java index 2d7e1b1c29..93da174d5a 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceJoddHttpImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceJoddHttpImpl.java @@ -8,7 +8,7 @@ import me.chanjar.weixin.common.util.http.HttpType; import me.chanjar.weixin.cp.config.WxCpConfigStorage; -public class WxCpServiceJoddHttpImpl extends WxCpServiceAbstractImpl { +public class WxCpServiceJoddHttpImpl extends BaseWxCpServiceImpl { protected HttpConnectionProvider httpClient; protected ProxyInfo httpProxy; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java index 34c978cd4f..47402fb341 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java @@ -11,7 +11,7 @@ import java.io.IOException; -public class WxCpServiceOkHttpImpl extends WxCpServiceAbstractImpl { +public class WxCpServiceOkHttpImpl extends BaseWxCpServiceImpl { protected OkHttpClient httpClient; protected OkHttpProxyInfo httpProxy; From d6923f253733783f662c165d112a5561396557b7 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 3 Jan 2019 20:01:58 +0800 Subject: [PATCH 07/81] =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E8=A7=A3?= =?UTF-8?q?=E5=AF=86=E5=B7=A5=E5=85=B7=E7=B1=BB=E5=A2=9E=E5=8A=A0=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- weixin-java-miniapp/pom.xml | 5 ++ .../wx/miniapp/util/crypt/WxMaCryptUtils.java | 58 ++++++++++++++++--- .../util/crypt/WxMaCryptUtilsTest.java | 35 +++++++++++ 3 files changed, 89 insertions(+), 9 deletions(-) create mode 100644 weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/util/crypt/WxMaCryptUtilsTest.java diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index 7c0b2ce85c..e8a0b9c6e6 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -70,6 +70,11 @@ redis.clients jedis + + org.bouncycastle + bcpkix-jdk15on + 1.59 + org.projectlombok lombok diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/crypt/WxMaCryptUtils.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/crypt/WxMaCryptUtils.java index e05bac5fb7..23ea851b3f 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/crypt/WxMaCryptUtils.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/crypt/WxMaCryptUtils.java @@ -1,19 +1,27 @@ package cn.binarywang.wx.miniapp.util.crypt; -import cn.binarywang.wx.miniapp.config.WxMaConfig; -import me.chanjar.weixin.common.util.crypto.PKCS7Encoder; -import org.apache.commons.codec.binary.Base64; - +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.security.AlgorithmParameters; +import java.security.Key; +import java.security.Security; +import java.util.Arrays; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; -import java.nio.charset.StandardCharsets; -import java.security.AlgorithmParameters; + +import org.apache.commons.codec.binary.Base64; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +import cn.binarywang.wx.miniapp.config.WxMaConfig; +import me.chanjar.weixin.common.util.crypto.PKCS7Encoder; /** * @author Binary Wang */ public class WxMaCryptUtils extends me.chanjar.weixin.common.util.crypto.WxCryptUtil { + private static final Charset UTF_8 = StandardCharsets.UTF_8; + public WxMaCryptUtils(WxMaConfig config) { this.appidOrCorpid = config.getAppid(); this.token = config.getToken(); @@ -21,8 +29,9 @@ public WxMaCryptUtils(WxMaConfig config) { } /** - * AES解密 + * AES解密. * + * @param sessionKey session_key * @param encryptedData 消息密文 * @param ivStr iv字符串 */ @@ -34,9 +43,40 @@ public static String decrypt(String sessionKey, String encryptedData, String ivS Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(Base64.decodeBase64(sessionKey), "AES"), params); - return new String(PKCS7Encoder.decode(cipher.doFinal(Base64.decodeBase64(encryptedData))), StandardCharsets.UTF_8); + return new String(PKCS7Encoder.decode(cipher.doFinal(Base64.decodeBase64(encryptedData))), UTF_8); + } catch (Exception e) { + throw new RuntimeException("AES解密失败!", e); + } + } + + + /** + * AES解密. + * + * @param sessionKey session_key + * @param encryptedData 消息密文 + * @param ivStr iv字符串 + */ + public static String decryptAnotherWay(String sessionKey, String encryptedData, String ivStr) { + byte[] keyBytes = Base64.decodeBase64(sessionKey.getBytes(UTF_8)); + + int base = 16; + if (keyBytes.length % base != 0) { + int groups = keyBytes.length / base + (keyBytes.length % base != 0 ? 1 : 0); + byte[] temp = new byte[groups * base]; + Arrays.fill(temp, (byte) 0); + System.arraycopy(keyBytes, 0, temp, 0, keyBytes.length); + keyBytes = temp; + } + + Security.addProvider(new BouncyCastleProvider()); + Key key = new SecretKeySpec(keyBytes, "AES"); + try { + Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC"); + cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(Base64.decodeBase64(ivStr.getBytes(UTF_8)))); + return new String(cipher.doFinal(Base64.decodeBase64(encryptedData.getBytes(UTF_8))), UTF_8); } catch (Exception e) { - throw new RuntimeException("AES解密失败", e); + throw new RuntimeException("AES解密失败!", e); } } diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/util/crypt/WxMaCryptUtilsTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/util/crypt/WxMaCryptUtilsTest.java new file mode 100644 index 0000000000..76b4e96743 --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/util/crypt/WxMaCryptUtilsTest.java @@ -0,0 +1,35 @@ +package cn.binarywang.wx.miniapp.util.crypt; + + +import org.testng.annotations.*; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + *
+ *
+ * Created by Binary Wang on 2018/12/25.
+ * 
+ * + * @author Binary Wang + */ +public class WxMaCryptUtilsTest { + @Test + public void testDecrypt() { + String sessionKey = "7MG7jbTToVVRWRXVA885rg=="; + String encryptedData = "BY6VOgcWbwGcyrunK0ECWI8rnDsT69DucZ+M78tc1aL9aM/3bEAHFYd4fu7kRjWhD4YfjObw44T9vUqKyHIjbKs6hvtEasZZEIW35x4a91xVgN48ZqZ7MTQqUlP13kDUlkuwYh+/8g8yceu4kNbjowYrhihx+SV7CfjKCveJ7TSepr5Z7aLv1o+rfeelfOwn++WN/YoQsuZ6S3L4fWlWe5DAAUnFUI6cJvxxCohVzbrVXhyH2AqQdSjH2WnMYFeaGFIbcoxMznlk7oEwFn+hBj63dyT/swdYQfEdzuyCBmKXy8d6l1RKVX6Y65coTD8kIlbr+FKsqYrXVUIUBSwehqYuOdhYWZ9Bntl5DWU1oqzAPCnMn2cAIoQpQPKP7IGSxMOvCNAMhVXbE7BvnWuVuGF+AM5tXAa9IVUhcMImGwLQqm4iV5uBd+5OcFObh3A4VJk9iBCBWSkBHa/rV9CVoY0bFv2F9/2Hv82++Ybl274="; + String ivStr = "TarMFjnzHVxy8pdS93wQbw=="; + System.out.println(WxMaCryptUtils.decrypt(sessionKey, encryptedData, ivStr)); +// System.out.println(WxMaCryptUtils.decryptAnotherWay(sessionKey, encryptedData, ivStr)); + } + + @Test + public void testDecryptAnotherWay() { + String encryptedData = "CiyLU1Aw2KjvrjMdj8YKliAjtP4gsMZMQmRzooG2xrDcvSnxIMXFufNstNGTyaGS9uT5geRa0W4oTOb1WT7fJlAC+oNPdbB+3hVbJSRgv+4lGOETKUQz6OYStslQ142dNCuabNPGBzlooOmB231qMM85d2/fV6ChevvXvQP8Hkue1poOFtnEtpyxVLW1zAo6/1Xx1COxFvrc2d7UL/lmHInNlxuacJXwu0fjpXfz/YqYzBIBzD6WUfTIF9GRHpOn/Hz7saL8xz+W//FRAUid1OksQaQx4CMs8LOddcQhULW4ucetDf96JcR3g0gfRK4PC7E/r7Z6xNrXd2UIeorGj5Ef7b1pJAYB6Y5anaHqZ9J6nKEBvB4DnNLIVWSgARns/8wR2SiRS7MNACwTyrGvt9ts8p12PKFdlqYTopNHR1Vf7XjfhQlVsAJdNiKdYmYVoKlaRv85IfVunYzO0IKXsyl7JCUjCpoG20f0a04COwfneQAGGwd5oa+T8yO5hzuyDb/XcxxmK01EpqOyuxINew=="; + String ivStr = "r7BXXKkLb8qrSNn05n0qiA=="; + String sessionKey = "tiihtNczf5v6AKRyjwEUhQ=="; + + assertThat(WxMaCryptUtils.decrypt(sessionKey, encryptedData, ivStr)) + .isEqualTo(WxMaCryptUtils.decryptAnotherWay(sessionKey, encryptedData, ivStr)); + } +} From 8ec61d1328f50e23cd14285a950ca57a088b32b2 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 10 Jan 2019 18:28:55 +0800 Subject: [PATCH 08/81] #903 disable DOCTYPE to fix XXE Vulnerability --- .../me/chanjar/weixin/common/util/crypto/WxCryptUtil.java | 1 + .../me/chanjar/weixin/common/util/crypto/WxCryptUtilTest.java | 3 +++ .../github/binarywang/wxpay/bean/result/BaseWxPayResult.java | 1 + .../binarywang/wxpay/bean/result/BaseWxPayResultTest.java | 4 +++- 4 files changed, 8 insertions(+), 1 deletion(-) diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java index cded0c9846..8124148110 100755 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java @@ -39,6 +39,7 @@ protected DocumentBuilder initialValue() { try { final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setExpandEntityReferences(false); + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); return factory.newDocumentBuilder(); } catch (ParserConfigurationException exc) { throw new IllegalArgumentException(exc); diff --git a/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/crypto/WxCryptUtilTest.java b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/crypto/WxCryptUtilTest.java index 06f9d7ba28..82cfa9d2d6 100755 --- a/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/crypto/WxCryptUtilTest.java +++ b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/crypto/WxCryptUtilTest.java @@ -40,6 +40,7 @@ public void testNormal() throws ParserConfigurationException, SAXException, IOEx DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); documentBuilderFactory.setExpandEntityReferences(false); + documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); Document document = documentBuilder.parse(new InputSource(new StringReader(encryptedXml))); @@ -83,6 +84,8 @@ public void testValidateSignatureError() throws ParserConfigurationException, SA String afterEncrpt = pc.encrypt(this.replyMsg); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); dbf.setExpandEntityReferences(false); + dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + DocumentBuilder db = dbf.newDocumentBuilder(); StringReader sr = new StringReader(afterEncrpt); InputSource is = new InputSource(sr); diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResult.java index b0233ded4d..5a1ea64e83 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResult.java @@ -189,6 +189,7 @@ private Document getXmlDoc() { try { final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setExpandEntityReferences(false); + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); this.xmlDoc = factory.newDocumentBuilder() .parse(new ByteArrayInputStream(this.xmlString.getBytes(StandardCharsets.UTF_8))); return xmlDoc; diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResultTest.java index 83fcc5f365..6b70d5542f 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResultTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/BaseWxPayResultTest.java @@ -75,7 +75,9 @@ public void testToMap() throws Exception { @Test(expectedExceptions = {RuntimeException.class}) public void testToMap_with_empty_xmlString() { WxPayOrderQueryResult result = new WxPayOrderQueryResult(); - result.setXmlString(" "); + result.setXmlString( "]" + + ">&win;"); Map map = result.toMap(); System.out.println(map); } From 2d424040afceab5308844256d1fce4431f4ba71c Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 10 Jan 2019 19:39:30 +0800 Subject: [PATCH 09/81] =?UTF-8?q?#894=20=E5=AE=8C=E5=96=84=E5=8D=A1?= =?UTF-8?q?=E5=88=B8=E6=9F=A5=E8=AF=A2Code=E6=8E=A5=E5=8F=A3=E7=BC=BA?= =?UTF-8?q?=E5=B0=91=E7=9A=84=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/mp/api/WxMpCardService.java | 6 +++--- .../mp/api/impl/WxMpCardServiceImpl.java | 16 ++++++--------- .../weixin/mp/bean/card/GrouponCard.java | 6 ++++-- .../weixin/mp/bean/{ => card}/WxMpCard.java | 8 ++++++-- .../bean/{result => card}/WxMpCardResult.java | 9 +++++++-- .../mp/util/json/WxMpCardGsonAdapter.java | 17 ++++++++++++---- .../util/json/WxMpCardResultGsonAdapter.java | 18 ++++++++++++----- .../weixin/mp/util/json/WxMpGsonBuilder.java | 2 ++ .../mp/api/impl/WxMpCardServiceImplTest.java | 20 ++++++++++++++++--- 9 files changed, 71 insertions(+), 31 deletions(-) rename weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/{ => card}/WxMpCard.java (80%) rename weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/{result => card}/WxMpCardResult.java (82%) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java index d0f06c13b8..c86b3d19fd 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java @@ -3,7 +3,7 @@ import me.chanjar.weixin.common.bean.WxCardApiSignature; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.bean.card.*; -import me.chanjar.weixin.mp.bean.result.WxMpCardResult; +import me.chanjar.weixin.mp.bean.card.WxMpCardResult; /** * 卡券相关接口 @@ -80,8 +80,8 @@ WxCardApiSignature createCardApiSignature(String... optionalSignParam) throws String decryptCardCode(String encryptCode) throws WxErrorException; /** - * 卡券Code查询 - * + * 卡券Code查询. + * 文档地址: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1451025272&anchor=1 * @param cardId 卡券ID代表一类卡券 * @param code 单张卡券的唯一标准 * @param checkConsume 是否校验code核销状态,填入true和false时的code异常状态返回数据不同 diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java index 5237fd6d2a..6717eb91b5 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java @@ -3,7 +3,6 @@ import java.util.Arrays; import java.util.concurrent.locks.Lock; -import me.chanjar.weixin.mp.bean.card.*; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,7 +22,12 @@ import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; import me.chanjar.weixin.mp.api.WxMpCardService; import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.result.WxMpCardResult; +import me.chanjar.weixin.mp.bean.card.WxMpCardCreateMessage; +import me.chanjar.weixin.mp.bean.card.WxMpCardCreateResult; +import me.chanjar.weixin.mp.bean.card.WxMpCardLandingPageCreateRequest; +import me.chanjar.weixin.mp.bean.card.WxMpCardLandingPageCreateResult; +import me.chanjar.weixin.mp.bean.card.WxMpCardQrcodeCreateResult; +import me.chanjar.weixin.mp.bean.card.WxMpCardResult; import me.chanjar.weixin.mp.enums.TicketType; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; @@ -148,14 +152,6 @@ public String decryptCardCode(String encryptCode) throws WxErrorException { return jsonPrimitive.getAsString(); } - /** - * 卡券Code查询. - * - * @param cardId 卡券ID代表一类卡券 - * @param code 单张卡券的唯一标准 - * @param checkConsume 是否校验code核销状态,填入true和false时的code异常状态返回数据不同 - * @return WxMpCardResult对象 - */ @Override public WxMpCardResult queryCardCode(String cardId, String code, boolean checkConsume) throws WxErrorException { JsonObject param = new JsonObject(); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GrouponCard.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GrouponCard.java index b0df7262bb..ba343a435b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GrouponCard.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GrouponCard.java @@ -1,17 +1,19 @@ package me.chanjar.weixin.mp.bean.card; +import java.io.Serializable; + import com.google.gson.annotations.SerializedName; import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; -import java.io.Serializable; - /** * . * @author leeis * @Date 2018/12/29 */ @Data +@EqualsAndHashCode(callSuper = false) public final class GrouponCard extends Card implements Serializable { private static final long serialVersionUID = 3221312561666697005L; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpCard.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCard.java similarity index 80% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpCard.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCard.java index 71e419a764..17314c90f6 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpCard.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCard.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.mp.bean; +package me.chanjar.weixin.mp.bean.card; import java.io.Serializable; @@ -24,7 +24,11 @@ public class WxMpCard implements Serializable { private String userCardStatus; - private Boolean canConsume; + private String membershipNumber; + + private String code; + + private Integer bonus; @Override public String toString() { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpCardResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardResult.java similarity index 82% rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpCardResult.java rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardResult.java index c6acc08007..9343cb40b5 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpCardResult.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardResult.java @@ -1,9 +1,8 @@ -package me.chanjar.weixin.mp.bean.result; +package me.chanjar.weixin.mp.bean.card; import java.io.Serializable; import lombok.Data; -import me.chanjar.weixin.mp.bean.WxMpCard; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; /** @@ -28,6 +27,12 @@ public class WxMpCardResult implements Serializable { private Boolean canConsume; + private String outStr; + + private String backgroundPicUrl; + + private String unionid; + @Override public String toString() { return WxMpGsonBuilder.create().toJson(this); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpCardGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpCardGsonAdapter.java index 022a59f111..872bf8c757 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpCardGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpCardGsonAdapter.java @@ -1,11 +1,15 @@ package me.chanjar.weixin.mp.util.json; -import com.google.gson.*; -import me.chanjar.weixin.common.util.json.GsonHelper; -import me.chanjar.weixin.mp.bean.WxMpCard; - import java.lang.reflect.Type; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.mp.bean.card.WxMpCard; + /** * Created by YuJian on 15/11/11. * @@ -18,11 +22,16 @@ public class WxMpCardGsonAdapter implements JsonDeserializer { public WxMpCard deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { WxMpCard card = new WxMpCard(); + JsonObject jsonObject = jsonElement.getAsJsonObject(); card.setCardId(GsonHelper.getString(jsonObject, "card_id")); card.setBeginTime(GsonHelper.getLong(jsonObject, "begin_time")); card.setEndTime(GsonHelper.getLong(jsonObject, "end_time")); + card.setUserCardStatus(GsonHelper.getString(jsonObject, "user_card_status")); + card.setMembershipNumber(GsonHelper.getString(jsonObject, "membership_number")); + card.setCode(GsonHelper.getString(jsonObject, "code")); + card.setBonus(GsonHelper.getInteger(jsonObject, "bonus")); return card; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpCardResultGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpCardResultGsonAdapter.java index 7e476acbe0..defe8822bb 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpCardResultGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpCardResultGsonAdapter.java @@ -1,12 +1,16 @@ package me.chanjar.weixin.mp.util.json; -import com.google.gson.*; +import java.lang.reflect.Type; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; import com.google.gson.reflect.TypeToken; import me.chanjar.weixin.common.util.json.GsonHelper; -import me.chanjar.weixin.mp.bean.WxMpCard; -import me.chanjar.weixin.mp.bean.result.WxMpCardResult; - -import java.lang.reflect.Type; +import me.chanjar.weixin.mp.bean.card.WxMpCard; +import me.chanjar.weixin.mp.bean.card.WxMpCardResult; /** * Created by YuJian on 15/11/11. @@ -18,6 +22,7 @@ public class WxMpCardResultGsonAdapter implements JsonDeserializer() { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java index a4357e9117..e6a60c34b0 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java @@ -3,6 +3,8 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import me.chanjar.weixin.mp.bean.*; +import me.chanjar.weixin.mp.bean.card.WxMpCard; +import me.chanjar.weixin.mp.bean.card.WxMpCardResult; import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserCumulate; import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserSummary; import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java index 5623299394..336d11b752 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java @@ -1,13 +1,27 @@ package me.chanjar.weixin.mp.api.impl; +import org.testng.annotations.*; + import com.google.inject.Inject; import me.chanjar.weixin.common.bean.WxCardApiSignature; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.test.ApiTestModule; -import me.chanjar.weixin.mp.bean.card.*; -import me.chanjar.weixin.mp.bean.result.WxMpCardResult; -import org.testng.annotations.*; +import me.chanjar.weixin.mp.bean.card.BaseInfo; +import me.chanjar.weixin.mp.bean.card.CashCard; +import me.chanjar.weixin.mp.bean.card.CashCardCreateRequest; +import me.chanjar.weixin.mp.bean.card.DateInfo; +import me.chanjar.weixin.mp.bean.card.DiscountCard; +import me.chanjar.weixin.mp.bean.card.DiscountCardCreateRequest; +import me.chanjar.weixin.mp.bean.card.GeneralCard; +import me.chanjar.weixin.mp.bean.card.GeneralCardCreateRequest; +import me.chanjar.weixin.mp.bean.card.GiftCard; +import me.chanjar.weixin.mp.bean.card.GiftCardCreateRequest; +import me.chanjar.weixin.mp.bean.card.GrouponCard; +import me.chanjar.weixin.mp.bean.card.GrouponCardCreateRequest; +import me.chanjar.weixin.mp.bean.card.Sku; +import me.chanjar.weixin.mp.bean.card.WxMpCardCreateMessage; +import me.chanjar.weixin.mp.bean.card.WxMpCardResult; import static org.testng.AssertJUnit.*; From 333a840d00b758871032570b95ee9ab5183fecbc Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Fri, 11 Jan 2019 21:02:36 +0800 Subject: [PATCH 10/81] =?UTF-8?q?#912=20=E4=BF=AE=E5=A4=8DAPP=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E5=9C=A8=E6=9C=8D=E5=8A=A1=E5=95=86=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E4=B8=8B=E7=9A=84=E4=BA=8C=E6=AC=A1=E7=AD=BE=E5=90=8D=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wxpay/service/impl/BaseWxPayServiceImpl.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java index ec57e745f9..616bf9a579 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java @@ -326,11 +326,9 @@ public T createOrder(WxPayUnifiedOrderRequest request) throws WxPayException Map configMap = new HashMap<>(8); // 此map用于参与调起sdk支付的二次签名,格式全小写,timestamp只能是10位,格式固定,切勿修改 - String partnerId; - if (StringUtils.isEmpty(request.getMchId())) { - partnerId = this.getConfig().getMchId(); - } else { - partnerId = request.getMchId(); + String partnerId = unifiedOrderResult.getMchId(); + if (StringUtils.isNotEmpty(unifiedOrderResult.getSubMchId())) { + partnerId = unifiedOrderResult.getSubMchId(); } configMap.put("prepayid", prepayId); From f7f7f9dd3c2873f40fa1eef434ed09f592c1d1b5 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 12 Jan 2019 19:52:44 +0800 Subject: [PATCH 11/81] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/mp/api/WxMpAiOpenService.java | 32 +++---------------- .../mp/api/impl/WxMpAiOpenServiceImpl.java | 31 ++++++++---------- .../api/impl/WxMpAiOpenServiceImplTest.java | 17 +++++----- 3 files changed, 28 insertions(+), 52 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpAiOpenService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpAiOpenService.java index 74b905d683..c57ad9d0f5 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpAiOpenService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpAiOpenService.java @@ -1,10 +1,10 @@ package me.chanjar.weixin.mp.api; +import java.io.File; + import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.enums.AiLangType; -import java.io.File; - /** *
  * 微信AI开放接口(语音识别,微信翻译).
@@ -15,24 +15,15 @@
  * @author Binary Wang
  */
 public interface WxMpAiOpenService {
+  String TRANSLATE_URL = "http://api.weixin.qq.com/cgi-bin/media/voice/translatecontent?lfrom=%s<o=%s";
   String VOICE_UPLOAD_URL = "http://api.weixin.qq.com/cgi-bin/media/voice/addvoicetorecofortext?format=%s&voice_id=%s&lang=%s";
   String VOICE_QUERY_RESULT_URL = "http://api.weixin.qq.com/cgi-bin/media/voice/queryrecoresultfortext";
 
   /**
    * 
    * 提交语音.
-   * 接口调用请求说明
-   *
    * http请求方式: POST
    * http://api.weixin.qq.com/cgi-bin/media/voice/addvoicetorecofortext?access_token=ACCESS_TOKEN&format=&voice_id=xxxxxx&lang=zh_CN
-   * 参数说明
-   *
-   * 参数	是否必须	说明
-   * access_token	是	接口调用凭证
-   * format	是	文件格式 (只支持mp3,16k,单声道,最大1M)
-   * voice_id	是	语音唯一标识
-   * lang	否	语言,zh_CN 或 en_US,默认中文
-   * 语音内容放body里或者上传文件的形式
    * 
* * @param lang 语言,zh_CN 或 en_US,默认中文 @@ -46,16 +37,9 @@ public interface WxMpAiOpenService { * 获取语音识别结果. * 接口调用请求说明 * - * http请求方式: POST * http://api.weixin.qq.com/cgi-bin/media/voice/queryrecoresultfortext?access_token=ACCESS_TOKEN&voice_id=xxxxxx&lang=zh_CN * 请注意,添加完文件之后10s内调用这个接口 * - * 参数说明 - * - * 参数 是否必须 说明 - * access_token 是 接口调用凭证 - * voice_id 是 语音唯一标识 - * lang 否 语言,zh_CN 或 en_US,默认中文 *
* * @param lang 语言,zh_CN 或 en_US,默认中文 @@ -80,18 +64,12 @@ public interface WxMpAiOpenService { * * http请求方式: POST * http://api.weixin.qq.com/cgi-bin/media/voice/translatecontent?access_token=ACCESS_TOKEN&lfrom=xxx<o=xxx - * 参数说明 * - * 参数 是否必须 说明 - * access_token 是 接口调用凭证 - * lfrom 是 源语言,zh_CN 或 en_US - * lto 是 目标语言,zh_CN 或 en_US - * 源内容放body里或者上传文件的形式(utf8格式,最大600Byte) *
* * @param langFrom 源语言,zh_CN 或 en_US - * @param langTo 目标语言,zh_CN 或 en_US - * @param content 要翻译的文本内容 + * @param langTo 目标语言,zh_CN 或 en_US + * @param content 要翻译的文本内容 */ String translate(AiLangType langFrom, AiLangType langTo, String content) throws WxErrorException; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImpl.java index b97da0a8a2..628b6c55f8 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImpl.java @@ -1,17 +1,16 @@ package me.chanjar.weixin.mp.api.impl; -import com.google.gson.JsonObject; +import java.io.File; + import com.google.gson.JsonParser; import me.chanjar.weixin.common.WxType; import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.error.WxErrorException; -import me.chanjar.weixin.mp.enums.AiLangType; import me.chanjar.weixin.mp.api.WxMpAiOpenService; import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.enums.AiLangType; import me.chanjar.weixin.mp.util.requestexecuter.voice.VoiceUploadRequestExecutor; -import java.io.File; - /** *
  *  Created by BinaryWang on 2018/6/9.
@@ -20,9 +19,7 @@
  * @author Binary Wang
  */
 public class WxMpAiOpenServiceImpl implements WxMpAiOpenService {
-
   private static final JsonParser JSON_PARSER = new JsonParser();
-  public static final String TRANSLATE_URL = "http://api.weixin.qq.com/cgi-bin/media/voice/translatecontent?lfrom=%s<o=%s";
   private WxMpService wxMpService;
 
   public WxMpAiOpenServiceImpl(WxMpService wxMpService) {
@@ -48,14 +45,14 @@ public String recogniseVoice(String voiceId, AiLangType lang, File voiceFile) th
 
   @Override
   public String translate(AiLangType langFrom, AiLangType langTo, String content) throws WxErrorException {
-    final String responseContent = this.wxMpService.post(String.format(TRANSLATE_URL, langFrom.getCode(), langTo.getCode()),
-      content);
-    final JsonObject jsonObject = new JsonParser().parse(responseContent).getAsJsonObject();
-    if (jsonObject.get("errcode") == null || jsonObject.get("errcode").getAsInt() == 0) {
-      return jsonObject.get("to_content").getAsString();
+    String response = this.wxMpService.post(String.format(TRANSLATE_URL, langFrom.getCode(), langTo.getCode()), content);
+
+    WxError error = WxError.fromJson(response, WxType.MP);
+    if (error.getErrorCode() != 0) {
+      throw new WxErrorException(error);
     }
 
-    throw new WxErrorException(WxError.fromJson(responseContent, WxType.MP));
+    return JSON_PARSER.parse(response).getAsJsonObject().get("to_content").getAsString();
   }
 
   @Override
@@ -64,13 +61,13 @@ public String queryRecognitionResult(String voiceId, AiLangType lang) throws WxE
       lang = AiLangType.zh_CN;
     }
 
-    final String responseContent = this.wxMpService.get(VOICE_QUERY_RESULT_URL,
+    final String response = this.wxMpService.get(VOICE_QUERY_RESULT_URL,
       String.format("voice_id=%s&lang=%s", voiceId, lang.getCode()));
-    final JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject();
-    if (jsonObject.get("errcode") == null || jsonObject.get("errcode").getAsInt() == 0) {
-      return jsonObject.get("result").getAsString();
+    WxError error = WxError.fromJson(response, WxType.MP);
+    if (error.getErrorCode() != 0) {
+      throw new WxErrorException(error);
     }
 
-    throw new WxErrorException(WxError.fromJson(responseContent, WxType.MP));
+    return JSON_PARSER.parse(response).getAsJsonObject().get("result").getAsString();
   }
 }
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImplTest.java
index 1e61c1faa8..9cf770ac5c 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImplTest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpAiOpenServiceImplTest.java
@@ -1,14 +1,16 @@
 package me.chanjar.weixin.mp.api.impl;
 
+import java.io.File;
+
+import org.testng.annotations.*;
+
 import com.google.inject.Inject;
 import me.chanjar.weixin.common.error.WxErrorException;
-import me.chanjar.weixin.mp.enums.AiLangType;
 import me.chanjar.weixin.mp.api.WxMpService;
 import me.chanjar.weixin.mp.api.test.ApiTestModule;
-import org.testng.annotations.Guice;
-import org.testng.annotations.Test;
+import me.chanjar.weixin.mp.enums.AiLangType;
 
-import java.io.File;
+import static org.assertj.core.api.Assertions.assertThat;
 
 /**
  * 
@@ -35,13 +37,12 @@ public void testRecogniseVoice() throws WxErrorException {
     String voiceId = System.currentTimeMillis() + "a";
     AiLangType lang = AiLangType.zh_CN;
     final String result = this.wxService.getAiOpenService().recogniseVoice(voiceId, lang, new File("d:\\t.mp3"));
-    System.out.println(result);
+    assertThat(result).isNotEmpty();
   }
 
   @Test
   public void testTranslate() throws WxErrorException {
-    final String responseContent = this.wxService.getAiOpenService()
-      .translate(AiLangType.zh_CN, AiLangType.en_US, "微信文档很坑爹");
-    System.out.println(responseContent);
+    final String result = this.wxService.getAiOpenService().translate(AiLangType.zh_CN, AiLangType.en_US, "微信文档很坑爹");
+    assertThat(result).isNotEmpty();
   }
 }

From 0eccfb6a822b5788b3e0f1aa95fcc8ea2b3a3fe7 Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sat, 12 Jan 2019 19:53:11 +0800
Subject: [PATCH 12/81] =?UTF-8?q?#895=20=E5=B0=8F=E7=A8=8B=E5=BA=8F?=
 =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=94=A8=E6=88=B7=E6=94=AF=E4=BB=98=E5=AE=8C?=
 =?UTF-8?q?=E8=8E=B7=E5=8F=96UnionId=E7=9A=84=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../wx/miniapp/api/WxMaService.java           | 23 ++++++++++++
 .../wx/miniapp/api/impl/WxMaServiceImpl.java  | 35 +++++++++++++++++--
 .../miniapp/api/impl/WxMaServiceImplTest.java |  8 +++--
 3 files changed, 62 insertions(+), 4 deletions(-)

diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java
index efa53939a8..578acc56af 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaService.java
@@ -17,6 +17,10 @@ public interface WxMaService {
   String GET_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
 
   String JSCODE_TO_SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session";
+  /**
+   * getPaidUnionId
+   */
+  String GET_PAID_UNION_ID_URL = "https://api.weixin.qq.com/wxa/getpaidunionid";
 
   /**
    * 获取登录后的session信息.
@@ -56,6 +60,22 @@ public interface WxMaService {
    */
   String getAccessToken(boolean forceRefresh) throws WxErrorException;
 
+  /**
+   * 
+   * 用户支付完成后,获取该用户的 UnionId,无需用户授权。本接口支持第三方平台代理查询。
+   *
+   * 注意:调用前需要用户完成支付,且在支付后的五分钟内有效。
+   * 请求地址: GET https://api.weixin.qq.com/wxa/getpaidunionid?access_token=ACCESS_TOKEN&openid=OPENID
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/api/getPaidUnionId.html
+   * 
+ * + * @param openid 必填 支付用户唯一标识 + * @param transactionId 非必填 微信支付订单号 + * @param mchId 非必填 微信支付分配的商户号,和商户订单号配合使用 + * @param outTradeNo 非必填 微信支付商户订单号,和商户号配合使用 + */ + String getPaidUnionId(String openid, String transactionId, String mchId, String outTradeNo) throws WxErrorException; + /** * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求. */ @@ -168,18 +188,21 @@ public interface WxMaService { /** * 返回分享相关查询服务. + * * @return WxMaShareService */ WxMaShareService getShareService(); /** * 返回微信运动相关接口服务对象. + * * @return WxMaShareService */ WxMaRunService getRunService(); /** * 返回内容安全相关接口服务对象. + * * @return WxMaShareService */ WxMaSecCheckService getSecCheckService(); diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java index 280a052e4a..a12fa1fea1 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java @@ -5,6 +5,7 @@ import java.util.Map; import java.util.concurrent.locks.Lock; +import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; @@ -29,7 +30,9 @@ import cn.binarywang.wx.miniapp.config.WxMaConfig; import com.google.common.base.Joiner; import com.google.gson.Gson; +import com.google.gson.JsonParser; import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.WxType; import me.chanjar.weixin.common.bean.WxAccessToken; import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.error.WxErrorException; @@ -50,6 +53,7 @@ */ @Slf4j public class WxMaServiceImpl implements WxMaService, RequestHttp { + private static final JsonParser JSON_PARSER = new JsonParser(); private CloseableHttpClient httpClient; private HttpHost httpProxy; private WxMaConfig wxMaConfig; @@ -150,6 +154,33 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException { return this.getWxMaConfig().getAccessToken(); } + @Override + public String getPaidUnionId(String openid, String transactionId, String mchId, String outTradeNo) + throws WxErrorException { + Map params = new HashMap<>(8); + params.put("openid", openid); + + if (StringUtils.isNotEmpty(transactionId)) { + params.put("transaction_id", transactionId); + } + + if (StringUtils.isNotEmpty(mchId)) { + params.put("mch_id", mchId); + } + + if (StringUtils.isNotEmpty(outTradeNo)) { + params.put("out_trade_no", outTradeNo); + } + + String responseContent = this.get(GET_PAID_UNION_ID_URL, Joiner.on("&").withKeyValueSeparator("=").join(params)); + WxError error = WxError.fromJson(responseContent, WxType.MiniApp); + if (error.getErrorCode() != 0) { + throw new WxErrorException(error); + } + + return JSON_PARSER.parse(responseContent).getAsJsonObject().get("unionid").getAsString(); + } + @Override public WxMaJscode2SessionResult jsCode2SessionInfo(String jsCode) throws WxErrorException { final WxMaConfig config = getWxMaConfig(); @@ -168,7 +199,7 @@ public boolean checkSignature(String timestamp, String nonce, String signature) try { return SHA1.gen(this.getWxMaConfig().getToken(), timestamp, nonce).equals(signature); } catch (Exception e) { - this.log.error("Checking signature failed, and the reason is :" + e.getMessage()); + log.error("Checking signature failed, and the reason is :" + e.getMessage()); return false; } } @@ -246,7 +277,7 @@ private T executeInternal(RequestExecutor executor, String uri, E d if (error.getErrorCode() == ERR_40001 || error.getErrorCode() == ERR_42001 || error.getErrorCode() == ERR_40014) { - // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token + // 强制设置WxMaConfig的access token过期了,这样在下一次请求里就会刷新access token this.getWxMaConfig().expireAccessToken(); if (this.getWxMaConfig().autoRefreshToken()) { return this.execute(executor, uri, data); diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImplTest.java index 1f87c7e4ee..85fb2f9850 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImplTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImplTest.java @@ -1,7 +1,5 @@ package cn.binarywang.wx.miniapp.api.impl; -import java.io.File; - import org.apache.commons.lang3.StringUtils; import org.testng.annotations.*; @@ -11,6 +9,7 @@ import com.google.inject.Inject; import me.chanjar.weixin.common.error.WxErrorException; +import static org.assertj.core.api.Assertions.assertThat; import static org.testng.Assert.*; /** @@ -33,4 +32,9 @@ public void testRefreshAccessToken() throws WxErrorException { assertTrue(StringUtils.isNotBlank(after)); } + @Test(expectedExceptions = {WxErrorException.class}) + public void testGetPaidUnionId() throws WxErrorException { + final String unionId = this.wxService.getPaidUnionId("1", null, "3", "4"); + assertThat(unionId).isNotEmpty(); + } } From 3225311b0930bcca3fb8fc546be6c951d51cb034 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 12 Jan 2019 20:54:52 +0800 Subject: [PATCH 13/81] =?UTF-8?q?=E5=8F=91=E5=B8=833.3.2.B=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- weixin-java-common/pom.xml | 2 +- weixin-java-cp/pom.xml | 2 +- weixin-java-miniapp/pom.xml | 2 +- weixin-java-mp/pom.xml | 2 +- weixin-java-open/pom.xml | 2 +- weixin-java-pay/pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 8dc48d8325..99d4288ca0 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.github.binarywang wx-java - 3.3.1.B + 3.3.2.B pom WxJava - Weixin/Wechat Java SDK 微信开发Java SDK diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index ec968d3afa..654c2b6a8c 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.1.B + 3.3.2.B weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index e7c02c7c14..245c2197e5 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.1.B + 3.3.2.B weixin-java-cp diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index e8a0b9c6e6..68530324b2 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.1.B + 3.3.2.B weixin-java-miniapp WxJava - MiniApp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 5c50e83a5b..79783a560f 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.1.B + 3.3.2.B weixin-java-mp WxJava - MP diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index b15ef92834..437aef4d9f 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -8,7 +8,7 @@ com.github.binarywang wx-java - 3.3.1.B + 3.3.2.B weixin-java-open WxJava - Open diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index bb354af507..1d401fde51 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ com.github.binarywang wx-java - 3.3.1.B + 3.3.2.B 4.0.0 From 568706f1553a881fbf35b70d8b8002bfdc6a43f8 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 20 Jan 2019 13:44:32 +0800 Subject: [PATCH 14/81] =?UTF-8?q?#921=20=E4=BC=81=E4=B8=9A=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E5=8F=91=E9=80=81=E5=BA=94=E7=94=A8=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=94=AF=E6=8C=81Markdown=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- weixin-java-common/pom.xml | 2 +- .../chanjar/weixin/common/api/WxConsts.java | 5 +++ weixin-java-cp/pom.xml | 2 +- .../cp/api/impl/BaseWxCpServiceImpl.java | 6 ++-- .../chanjar/weixin/cp/bean/WxCpMessage.java | 9 +++++ .../messagebuilder/MarkdownMsgBuilder.java | 32 ++++++++++++++++++ .../cp/util/json/WxCpMessageGsonAdapter.java | 20 ++++++++--- .../weixin/cp/api/WxCpMessageAPITest.java | 33 +++++++++++++++++-- weixin-java-miniapp/pom.xml | 5 +-- weixin-java-mp/pom.xml | 3 +- weixin-java-open/pom.xml | 7 ++-- weixin-java-pay/pom.xml | 2 +- 12 files changed, 108 insertions(+), 18 deletions(-) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MarkdownMsgBuilder.java diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 654c2b6a8c..7a51af4b96 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -11,7 +11,7 @@ weixin-java-common - WxJava - Common + WxJava - Common Java SDK 微信开发Java SDK公共模块 diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java index c4bac2a83c..557d1fc10e 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java @@ -62,6 +62,11 @@ public static class KefuMsgType { * 图文消息(点击跳转到图文消息页面). */ public static final String MPNEWS = "mpnews"; + /** + * markdown消息. + * (目前仅支持markdown语法的子集,微工作台(原企业号)不支持展示markdown消息) + */ + public static final String MARKDOWN = "markdown"; /** * 发送文件(CP专用). */ diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 245c2197e5..3d9cf9a8f7 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -11,7 +11,7 @@ weixin-java-cp - WxJava - CP + WxJava - CP Java SDK 微信企业号/企业微信 Java SDK diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java index 0000c9529c..89aeb4863e 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java @@ -10,7 +10,6 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; - import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.error.WxError; import me.chanjar.weixin.common.error.WxErrorException; @@ -141,9 +140,10 @@ public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException public WxCpMessageSendResult messageSend(WxCpMessage message) throws WxErrorException { String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send"; Integer agentId = message.getAgentId(); - if(null == agentId){ + if (null == agentId) { message.setAgentId(this.getWxCpConfigStorage().getAgentId()); } + return WxCpMessageSendResult.fromJson(this.post(url, message.toJson())); } @@ -171,7 +171,7 @@ public String post(String url, String postData) throws WxErrorException { } /** - * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 + * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求. */ @Override public T execute(RequestExecutor executor, String uri, E data) throws WxErrorException { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java index d28c178c35..cd455d88ce 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java @@ -10,6 +10,7 @@ import me.chanjar.weixin.cp.bean.article.NewArticle; import me.chanjar.weixin.cp.bean.messagebuilder.FileBuilder; import me.chanjar.weixin.cp.bean.messagebuilder.ImageBuilder; +import me.chanjar.weixin.cp.bean.messagebuilder.MarkdownMsgBuilder; import me.chanjar.weixin.cp.bean.messagebuilder.MpnewsBuilder; import me.chanjar.weixin.cp.bean.messagebuilder.NewsBuilder; import me.chanjar.weixin.cp.bean.messagebuilder.TextBuilder; @@ -94,6 +95,13 @@ public static MpnewsBuilder MPNEWS() { return new MpnewsBuilder(); } + /** + * 获得markdown消息builder. + */ + public static MarkdownMsgBuilder MARKDOWN() { + return new MarkdownMsgBuilder(); + } + /** * 获得文件消息builder. */ @@ -112,6 +120,7 @@ public static FileBuilder FILE() { * {@link WxConsts.KefuMsgType#VIDEO} * {@link WxConsts.KefuMsgType#NEWS} * {@link WxConsts.KefuMsgType#MPNEWS} + * {@link WxConsts.KefuMsgType#MARKDOWN} *
* * @param msgType 消息类型 diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MarkdownMsgBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MarkdownMsgBuilder.java new file mode 100644 index 0000000000..6e0a4a3302 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MarkdownMsgBuilder.java @@ -0,0 +1,32 @@ +package me.chanjar.weixin.cp.bean.messagebuilder; + +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.cp.bean.WxCpMessage; + +/** + *
+ * markdown类型的消息builder
+ * Created by Binary Wang on 2019/1/20.
+ * 
+ * + * @author Binary Wang + */ +public class MarkdownMsgBuilder extends BaseBuilder { + private String content; + + public MarkdownMsgBuilder() { + this.msgType = WxConsts.KefuMsgType.MARKDOWN; + } + + public MarkdownMsgBuilder content(String content) { + this.content = content; + return this; + } + + @Override + public WxCpMessage build() { + WxCpMessage m = super.build(); + m.setContent(this.content); + return m; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java index 7bed435d30..fbf70bb581 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java @@ -8,14 +8,19 @@ */ package me.chanjar.weixin.cp.util.json; -import com.google.gson.*; +import java.lang.reflect.Type; + +import org.apache.commons.lang3.StringUtils; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.cp.bean.WxCpMessage; import me.chanjar.weixin.cp.bean.article.MpnewsArticle; import me.chanjar.weixin.cp.bean.article.NewArticle; -import org.apache.commons.lang3.StringUtils; - -import java.lang.reflect.Type; /** * @author Daniel Qian @@ -37,12 +42,19 @@ public JsonElement serialize(WxCpMessage message, Type typeOfSrc, JsonSerializat if (StringUtils.isNotBlank(message.getToTag())) { messageJson.addProperty("totag", message.getToTag()); } + if (WxConsts.KefuMsgType.TEXT.equals(message.getMsgType())) { JsonObject text = new JsonObject(); text.addProperty("content", message.getContent()); messageJson.add("text", text); } + if (WxConsts.KefuMsgType.MARKDOWN.equals(message.getMsgType())) { + JsonObject text = new JsonObject(); + text.addProperty("content", message.getContent()); + messageJson.add("markdown", text); + } + if (WxConsts.KefuMsgType.TEXTCARD.equals(message.getMsgType())) { JsonObject text = new JsonObject(); text.addProperty("title", message.getTitle()); diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java index 640bbad17d..370f33f801 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java @@ -1,11 +1,12 @@ package me.chanjar.weixin.cp.api; +import org.testng.annotations.*; + import com.google.inject.Inject; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.cp.bean.WxCpMessage; import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; -import org.testng.annotations.*; import static org.testng.Assert.*; @@ -14,7 +15,7 @@ * @author Daniel Qian * */ -@Test(groups = "customMessageAPI") +@Test @Guice(modules = ApiTestModule.class) public class WxCpMessageAPITest { @@ -59,4 +60,32 @@ public void testSendMessage1() throws WxErrorException { System.out.println(messageSendResult.getInvalidUserList()); System.out.println(messageSendResult.getInvalidTagList()); } + + @Test + public void testSendMessage_markdown() throws WxErrorException { + WxCpMessage message = WxCpMessage + .MARKDOWN() + .toUser(configStorage.getUserId()) + .content("您的会议室已经预定,稍后会同步到`邮箱` \n" + + " >**事项详情** \n" + + " >事 项:开会 \n" + + " >组织者:@miglioguan \n" + + " >参与者:@miglioguan、@kunliu、@jamdeezhou、@kanexiong、@kisonwang \n" + + " > \n" + + " >会议室:广州TIT 1楼 301 \n" + + " >日 期:2018年5月18日 \n" + + " >时 间:上午9:00-11:00 \n" + + " > \n" + + " >请准时参加会议。 \n" + + " > \n" + + " >如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)") + .build(); + + WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message); + assertNotNull(messageSendResult); + System.out.println(messageSendResult); + System.out.println(messageSendResult.getInvalidPartyList()); + System.out.println(messageSendResult.getInvalidUserList()); + System.out.println(messageSendResult.getInvalidTagList()); + } } diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index 68530324b2..1dc35df68c 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -9,9 +9,10 @@ wx-java 3.3.2.B + weixin-java-miniapp - WxJava - MiniApp - 微信小程序Java SDK + WxJava - MiniApp Java SDK + 微信小程序 Java SDK diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 79783a560f..4196eb28db 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -9,8 +9,9 @@ wx-java 3.3.2.B + weixin-java-mp - WxJava - MP + WxJava - MP Java SDK 微信公众号Java SDK diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index 437aef4d9f..3abad1f261 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -3,16 +3,17 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"> - 4.0.0 com.github.binarywang wx-java 3.3.2.B + weixin-java-open - WxJava - Open - 微信开放平台Java SDK + WxJava - Open Java SDK + 微信开放平台 Java SDK + 007 diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index 1d401fde51..d3f7dc3e3f 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -10,7 +10,7 @@ 4.0.0 weixin-java-pay - WxJava - PAY + WxJava - PAY Java SDK 微信支付 Java SDK From f45c8103e96a28b790b1c7eaa523f3bba9e485c6 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 20 Jan 2019 13:49:30 +0800 Subject: [PATCH 15/81] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=96=87=E6=9C=AC?= =?UTF-8?q?=E5=8D=A1=E7=89=87=E6=B6=88=E6=81=AF=E7=9A=84=E5=8F=91=E9=80=81?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/cp/api/WxCpMessageAPITest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java index 370f33f801..5c93f38fb1 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java @@ -88,4 +88,23 @@ public void testSendMessage_markdown() throws WxErrorException { System.out.println(messageSendResult.getInvalidUserList()); System.out.println(messageSendResult.getInvalidTagList()); } + + @Test + public void testSendMessage_textCard() throws WxErrorException { + WxCpMessage message = WxCpMessage + .TEXTCARD() + .toUser(configStorage.getUserId()) + .btnTxt("更多") + .description( "
2016年9月26日
恭喜你抽中iPhone 7一台,领奖码:xxxx
请于2016年10月10日前联系行政同事领取
") + .url("URL") + .title("领奖通知") + .build(); + + WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message); + assertNotNull(messageSendResult); + System.out.println(messageSendResult); + System.out.println(messageSendResult.getInvalidPartyList()); + System.out.println(messageSendResult.getInvalidUserList()); + System.out.println(messageSendResult.getInvalidTagList()); + } } From cf11fa382649515b4c91f2c8b0c665f72c061e26 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 20 Jan 2019 14:01:48 +0800 Subject: [PATCH 16/81] =?UTF-8?q?#919=20=E5=A2=9E=E5=8A=A0=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E6=8E=A8=E9=80=81=E7=94=A8=E6=88=B7=E7=A4=BC=E5=93=81?= =?UTF-8?q?=E5=8D=A1=E7=9B=B8=E5=85=B3=E4=BA=8B=E4=BB=B6=E5=B8=B8=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mp/constant/WxMpEventConstants.java | 53 ++++++++++++------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/constant/WxMpEventConstants.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/constant/WxMpEventConstants.java index df1790e3da..0019816a20 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/constant/WxMpEventConstants.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/constant/WxMpEventConstants.java @@ -10,23 +10,23 @@ */ public class WxMpEventConstants { /** - * 门店审核事件 + * 门店审核事件. */ public static final String POI_CHECK_NOTIFY = "poi_check_notify"; /** - * 接收会员信息事件 + * 接收会员信息事件. */ public static final String SUBMIT_MEMBERCARD_USER_INFO = "submit_membercard_user_info"; /** - * 微信摇一摇周边>>摇一摇事件通知 + * 微信摇一摇周边>>摇一摇事件通知. */ public static final String SHAKEAROUND_USER_SHAKE = "ShakearoundUserShake"; /** - * 卡券相关事件 + * 卡券相关事件. */ public static class Card { public static final String CARD_PASS_CHECK = "card_pass_check"; @@ -39,74 +39,89 @@ public static class Card { public static final String USER_ENTER_SESSION_FROM_CARD = "user_enter_session_from_card"; /** - * 卡券转赠事件 + * 卡券转赠事件. */ public static final String USER_GIFTING_CARD = "user_gifting_card"; /** - * 库存报警 + * 库存报警. */ public static final String CARD_SKU_REMIND = "card_sku_remind"; /** - * 会员卡内容更新事件 + * 会员卡内容更新事件. */ public static final String UPDATE_MEMBER_CARD = "update_member_card"; /** - * 券点流水详情事件 + * 券点流水详情事件. */ public static final String CARD_PAY_ORDER = "card_pay_order"; + + /** + * 用户购买礼品卡付款成功事件. + */ + public static final String GIFTCARD_PAY_DONE = "giftcard_pay_done"; + + /** + * 用户购买后赠送事件. + */ + public static final String GIFTCARD_SEND_TO_FRIEND = "giftcard_send_to_friend"; + + /** + * 用户领取礼品卡成功事件. + */ + public static final String GIFTCARD_USER_ACCEPT = "giftcard_user_accept"; } /** - * 客服相关事件 + * 客服相关事件. */ public static class CustomerService { /** - * 客服接入会话 + * 客服接入会话. */ public static final String KF_CREATE_SESSION = "kf_create_session"; /** - * 客服关闭会话 + * 客服关闭会话. */ public static final String KF_CLOSE_SESSION = "kf_close_session"; /** - * 客服转接会话 + * 客服转接会话. */ public static final String KF_SWITCH_SESSION = "kf_switch_session"; } /** - * 微信认证事件 + * 微信认证事件. */ public static class Qualification { /** - * 资质认证成功 + * 资质认证成功. */ public static final String QUALIFICATION_VERIFY_SUCCESS = "qualification_verify_success"; /** - * 资质认证失败 + * 资质认证失败. */ public static final String QUALIFICATION_VERIFY_FAIL = "qualification_verify_fail"; /** - * 名称认证成功 + * 名称认证成功. */ public static final String NAMING_VERIFY_SUCCESS = "naming_verify_success"; /** - * 名称认证失败 + * 名称认证失败. */ public static final String NAMING_VERIFY_FAIL = "naming_verify_fail"; /** - * 年审通知 + * 年审通知. */ public static final String ANNUAL_RENEW = "annual_renew"; /** - * 认证过期失效通知 + * 认证过期失效通知. */ public static final String VERIFY_EXPIRED = "verify_expired"; } From 8fa9ee4dc69ec2ff198cf192237742a86f908cca Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 20 Jan 2019 14:07:40 +0800 Subject: [PATCH 17/81] =?UTF-8?q?#918=20=E4=BF=AE=E5=A4=8D=E5=8D=A1?= =?UTF-8?q?=E5=8A=B5=E9=AB=98=E7=BA=A7=E4=BF=A1=E6=81=AF=E4=B8=AD=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E6=97=B6=E6=AE=B5=E9=99=90=E5=88=B6=E5=AD=97=E6=AE=B5?= =?UTF-8?q?time=5Flimit=E7=9A=84=E9=94=99=E8=AF=AF=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/mp/bean/card/AdvancedInfo.java | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/AdvancedInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/AdvancedInfo.java index f127c8ecfd..7ab5786dec 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/AdvancedInfo.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/AdvancedInfo.java @@ -11,6 +11,7 @@ /** * 微信会员卡高级字段信息. + * * @author yuanqixun * date:2018-08-25 00:36 */ @@ -18,13 +19,6 @@ public class AdvancedInfo implements Serializable { private static final long serialVersionUID = -8470424140133771841L; -// public AdvancedInfo(){ -// useCondition = new UseCondition(); -// abstractInfo = new Abstract(); -// textImageList = new ArrayList<>(); -// timeLimit = new TimeLimit(); -// } - /** * 使用门槛(条件). * 若不填写使用条件则在券面拼写 :无最低消费限制,全场通用,不限品类;并在使用说明显示: 可与其他优惠共享 @@ -56,7 +50,7 @@ public class AdvancedInfo implements Serializable { * 使用时段限制. */ @SerializedName("time_limit") - private TimeLimit timeLimit; + private List timeLimits; /** * 是否可以分享朋友. @@ -66,7 +60,7 @@ public class AdvancedInfo implements Serializable { public void addBusinessService(BusinessServiceType businessServiceType) { if (businessServiceType != null) { - if (businessServiceList == null){ + if (businessServiceList == null) { businessServiceList = new ArrayList<>(); } From 6fccfb3600d89674a0a9150f22c0e00c38b3cf75 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 20 Jan 2019 14:28:00 +0800 Subject: [PATCH 18/81] =?UTF-8?q?#915=20=E4=BC=81=E4=B8=9A=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1WxCpUser=E5=AF=B9=E8=B1=A1=E5=A2=9E=E5=8A=A0order?= =?UTF-8?q?=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/cp/bean/WxCpUser.java | 1 + .../cp/util/json/WxCpUserGsonAdapter.java | 138 +++++++++++------- .../cp/util/json/WxCpUserGsonAdapterTest.java | 14 +- 3 files changed, 99 insertions(+), 54 deletions(-) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java index 233d4576e1..5a4f998db5 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java @@ -21,6 +21,7 @@ public class WxCpUser implements Serializable { private String userId; private String name; private Integer[] departIds; + private Integer[] orders; private String position; private String mobile; private Gender gender; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java index 1dc3f687d5..7f8b2640c5 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java @@ -6,6 +6,7 @@ * arose from modification of the original source, or other redistribution of this source * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. */ + package me.chanjar.weixin.cp.util.json; import java.lang.reflect.Type; @@ -24,11 +25,14 @@ import me.chanjar.weixin.cp.bean.WxCpUser; /** + * cp user gson adapter. + * * @author Daniel Qian */ public class WxCpUserGsonAdapter implements JsonDeserializer, JsonSerializer { private static final String EXTERNAL_PROFILE = "external_profile"; private static final String EXTERNAL_ATTR = "external_attr"; + private static final String EXTATTR = "extattr"; @Override public WxCpUser deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { @@ -45,6 +49,16 @@ public WxCpUser deserialize(JsonElement json, Type typeOfT, JsonDeserializationC user.setDepartIds(departIds); } + if (o.get("order") != null) { + JsonArray departJsonArray = o.get("order").getAsJsonArray(); + Integer[] orders = new Integer[departJsonArray.size()]; + int i = 0; + for (JsonElement jsonElement : departJsonArray) { + orders[i++] = jsonElement.getAsInt(); + } + user.setOrders(orders); + } + user.setUserId(GsonHelper.getString(o, "userid")); user.setName(GsonHelper.getString(o, "name")); user.setPosition(GsonHelper.getString(o, "position")); @@ -62,64 +76,73 @@ public WxCpUser deserialize(JsonElement json, Type typeOfT, JsonDeserializationC user.setQrCode(GsonHelper.getString(o, "qr_code")); user.setToInvite(GsonHelper.getBoolean(o, "to_invite")); - if (GsonHelper.isNotNull(o.get("extattr"))) { - JsonArray attrJsonElements = o.get("extattr").getAsJsonObject().get("attrs").getAsJsonArray(); - for (JsonElement attrJsonElement : attrJsonElements) { - WxCpUser.Attr attr = new WxCpUser.Attr( - GsonHelper.getString(attrJsonElement.getAsJsonObject(), "name"), - GsonHelper.getString(attrJsonElement.getAsJsonObject(), "value") - ); - user.getExtAttrs().add(attr); - } + if (GsonHelper.isNotNull(o.get(EXTATTR))) { + this.buildExtraAttrs(o, user); } if (GsonHelper.isNotNull(o.get(EXTERNAL_PROFILE))) { - JsonArray attrJsonElements = o.get(EXTERNAL_PROFILE).getAsJsonObject().get(EXTERNAL_ATTR).getAsJsonArray(); - for (JsonElement element : attrJsonElements) { - final Integer type = GsonHelper.getInteger(element.getAsJsonObject(), "type"); - final String name = GsonHelper.getString(element.getAsJsonObject(), "name"); + this.buildExternalAttrs(o, user); + } - switch (type) { - case 0: { - user.getExternalAttrs() - .add(WxCpUser.ExternalAttribute.builder() - .type(type) - .name(name) - .value(GsonHelper.getString(element.getAsJsonObject().get("text").getAsJsonObject(), "value")) - .build() - ); - break; - } - case 1: { - final JsonObject web = element.getAsJsonObject().get("web").getAsJsonObject(); - user.getExternalAttrs() - .add(WxCpUser.ExternalAttribute.builder() - .type(type) - .name(name) - .url(GsonHelper.getString(web, "url")) - .title(GsonHelper.getString(web, "title")) - .build() - ); - break; - } - case 2: { - final JsonObject miniprogram = element.getAsJsonObject().get("miniprogram").getAsJsonObject(); - user.getExternalAttrs() - .add(WxCpUser.ExternalAttribute.builder() - .type(type) - .name(name) - .appid(GsonHelper.getString(miniprogram, "appid")) - .pagePath(GsonHelper.getString(miniprogram, "pagepath")) - .title(GsonHelper.getString(miniprogram, "title")) - .build() - ); - break; - } - default://ignored + return user; + } + + private void buildExtraAttrs(JsonObject o, WxCpUser user) { + JsonArray attrJsonElements = o.get(EXTATTR).getAsJsonObject().get("attrs").getAsJsonArray(); + for (JsonElement attrJsonElement : attrJsonElements) { + WxCpUser.Attr attr = new WxCpUser.Attr( + GsonHelper.getString(attrJsonElement.getAsJsonObject(), "name"), + GsonHelper.getString(attrJsonElement.getAsJsonObject(), "value") + ); + user.getExtAttrs().add(attr); + } + } + + private void buildExternalAttrs(JsonObject o, WxCpUser user) { + JsonArray attrJsonElements = o.get(EXTERNAL_PROFILE).getAsJsonObject().get(EXTERNAL_ATTR).getAsJsonArray(); + for (JsonElement element : attrJsonElements) { + final Integer type = GsonHelper.getInteger(element.getAsJsonObject(), "type"); + final String name = GsonHelper.getString(element.getAsJsonObject(), "name"); + + switch (type) { + case 0: { + user.getExternalAttrs() + .add(WxCpUser.ExternalAttribute.builder() + .type(type) + .name(name) + .value(GsonHelper.getString(element.getAsJsonObject().get("text").getAsJsonObject(), "value")) + .build() + ); + break; } + case 1: { + final JsonObject web = element.getAsJsonObject().get("web").getAsJsonObject(); + user.getExternalAttrs() + .add(WxCpUser.ExternalAttribute.builder() + .type(type) + .name(name) + .url(GsonHelper.getString(web, "url")) + .title(GsonHelper.getString(web, "title")) + .build() + ); + break; + } + case 2: { + final JsonObject miniprogram = element.getAsJsonObject().get("miniprogram").getAsJsonObject(); + user.getExternalAttrs() + .add(WxCpUser.ExternalAttribute.builder() + .type(type) + .name(name) + .appid(GsonHelper.getString(miniprogram, "appid")) + .pagePath(GsonHelper.getString(miniprogram, "pagepath")) + .title(GsonHelper.getString(miniprogram, "title")) + .build() + ); + break; + } + default://ignored } } - return user; } @Override @@ -138,6 +161,15 @@ public JsonElement serialize(WxCpUser user, Type typeOfSrc, JsonSerializationCon } o.add("department", jsonArray); } + + if (user.getOrders() != null) { + JsonArray jsonArray = new JsonArray(); + for (Integer order : user.getOrders()) { + jsonArray.add(new JsonPrimitive(order)); + } + o.add("order", jsonArray); + } + if (user.getPosition() != null) { o.addProperty("position", user.getPosition()); } @@ -191,14 +223,14 @@ public JsonElement serialize(WxCpUser user, Type typeOfSrc, JsonSerializationCon } JsonObject attrsJson = new JsonObject(); attrsJson.add("attrs", attrsJsonArray); - o.add("extattr", attrsJson); + o.add(EXTATTR, attrsJson); } if (user.getExternalAttrs().size() > 0) { JsonArray attrsJsonArray = new JsonArray(); for (WxCpUser.ExternalAttribute attr : user.getExternalAttrs()) { JsonObject attrJson = new JsonObject(); - attrJson.addProperty("type",attr.getType()); + attrJson.addProperty("type", attr.getType()); attrJson.addProperty("name", attr.getName()); switch (attr.getType()) { case 0: { diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapterTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapterTest.java index ec553f7521..9cdc51f885 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapterTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapterTest.java @@ -76,6 +76,13 @@ public void testDeserialize() { final WxCpUser user = WxCpUser.fromJson(userJson); assertThat(user).isNotNull(); + + assertThat(user.getOrders()).isNotEmpty(); + assertThat(user.getOrders().length).isEqualTo(2); + assertThat(user.getOrders()[0]).isEqualTo(1); + assertThat(user.getOrders()[1]).isEqualTo(2); + + assertThat(user.getExternalAttrs()).isNotEmpty(); final WxCpUser.ExternalAttribute externalAttr1 = user.getExternalAttrs().get(0); @@ -100,6 +107,7 @@ public void testDeserialize() { @Test public void testSerialize() { WxCpUser user = new WxCpUser(); + user.setOrders(new Integer[]{1, 2}); user.addExternalAttr(WxCpUser.ExternalAttribute.builder() .type(0) .name("文本名称") @@ -119,6 +127,10 @@ public void testSerialize() { .title("my miniprogram") .build()); - assertThat(user.toJson()).isEqualTo("{\"external_profile\":{\"external_attr\":[{\"type\":0,\"name\":\"文本名称\",\"text\":{\"value\":\"文本\"}},{\"type\":1,\"name\":\"网页名称\",\"web\":{\"url\":\"http://www.test.com\",\"title\":\"标题\"}},{\"type\":2,\"name\":\"测试app\",\"miniprogram\":{\"appid\":\"wx8bd80126147df384\",\"pagepath\":\"/index\",\"title\":\"my miniprogram\"}}]}}"); + assertThat(user.toJson()).isEqualTo("{\"order\":[1,2],\"external_profile\":{\"external_attr\":" + + "[{\"type\":0,\"name\":\"文本名称\",\"text\":{\"value\":\"文本\"}}," + + "{\"type\":1,\"name\":\"网页名称\",\"web\":{\"url\":\"http://www.test.com\",\"title\":\"标题\"}}," + + "{\"type\":2,\"name\":\"测试app\"," + + "\"miniprogram\":{\"appid\":\"wx8bd80126147df384\",\"pagepath\":\"/index\",\"title\":\"my miniprogram\"}}]}}"); } } From 24619d666f9c4b7521089c7fe565f7d7f1f2768e Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 20 Jan 2019 14:57:58 +0800 Subject: [PATCH 19/81] =?UTF-8?q?=E5=8F=91=E5=B8=833.3.3.B=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- weixin-java-common/pom.xml | 2 +- weixin-java-cp/pom.xml | 2 +- weixin-java-miniapp/pom.xml | 2 +- weixin-java-mp/pom.xml | 2 +- weixin-java-open/pom.xml | 2 +- weixin-java-pay/pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 99d4288ca0..503bb5639a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.github.binarywang wx-java - 3.3.2.B + 3.3.3.B pom WxJava - Weixin/Wechat Java SDK 微信开发Java SDK diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 7a51af4b96..f0cdad4260 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.2.B + 3.3.3.B weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 3d9cf9a8f7..b8d9d82d27 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.2.B + 3.3.3.B weixin-java-cp diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index 1dc35df68c..4c70f78229 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.2.B + 3.3.3.B weixin-java-miniapp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 4196eb28db..2c32c42657 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.2.B + 3.3.3.B weixin-java-mp diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index 3abad1f261..bf9d0560a8 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.2.B + 3.3.3.B weixin-java-open diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index d3f7dc3e3f..3b481619c0 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ com.github.binarywang wx-java - 3.3.2.B + 3.3.3.B 4.0.0 From 58faf5a89181f568381c051aac90cf6b30dde95a Mon Sep 17 00:00:00 2001 From: fxl <744822514@qq.com> Date: Tue, 22 Jan 2019 11:13:17 +0800 Subject: [PATCH 20/81] =?UTF-8?q?#924=20=E5=A2=9E=E5=8A=A0=E5=8D=A1?= =?UTF-8?q?=E5=88=B8=E5=88=A0=E9=99=A4=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/mp/api/WxMpCardService.java | 13 +++++++ .../mp/api/impl/WxMpCardServiceImpl.java | 38 +++++++++---------- .../mp/bean/card/BaseWxMpCardResult.java | 25 ++++++++++++ .../mp/bean/card/WxMpCardDeleteResult.java | 21 ++++++++++ .../mp/api/impl/WxMpCardServiceImplTest.java | 34 ++++++++--------- 5 files changed, 93 insertions(+), 38 deletions(-) create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/BaseWxMpCardResult.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardDeleteResult.java diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java index c86b3d19fd..66aeccade7 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java @@ -27,6 +27,11 @@ public interface WxMpCardService { */ String CARD_CODE_UNAVAILABLE = "https://api.weixin.qq.com/card/code/unavailable"; + /** + * 卡券删除 + */ + String CARD_DELETE = "https://api.weixin.qq.com/card/delete"; + /** * 得到WxMpService */ @@ -189,4 +194,12 @@ void markCardCode(String code, String cardId, String openId, boolean isMark) thr */ String unavailableCardCode(String cardId, String code, String reason) throws WxErrorException; + /** + * 删除卡券接口 + * @param cardId + * @return + * @throws WxErrorException + */ + WxMpCardDeleteResult deleteCard(String cardId) throws WxErrorException; + } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java index 6717eb91b5..bdd1990440 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java @@ -1,18 +1,6 @@ package me.chanjar.weixin.mp.api.impl; -import java.util.Arrays; -import java.util.concurrent.locks.Lock; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.JsonPrimitive; +import com.google.gson.*; import com.google.gson.reflect.TypeToken; import me.chanjar.weixin.common.bean.WxCardApiSignature; import me.chanjar.weixin.common.error.WxError; @@ -22,14 +10,15 @@ import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; import me.chanjar.weixin.mp.api.WxMpCardService; import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.bean.card.WxMpCardCreateMessage; -import me.chanjar.weixin.mp.bean.card.WxMpCardCreateResult; -import me.chanjar.weixin.mp.bean.card.WxMpCardLandingPageCreateRequest; -import me.chanjar.weixin.mp.bean.card.WxMpCardLandingPageCreateResult; -import me.chanjar.weixin.mp.bean.card.WxMpCardQrcodeCreateResult; -import me.chanjar.weixin.mp.bean.card.WxMpCardResult; +import me.chanjar.weixin.mp.bean.card.*; import me.chanjar.weixin.mp.enums.TicketType; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Arrays; +import java.util.concurrent.locks.Lock; /** * Created by Binary Wang on 2016/7/27. @@ -325,4 +314,15 @@ public String unavailableCardCode(String cardId, String code, String reason) thr jsonRequest.addProperty("reason", reason); return this.wxMpService.post(CARD_CODE_UNAVAILABLE, GSON.toJson(jsonRequest)); } + + @Override + public WxMpCardDeleteResult deleteCard(String cardId) throws WxErrorException { + if (StringUtils.isEmpty(cardId)) { + throw new WxErrorException(WxError.builder().errorCode(41012).errorMsg("cardId不能为空").build()); + } + JsonObject param = new JsonObject(); + param.addProperty("card_id", cardId); + String response = this.wxMpService.post(CARD_DELETE, param.toString()); + return WxMpCardDeleteResult.fromJson(response); + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/BaseWxMpCardResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/BaseWxMpCardResult.java new file mode 100644 index 0000000000..3988ee0c24 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/BaseWxMpCardResult.java @@ -0,0 +1,25 @@ +package me.chanjar.weixin.mp.bean.card; + +import java.io.Serializable; + +/** + * @description 卡券返回结果基础类 + * @author: fanxl + * @date: 2019/1/22 0022 10:08 + */ +public class BaseWxMpCardResult implements Serializable { + + /** + * 错误码 + */ + private Integer errcode; + + /** + * 错误信息 + */ + private String errmsg; + + public boolean isSuccess() { + return 0 == errcode; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardDeleteResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardDeleteResult.java new file mode 100644 index 0000000000..3dcbc3534c --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxMpCardDeleteResult.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.mp.bean.card; + +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +/** + * @description 删除卡券结果 + * @author: fanxl + * @date: 2019/1/22 0022 10:24 + */ +public class WxMpCardDeleteResult extends BaseWxMpCardResult { + + public static WxMpCardDeleteResult fromJson(String json) { + return WxMpGsonBuilder.create().fromJson(json, WxMpCardDeleteResult.class); + } + + @Override + public String toString() { + return WxMpGsonBuilder.create().toJson(this); + } + +} diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java index 336d11b752..37147e535a 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImplTest.java @@ -1,29 +1,16 @@ package me.chanjar.weixin.mp.api.impl; -import org.testng.annotations.*; - import com.google.inject.Inject; import me.chanjar.weixin.common.bean.WxCardApiSignature; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.test.ApiTestModule; -import me.chanjar.weixin.mp.bean.card.BaseInfo; -import me.chanjar.weixin.mp.bean.card.CashCard; -import me.chanjar.weixin.mp.bean.card.CashCardCreateRequest; -import me.chanjar.weixin.mp.bean.card.DateInfo; -import me.chanjar.weixin.mp.bean.card.DiscountCard; -import me.chanjar.weixin.mp.bean.card.DiscountCardCreateRequest; -import me.chanjar.weixin.mp.bean.card.GeneralCard; -import me.chanjar.weixin.mp.bean.card.GeneralCardCreateRequest; -import me.chanjar.weixin.mp.bean.card.GiftCard; -import me.chanjar.weixin.mp.bean.card.GiftCardCreateRequest; -import me.chanjar.weixin.mp.bean.card.GrouponCard; -import me.chanjar.weixin.mp.bean.card.GrouponCardCreateRequest; -import me.chanjar.weixin.mp.bean.card.Sku; -import me.chanjar.weixin.mp.bean.card.WxMpCardCreateMessage; -import me.chanjar.weixin.mp.bean.card.WxMpCardResult; - -import static org.testng.AssertJUnit.*; +import me.chanjar.weixin.mp.bean.card.*; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; /** * 测试代码仅供参考,未做严格测试,因原接口作者并未提供单元测试代码 @@ -210,4 +197,13 @@ public void testCreateGrouponCard() throws WxErrorException { generalMessage.setCardCreateRequest(generalCardCreateRequest); System.out.println(this.wxService.getCardService().createCard(generalMessage)); } + + @Test + public void testDeleteCard() throws Exception { + String cardId = "pwkrWjtw7W4_l50kCQcZ1in1yS6g"; + WxMpCardDeleteResult result = this.wxService.getCardService().deleteCard(cardId); + assertEquals(result.isSuccess(), true); + System.out.println(result); + } + } From bdd72995a5ae84c9bb51916dbb133d074772027e Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 24 Jan 2019 11:47:01 +0800 Subject: [PATCH 21/81] =?UTF-8?q?#927=20=E4=BC=81=E4=B8=9A=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1WxCpUser=E7=9A=84departIds=E7=B1=BB=E5=9E=8B=E6=94=B9?= =?UTF-8?q?=E4=B8=BALong[]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java | 2 +- .../me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java | 6 +++--- .../chanjar/weixin/cp/api/impl/WxCpUserServiceImplTest.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java index 5a4f998db5..dcf4789eba 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java @@ -20,7 +20,7 @@ public class WxCpUser implements Serializable { private static final long serialVersionUID = -5696099236344075582L; private String userId; private String name; - private Integer[] departIds; + private Long[] departIds; private Integer[] orders; private String position; private String mobile; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java index 7f8b2640c5..84ee7c0f2f 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java @@ -41,10 +41,10 @@ public WxCpUser deserialize(JsonElement json, Type typeOfT, JsonDeserializationC if (o.get("department") != null) { JsonArray departJsonArray = o.get("department").getAsJsonArray(); - Integer[] departIds = new Integer[departJsonArray.size()]; + Long[] departIds = new Long[departJsonArray.size()]; int i = 0; for (JsonElement jsonElement : departJsonArray) { - departIds[i++] = jsonElement.getAsInt(); + departIds[i++] = jsonElement.getAsLong(); } user.setDepartIds(departIds); } @@ -156,7 +156,7 @@ public JsonElement serialize(WxCpUser user, Type typeOfSrc, JsonSerializationCon } if (user.getDepartIds() != null) { JsonArray jsonArray = new JsonArray(); - for (Integer departId : user.getDepartIds()) { + for (Long departId : user.getDepartIds()) { jsonArray.add(new JsonPrimitive(departId)); } o.add("department", jsonArray); diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImplTest.java index f473fe6be7..2ec33e7ba7 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImplTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpUserServiceImplTest.java @@ -42,7 +42,7 @@ public void testCreate() throws Exception { WxCpUser user = new WxCpUser(); user.setUserId(userId); user.setName("Some Woman"); - user.setDepartIds(new Integer[]{2}); + user.setDepartIds(new Long[]{2L}); user.setEmail("none@none.com"); user.setGender(Gender.FEMALE); user.setMobile("13560084979"); From 761e88201c95412cd4cfe8005c7c8e5406c44348 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Fri, 25 Jan 2019 16:08:03 +0800 Subject: [PATCH 22/81] =?UTF-8?q?#928=20=E4=BF=AE=E5=A4=8D=E5=8D=A1?= =?UTF-8?q?=E5=88=B8=E6=8B=89=E5=8F=96=E7=94=A8=E6=88=B7=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=8A=A5=E7=A9=BA=E6=8C=87=E9=92=88=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...MpMemberCardUserInfoResultGsonAdapter.java | 45 ++++++++++++------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMemberCardUserInfoResultGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMemberCardUserInfoResultGsonAdapter.java index 3b14e0dc10..82790a0b0d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMemberCardUserInfoResultGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMemberCardUserInfoResultGsonAdapter.java @@ -1,50 +1,62 @@ package me.chanjar.weixin.mp.util.json; -import com.google.gson.*; +import java.lang.reflect.Type; + +import com.google.gson.JsonArray; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; import me.chanjar.weixin.common.util.json.GsonHelper; import me.chanjar.weixin.mp.bean.membercard.MemberCardUserInfo; import me.chanjar.weixin.mp.bean.membercard.NameValues; import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUserInfoResult; -import java.lang.reflect.Type; +import static me.chanjar.weixin.common.util.json.GsonHelper.getString; /** * Json to WxMpMemberCardUserInfoResult 的转换适配器 * - * @author YuJian(mgcnrx11@gmail.com) + * @author YuJian(mgcnrx11 @ gmail.com) * @version 2017/7/11 */ public class WxMpMemberCardUserInfoResultGsonAdapter implements JsonDeserializer { @Override - public WxMpMemberCardUserInfoResult deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + public WxMpMemberCardUserInfoResult deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext context) + throws JsonParseException { WxMpMemberCardUserInfoResult result = new WxMpMemberCardUserInfoResult(); JsonObject jsonObject = jsonElement.getAsJsonObject(); - result.setOpenId(GsonHelper.getString(jsonObject, "openid")); - result.setErrorCode(GsonHelper.getString(jsonObject, "errcode")); - result.setErrorMsg(GsonHelper.getString(jsonObject, "errmsg")); - result.setNickname(GsonHelper.getString(jsonObject, "nickname")); - result.setMembershipNumber(GsonHelper.getString(jsonObject, "membership_number")); + result.setOpenId(getString(jsonObject, "openid")); + result.setErrorCode(getString(jsonObject, "errcode")); + result.setErrorMsg(getString(jsonObject, "errmsg")); + result.setNickname(getString(jsonObject, "nickname")); + result.setMembershipNumber(getString(jsonObject, "membership_number")); result.setBonus(GsonHelper.getInteger(jsonObject, "bonus")); result.setBalance(GsonHelper.getDouble(jsonObject, "balance")); - result.setSex(GsonHelper.getString(jsonObject, "sex")); - result.setUserCardStatus(GsonHelper.getString(jsonObject, "user_card_status")); + result.setSex(getString(jsonObject, "sex")); + result.setUserCardStatus(getString(jsonObject, "user_card_status")); result.setHasActive(GsonHelper.getBoolean(jsonObject, "has_active")); JsonObject userInfoJsonObject = jsonObject.getAsJsonObject("user_info"); - MemberCardUserInfo cardUserInfo = new MemberCardUserInfo(); + if (userInfoJsonObject == null) { + return result; + } JsonArray commonFieldListObj = userInfoJsonObject.getAsJsonArray("common_field_list"); NameValues[] commonFieldListValues = new NameValues[commonFieldListObj.size()]; for (int i = 0; i < commonFieldListObj.size(); i++) { JsonObject commonField = commonFieldListObj.get(i).getAsJsonObject(); NameValues commonNameValues = new NameValues(); - commonNameValues.setName(GsonHelper.getString(commonField, "name")); - commonNameValues.setValue(GsonHelper.getString(commonField, "value")); + commonNameValues.setName(getString(commonField, "name")); + commonNameValues.setValue(getString(commonField, "value")); commonFieldListValues[i] = commonNameValues; } + + MemberCardUserInfo cardUserInfo = new MemberCardUserInfo(); cardUserInfo.setCommonFieldList(commonFieldListValues); JsonArray customFieldListObj = userInfoJsonObject.getAsJsonArray("custom_field_list"); @@ -52,8 +64,8 @@ public WxMpMemberCardUserInfoResult deserialize(JsonElement jsonElement, Type ty for (int i = 0; i < customFieldListObj.size(); i++) { JsonObject customField = customFieldListObj.get(i).getAsJsonObject(); NameValues customNameValues = new NameValues(); - customNameValues.setName(GsonHelper.getString(customField, "name")); - customNameValues.setValue(GsonHelper.getString(customField, "value")); + customNameValues.setName(getString(customField, "name")); + customNameValues.setValue(getString(customField, "value")); JsonArray valueListArray = customField.getAsJsonArray("value_list"); String[] valueList = new String[valueListArray.size()]; @@ -63,6 +75,7 @@ public WxMpMemberCardUserInfoResult deserialize(JsonElement jsonElement, Type ty customNameValues.setValueList(valueList); customFieldListValues[i] = customNameValues; } + cardUserInfo.setCustomFieldList(customFieldListValues); result.setUserInfo(cardUserInfo); From a47d91fc24c00b96903c471350dc37d2b7a828bc Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 26 Jan 2019 15:03:44 +0800 Subject: [PATCH 23/81] =?UTF-8?q?#907=20=E4=BC=81=E4=B8=9A=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E5=A2=9E=E5=8A=A0=E5=BA=94=E7=94=A8=E6=8E=A8=E9=80=81?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E5=88=B0=E7=BE=A4=E8=81=8A=E4=BC=9A=E8=AF=9D?= =?UTF-8?q?=E7=9A=84=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/me/chanjar/weixin/cp/WxCpConsts.java | 42 +++++ .../weixin/cp/api/WxCpChatService.java | 46 ++++-- .../cp/api/impl/WxCpChatServiceImpl.java | 39 +++-- .../weixin/cp/bean/WxCpAppChatMessage.java | 154 ++++++++++++++++++ .../weixin/cp/bean/article/NewArticle.java | 10 +- .../cp/api/impl/WxCpChatServiceImplTest.java | 140 ++++++++++++++-- .../demo/WxCpDemoInMemoryConfigStorage.java | 15 +- 7 files changed, 388 insertions(+), 58 deletions(-) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/WxCpConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/WxCpConsts.java index 4eb52a903d..168bcf7492 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/WxCpConsts.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/WxCpConsts.java @@ -126,4 +126,46 @@ public static class ContactChangeType { public static final String UPDATE_TAG = "update_tag"; } + + /** + * 应用推送消息的消息类型. + */ + public static class AppChatMsgType { + /** + * 文本消息. + */ + public static final String TEXT = "text"; + /** + * 图片消息. + */ + public static final String IMAGE = "image"; + /** + * 语音消息. + */ + public static final String VOICE = "voice"; + /** + * 视频消息. + */ + public static final String VIDEO = "video"; + /** + * 发送文件(CP专用). + */ + public static final String FILE = "file"; + /** + * 文本卡片消息(CP专用). + */ + public static final String TEXTCARD = "textcard"; + /** + * 图文消息(点击跳转到外链). + */ + public static final String NEWS = "news"; + /** + * 图文消息(点击跳转到图文消息页面). + */ + public static final String MPNEWS = "mpnews"; + /** + * markdown消息. + */ + public static final String MARKDOWN = "markdown"; + } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java index 2c24701dda..a9a7cfe7f3 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java @@ -3,46 +3,60 @@ import java.util.List; import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.bean.WxCpAppChatMessage; import me.chanjar.weixin.cp.bean.WxCpChat; /** - * 群聊服务 + * 群聊服务. * * @author gaigeshen */ public interface WxCpChatService { + String APPCHAT_CREATE = "https://qyapi.weixin.qq.com/cgi-bin/appchat/create"; + String APPCHAT_UPDATE = "https://qyapi.weixin.qq.com/cgi-bin/appchat/update"; + String APPCHAT_GET_CHATID = "https://qyapi.weixin.qq.com/cgi-bin/appchat/get?chatid="; /** - * 创建群聊会话,注意:刚创建的群,如果没有下发消息,在企业微信不会出现该群。 + * 创建群聊会话,注意:刚创建的群,如果没有下发消息,在企业微信不会出现该群. * - * @param name 群聊名,最多50个utf8字符,超过将截断 - * @param owner 指定群主的id。如果不指定,系统会随机从userlist中选一人作为群主 - * @param users 群成员id列表。至少2人,至多500人 + * @param name 群聊名,最多50个utf8字符,超过将截断 + * @param owner 指定群主的id。如果不指定,系统会随机从userlist中选一人作为群主 + * @param users 群成员id列表。至少2人,至多500人 * @param chatId 群聊的唯一标志,不能与已有的群重复;字符串类型,最长32个字符。只允许字符0-9及字母a-zA-Z。如果不填,系统会随机生成群id - * @return 创建群聊会话的结果,群聊的唯一标志 + * @return 创建的群聊会话chatId * @throws WxErrorException 发生异常 */ String chatCreate(String name, String owner, List users, String chatId) throws WxErrorException; - + /** - * 修改群聊会话 - * - * @param chatId 群聊id - * @param name 新的群聊名。若不需更新,请忽略此参数(null or empty)。最多50个utf8字符,超过将截断 - * @param owner 新群主的id。若不需更新,请忽略此参数(null or empty) - * @param usersToAdd 添加成员的id列表,若不需要更新,则传递空对象或者空集合 + * 修改群聊会话. + * + * @param chatId 群聊id + * @param name 新的群聊名。若不需更新,请忽略此参数(null or empty)。最多50个utf8字符,超过将截断 + * @param owner 新群主的id。若不需更新,请忽略此参数(null or empty) + * @param usersToAdd 添加成员的id列表,若不需要更新,则传递空对象或者空集合 * @param usersToDelete 踢出成员的id列表,若不需要更新,则传递空对象或者空集合 * @throws WxErrorException 发生异常 */ void chatUpdate(String chatId, String name, String owner, List usersToAdd, List usersToDelete) throws WxErrorException; /** - * 获取群聊会话 - * + * 获取群聊会话. + * * @param chatId 群聊编号 * @return 群聊会话 * @throws WxErrorException 发生异常 */ WxCpChat chatGet(String chatId) throws WxErrorException; - + + /** + * 应用支持推送文本、图片、视频、文件、图文等类型. + * 请求方式: POST(HTTPS) + * 请求地址: https://qyapi.weixin.qq.com/cgi-bin/appchat/send?access_token=ACCESS_TOKEN + * 文档地址:https://work.weixin.qq.com/api/doc#90000/90135/90248 + * + * @param message 要发送的消息内容对象 + */ + void sendMsg(WxCpAppChatMessage message) throws WxErrorException; + } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java index b8e894fb9b..96e842adbc 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java @@ -7,30 +7,30 @@ import org.apache.commons.lang3.StringUtils; import com.google.gson.JsonParser; - import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.json.WxGsonBuilder; import me.chanjar.weixin.cp.api.WxCpChatService; import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.WxCpAppChatMessage; import me.chanjar.weixin.cp.bean.WxCpChat; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; /** - * 群聊服务实现 + * 群聊服务实现. * * @author gaigeshen */ -public class WxCpChatServiceImpl implements WxCpChatService { +public class WxCpChatServiceImpl implements WxCpChatService { + private static final JsonParser JSON_PARSER = new JsonParser(); + private final WxCpService cpService; - private final WxCpService internalService; - /** - * 创建群聊服务实现的实例 - * - * @param internalService 企业微信的服务 + * 创建群聊服务实现的实例. + * + * @param cpService 企业微信的服务 */ - public WxCpChatServiceImpl(WxCpService internalService) { - this.internalService = internalService; + WxCpChatServiceImpl(WxCpService cpService) { + this.cpService = cpService; } @Override @@ -48,12 +48,13 @@ public String chatCreate(String name, String owner, List users, String c if (StringUtils.isNotBlank(chatId)) { data.put("chatid", chatId); } - String result = internalService.post("https://qyapi.weixin.qq.com/cgi-bin/appchat/create", WxGsonBuilder.create().toJson(data)); + String result = this.cpService.post(APPCHAT_CREATE, WxGsonBuilder.create().toJson(data)); return new JsonParser().parse(result).getAsJsonObject().get("chatid").getAsString(); } @Override - public void chatUpdate(String chatId, String name, String owner, List usersToAdd, List usersToDelete) throws WxErrorException { + public void chatUpdate(String chatId, String name, String owner, List usersToAdd, List usersToDelete) + throws WxErrorException { Map data = new HashMap<>(5); if (StringUtils.isNotBlank(chatId)) { data.put("chatid", chatId); @@ -70,14 +71,20 @@ public void chatUpdate(String chatId, String name, String owner, List us if (usersToDelete != null && !usersToDelete.isEmpty()) { data.put("del_user_list", usersToDelete); } - internalService.post("https://qyapi.weixin.qq.com/cgi-bin/appchat/update", WxGsonBuilder.create().toJson(data)); + + this.cpService.post(APPCHAT_UPDATE, WxGsonBuilder.create().toJson(data)); } @Override public WxCpChat chatGet(String chatId) throws WxErrorException { - String result = internalService.get("https://qyapi.weixin.qq.com/cgi-bin/appchat/get?chatid=" + chatId, null); - return WxCpGsonBuilder.create().fromJson( - new JsonParser().parse(result).getAsJsonObject().getAsJsonObject("chat_info").toString(), WxCpChat.class); + String result = this.cpService.get(APPCHAT_GET_CHATID + chatId, null); + return WxCpGsonBuilder.create() + .fromJson(JSON_PARSER.parse(result).getAsJsonObject().getAsJsonObject("chat_info").toString(), WxCpChat.class); + } + + @Override + public void sendMsg(WxCpAppChatMessage message) throws WxErrorException { + this.cpService.post("https://qyapi.weixin.qq.com/cgi-bin/appchat/send", message.toJson()); } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java new file mode 100644 index 0000000000..65a13badd0 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java @@ -0,0 +1,154 @@ +package me.chanjar.weixin.cp.bean; + +import java.io.Serializable; +import java.util.List; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.cp.WxCpConsts; +import me.chanjar.weixin.cp.bean.article.MpnewsArticle; +import me.chanjar.weixin.cp.bean.article.NewArticle; + +/** + *
+ * 应用推送消息
+ * Created by Binary Wang on 2019/1/26.
+ * 
+ * + * @author Binary Wang + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class WxCpAppChatMessage implements Serializable { + private static final long serialVersionUID = -5469013416372240229L; + + private String msgType; + private String content; + private String chatId; + private String mediaId; + private String title; + private String description; + private Boolean safe; + private String url; + private String btnTxt; + private List articles; + private List mpnewsArticles; + + /** + * 构建文本消息. + */ + public static WxCpAppChatMessage buildTextMsg(String chatId, String content, boolean safe) { + final WxCpAppChatMessage message = new WxCpAppChatMessage(); + message.setMsgType(WxCpConsts.AppChatMsgType.TEXT); + message.setContent(content); + message.setChatId(chatId); + message.setSafe(safe); + return message; + } + + /** + * 生成json字符串. + */ + public String toJson() { + JsonObject messageJson = new JsonObject(); + messageJson.addProperty("msgtype", this.getMsgType()); + messageJson.addProperty("chatid", this.getChatId()); + + if (WxConsts.KefuMsgType.TEXT.equals(this.getMsgType())) { + JsonObject text = new JsonObject(); + text.addProperty("content", this.getContent()); + messageJson.add("text", text); + } + + if (WxConsts.KefuMsgType.MARKDOWN.equals(this.getMsgType())) { + JsonObject text = new JsonObject(); + text.addProperty("content", this.getContent()); + messageJson.add("markdown", text); + } + + if (WxConsts.KefuMsgType.TEXTCARD.equals(this.getMsgType())) { + JsonObject text = new JsonObject(); + text.addProperty("title", this.getTitle()); + text.addProperty("description", this.getDescription()); + text.addProperty("url", this.getUrl()); + text.addProperty("btntxt", this.getBtnTxt()); + messageJson.add("textcard", text); + } + + if (WxConsts.KefuMsgType.IMAGE.equals(this.getMsgType())) { + JsonObject image = new JsonObject(); + image.addProperty("media_id", this.getMediaId()); + messageJson.add("image", image); + } + + if (WxConsts.KefuMsgType.FILE.equals(this.getMsgType())) { + JsonObject image = new JsonObject(); + image.addProperty("media_id", this.getMediaId()); + messageJson.add("file", image); + } + + if (WxConsts.KefuMsgType.VOICE.equals(this.getMsgType())) { + JsonObject voice = new JsonObject(); + voice.addProperty("media_id", this.getMediaId()); + messageJson.add("voice", voice); + } + + if (this.getSafe() != null && this.getSafe()) { + messageJson.addProperty("safe", 1); + } + + if (WxConsts.KefuMsgType.VIDEO.equals(this.getMsgType())) { + JsonObject video = new JsonObject(); + video.addProperty("media_id", this.getMediaId()); + video.addProperty("title", this.getTitle()); + video.addProperty("description", this.getDescription()); + messageJson.add("video", video); + } + + if (WxConsts.KefuMsgType.NEWS.equals(this.getMsgType())) { + JsonObject newsJsonObject = new JsonObject(); + JsonArray articleJsonArray = new JsonArray(); + for (NewArticle article : this.getArticles()) { + JsonObject articleJson = new JsonObject(); + articleJson.addProperty("title", article.getTitle()); + articleJson.addProperty("description", article.getDescription()); + articleJson.addProperty("url", article.getUrl()); + articleJson.addProperty("picurl", article.getPicUrl()); + articleJsonArray.add(articleJson); + } + newsJsonObject.add("articles", articleJsonArray); + messageJson.add("news", newsJsonObject); + } + + if (WxConsts.KefuMsgType.MPNEWS.equals(this.getMsgType())) { + JsonObject newsJsonObject = new JsonObject(); + if (this.getMediaId() != null) { + newsJsonObject.addProperty("media_id", this.getMediaId()); + } else { + JsonArray articleJsonArray = new JsonArray(); + for (MpnewsArticle article : this.getMpnewsArticles()) { + JsonObject articleJson = new JsonObject(); + articleJson.addProperty("title", article.getTitle()); + articleJson.addProperty("thumb_media_id", article.getThumbMediaId()); + articleJson.addProperty("author", article.getAuthor()); + articleJson.addProperty("content_source_url", article.getContentSourceUrl()); + articleJson.addProperty("content", article.getContent()); + articleJson.addProperty("digest", article.getDigest()); + articleJsonArray.add(articleJson); + } + + newsJsonObject.add("articles", articleJsonArray); + } + messageJson.add("mpnews", newsJsonObject); + } + + return messageJson.toString(); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java index 7f10d363b4..d5e74c44ff 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java @@ -1,9 +1,12 @@ package me.chanjar.weixin.cp.bean.article; -import lombok.Data; - import java.io.Serializable; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + /** *
  *  Created by BinaryWang on 2017/3/27.
@@ -12,6 +15,9 @@
  * @author Binary Wang
  */
 @Data
+@Builder
+@AllArgsConstructor
+@NoArgsConstructor
 public class NewArticle implements Serializable {
   private static final long serialVersionUID = 4087852055781140659L;
 
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java
index 8317a45ebb..4b25985f11 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java
@@ -2,15 +2,21 @@
 
 import java.util.Arrays;
 
-import me.chanjar.weixin.cp.bean.WxCpChat;
-import org.testng.Assert;
-import org.testng.annotations.Guice;
-import org.testng.annotations.Test;
+import org.testng.*;
+import org.testng.annotations.*;
 
+import com.google.common.collect.Lists;
 import com.google.inject.Inject;
-
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.WxCpConsts.AppChatMsgType;
 import me.chanjar.weixin.cp.api.ApiTestModule;
 import me.chanjar.weixin.cp.api.WxCpService;
+import me.chanjar.weixin.cp.bean.WxCpAppChatMessage;
+import me.chanjar.weixin.cp.bean.WxCpChat;
+import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
+import me.chanjar.weixin.cp.bean.article.NewArticle;
+
+import static org.assertj.core.api.Assertions.assertThat;
 
 /**
  * 测试群聊服务
@@ -19,28 +25,134 @@
  */
 @Guice(modules = ApiTestModule.class)
 public class WxCpChatServiceImplTest {
+  private String chatId;
+  private String userId;
 
   @Inject
-  private WxCpService wxCpService;
-  
+  private WxCpService cpService;
+
+  @BeforeTest
+  public void init() {
+    this.chatId = "mychatid";
+    this.userId = ((ApiTestModule.WxXmlCpInMemoryConfigStorage) this.cpService.getWxCpConfigStorage()).getUserId();
+  }
+
   @Test
-  public void create() throws Exception {
-    wxCpService.getChatService().chatCreate("测试群聊", "gaige_shen", Arrays.asList("gaige_shen", "ZhangXiaoMing"), "mychatid");
+  public void testChatCreate() throws Exception {
+    final String result = cpService.getChatService().chatCreate("测试群聊", userId,
+      Arrays.asList(userId, userId), chatId);
+    assertThat(result).isNotEmpty();
+    assertThat(result).isEqualTo(chatId);
   }
 
   @Test
-  public void get() throws Exception {
-    WxCpChat chat = wxCpService.getChatService().chatGet("mychatid");
+  public void testChatGet() throws Exception {
+    WxCpChat chat = this.cpService.getChatService().chatGet(chatId);
     System.out.println(chat);
     Assert.assertEquals(chat.getName(), "测试群聊");
   }
 
   @Test
-  public void update() throws Exception {
-    wxCpService.getChatService().chatUpdate("mychatid",  "", "", Arrays.asList("ZhengWuYao"), null);
-    WxCpChat chat = wxCpService.getChatService().chatGet("mychatid");
+  public void testChatUpdate() throws Exception {
+    this.cpService.getChatService().chatUpdate(chatId, "", "", Arrays.asList("ZhengWuYao"), null);
+    WxCpChat chat = this.cpService.getChatService().chatGet(chatId);
     System.out.println(chat);
     Assert.assertEquals(chat.getUsers().size(), 3);
   }
 
+  @DataProvider
+  public Object[][] messages() {
+    return new Object[][]{
+      {WxCpAppChatMessage.builder()
+        .msgType(AppChatMsgType.TEXT)
+        .chatId(chatId)
+        .content("你的快递已到\n请携带工卡前往邮件中心领取")
+        .build()
+      },
+      {WxCpAppChatMessage.builder()
+        .msgType(AppChatMsgType.IMAGE)
+        .chatId(chatId)
+        .mediaId("3_xWGPXZhpOKZrlRISWrjhPrDUZqZ-jIEVzxd56jLuqM")
+        .build()
+      },
+      {WxCpAppChatMessage.builder()
+        .msgType(AppChatMsgType.VOICE)
+        .chatId(chatId)
+        .mediaId("3X5t6HkdN1hUgB7OzrdRnc8v0yI0CqlAxFxnCkS3msTnTLanpYrV4esLv4foZVnlf")
+        .build()
+      },
+      {WxCpAppChatMessage.builder()
+        .msgType(AppChatMsgType.VIDEO)
+        .chatId(chatId)
+        .mediaId("3otWyy_acbID8fyltmCOW5hGVD8oa0_p0za5jhukxKTUDoGT71lqTvtQAWoycXpQf")
+        .title("aaaa")
+        .description("ddddd")
+        .build()
+      },
+      {WxCpAppChatMessage.builder()
+        .msgType(AppChatMsgType.FILE)
+        .chatId(chatId)
+        .mediaId("34AyVyDdndVhB4Z2tT-_FYKZ7Xqrr47LPC11GHH4oy7o")
+        .build()
+      },
+      {WxCpAppChatMessage.builder()
+        .msgType(AppChatMsgType.TEXTCARD)
+        .chatId(chatId)
+        .btnTxt("更多")
+        .title("领奖通知")
+        .url("https://zhidao.baidu.com/question/2073647112026042748.html")
+        .description("
2016年9月26日
恭喜你抽中iPhone 7一台,领奖码:520258
请于2016年10月10日前联系行 政同事领取
") + .build() + }, + {WxCpAppChatMessage.builder() + .msgType(AppChatMsgType.NEWS) + .chatId(chatId) + .articles(Lists.newArrayList(NewArticle.builder() + .title("领奖通知") + .url("https://zhidao.baidu.com/question/2073647112026042748.html") + .description("今年中秋节公司有豪礼相送") + .picUrl("http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png") + .build() + )) + .build() + }, + {WxCpAppChatMessage.builder() + .msgType(AppChatMsgType.MPNEWS) + .chatId(chatId) + .mpnewsArticles(Lists.newArrayList(MpnewsArticle.newBuilder() + .title("地球一小时") + .thumbMediaId("3_xWGPXZhpOKZrlRISWrjhPrDUZqZ-jIEVzxd56jLuqM") + .author("Author") + .contentSourceUrl("https://work.weixin.qq.com") + .content("3月24日20:30-21:30 \n办公区将关闭照明一小时,请各部门同事相互转告") + .digest("3月24日20:30-21:30 \n办公区将关闭照明一小时") + .build() + )) + .build() + }, + {WxCpAppChatMessage.builder() + .msgType(AppChatMsgType.MARKDOWN) + .chatId(chatId) + .content("您的会议室已经预定,稍后会同步到`邮箱` \n" + + " >**事项详情** \n" + + " >事 项:开会 \n" + + " >组织者:@miglioguan \n" + + " >参与者:@miglioguan、@kunliu、@jamdeezhou、@kanexiong、@kisonwang \n" + + " > \n" + + " >会议室:广州TIT 1楼 301 \n" + + " >日 期:2018年5月18日 \n" + + " >时 间:上午9:00-11:00 \n" + + " > \n" + + " >请准时参加会议。 \n" + + " > \n" + + " >如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)") + .build() + }, + }; + } + + @Test(dataProvider = "messages") + public void testSendMsg(WxCpAppChatMessage message) throws WxErrorException { + this.cpService.getChatService().sendMsg(message); + } } diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoInMemoryConfigStorage.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoInMemoryConfigStorage.java index 93ff1bbc0a..cbb3503760 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoInMemoryConfigStorage.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoInMemoryConfigStorage.java @@ -1,28 +1,23 @@ package me.chanjar.weixin.cp.demo; +import java.io.InputStream; + import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.ToString; import me.chanjar.weixin.common.util.xml.XStreamInitializer; import me.chanjar.weixin.cp.config.WxCpInMemoryConfigStorage; -import java.io.InputStream; - /** * @author Daniel Qian */ @XStreamAlias("xml") -class WxCpDemoInMemoryConfigStorage extends WxCpInMemoryConfigStorage { - +@ToString +public class WxCpDemoInMemoryConfigStorage extends WxCpInMemoryConfigStorage { public static WxCpDemoInMemoryConfigStorage fromXml(InputStream is) { XStream xstream = XStreamInitializer.getInstance(); xstream.processAnnotations(WxCpDemoInMemoryConfigStorage.class); return (WxCpDemoInMemoryConfigStorage) xstream.fromXML(is); } - @Override - public String toString() { - return "SimpleWxConfigProvider [appidOrCorpid=" + this.corpId + ", corpSecret=" + this.corpSecret + ", accessToken=" + this.accessToken - + ", expiresTime=" + this.expiresTime + ", token=" + this.token + ", aesKey=" + this.aesKey + "]"; - } - } From cf549eaed38cfb11ea498e5508310142263e660b Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 26 Jan 2019 15:27:36 +0800 Subject: [PATCH 24/81] =?UTF-8?q?=E5=8F=91=E5=B8=833.3.4.B=20=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- weixin-java-common/pom.xml | 2 +- weixin-java-cp/pom.xml | 2 +- weixin-java-miniapp/pom.xml | 2 +- weixin-java-mp/pom.xml | 2 +- weixin-java-open/pom.xml | 2 +- weixin-java-pay/pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 503bb5639a..b8f88ef8b7 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.github.binarywang wx-java - 3.3.3.B + 3.3.4.B pom WxJava - Weixin/Wechat Java SDK 微信开发Java SDK diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index f0cdad4260..6a153612a6 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.3.B + 3.3.4.B weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index b8d9d82d27..7bf4acca36 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.3.B + 3.3.4.B weixin-java-cp diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index 4c70f78229..7bec0add26 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.3.B + 3.3.4.B weixin-java-miniapp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 2c32c42657..86b1c89104 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.3.B + 3.3.4.B weixin-java-mp diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index bf9d0560a8..73096345c0 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.3.B + 3.3.4.B weixin-java-open diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index 3b481619c0..f76a66206b 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ com.github.binarywang wx-java - 3.3.3.B + 3.3.4.B 4.0.0 From 014fb283549b3f8f23fc791f182c83b377173443 Mon Sep 17 00:00:00 2001 From: Hipple <1159828430@qq.com> Date: Sun, 27 Jan 2019 15:18:47 +0800 Subject: [PATCH 25/81] =?UTF-8?q?#932=20=E5=A2=9E=E5=8A=A0=E7=AC=AC?= =?UTF-8?q?=E4=B8=89=E6=96=B9=E5=B9=B3=E5=8F=B0=E5=BF=AB=E9=80=9F=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E5=B0=8F=E7=A8=8B=E5=BA=8F=E6=8E=A5=E5=8F=A3=E5=8F=8A?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E7=9A=84=E4=BF=A1=E6=81=AF=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add 接收API创建小程序成功的消息推送 实现快速创建小程序的新建、查询接口 增加WxOpenFastMaService(API创建的小程序专用的接口) * Add 实现小程序名称设置及改名、微信认证名称检测、修改头像、修改功能介绍接口 * Add 实现所有通过API创建的小程序专属接口及相关结果类 * Add 添加三个复杂实体的单体测试 * Update 修复WxFastMaService 8.1接口:因为不同类目含有特定字段,目前没有完整的类目信息数据,为保证兼容性,放弃将response转换为实体 * Update 将快速创建小程序接口返回值更改为WxOpenResult --- .../open/api/WxOpenComponentService.java | 49 ++++ .../weixin/open/api/WxOpenFastMaService.java | 188 +++++++++++++ .../api/impl/WxOpenComponentServiceImpl.java | 55 +++- .../api/impl/WxOpenFastMaServiceImpl.java | 256 ++++++++++++++++++ .../open/bean/fastma/WxFastMaCategory.java | 36 +++ .../open/bean/message/WxOpenXmlMessage.java | 60 +++- .../WxFastMaAccountBasicInfoResult.java | 135 +++++++++ .../result/WxFastMaBeenSetCategoryResult.java | 73 +++++ .../result/WxFastMaCanSetCategoryResult.java | 58 ++++ .../result/WxFastMaCheckNickameResult.java | 29 ++ .../WxFastMaQueryNicknameStatusResult.java | 43 +++ .../bean/result/WxFastMaSetNickameResult.java | 29 ++ .../WxFastMaAccountBasicInfoGsonAdapter.java | 44 +++ .../open/util/json/WxOpenGsonBuilder.java | 3 + .../WxFastMaAccountBasicInfoResultTest.java | 51 ++++ .../WxFastMaBeenSetCategoryResultTest.java | 40 +++ .../WxFastMaCanSetCategoryResultTest.java | 79 ++++++ .../src/test/resources/logback-test.xml | 13 + .../src/test/resources/test-config.sample.xml | 7 + .../src/test/resources/testng.xml | 11 + 20 files changed, 1247 insertions(+), 12 deletions(-) create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenFastMaService.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenFastMaServiceImpl.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/fastma/WxFastMaCategory.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaAccountBasicInfoResult.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaBeenSetCategoryResult.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaCanSetCategoryResult.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaCheckNickameResult.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaQueryNicknameStatusResult.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaSetNickameResult.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxFastMaAccountBasicInfoGsonAdapter.java create mode 100644 weixin-java-open/src/test/java/me/chanjar/weixin/open/bean/result/WxFastMaAccountBasicInfoResultTest.java create mode 100644 weixin-java-open/src/test/java/me/chanjar/weixin/open/bean/result/WxFastMaBeenSetCategoryResultTest.java create mode 100644 weixin-java-open/src/test/java/me/chanjar/weixin/open/bean/result/WxFastMaCanSetCategoryResultTest.java create mode 100644 weixin-java-open/src/test/resources/logback-test.xml create mode 100644 weixin-java-open/src/test/resources/test-config.sample.xml create mode 100644 weixin-java-open/src/test/resources/testng.xml diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java index 0ae803fccf..7016bd1b6c 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java @@ -10,6 +10,7 @@ import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; +import me.chanjar.weixin.open.bean.result.WxOpenResult; import java.util.List; @@ -26,6 +27,7 @@ public interface WxOpenComponentService { String API_SET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/api_set_authorizer_option"; String COMPONENT_LOGIN_PAGE_URL = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=%s&pre_auth_code=%s&redirect_uri=%s"; + /** * 手机端打开授权链接 */ @@ -45,6 +47,13 @@ public interface WxOpenComponentService { String CREATE_OPEN_URL= "https://api.weixin.qq.com/cgi-bin/open/create"; + /** + * 快速创建小程序接口 + */ + String FAST_REGISTER_WEAPP_URL = "https://api.weixin.qq.com/cgi-bin/component/fastregisterweapp?action=create"; + String FAST_REGISTER_WEAPP_SEARCH_URL = "https://api.weixin.qq.com/cgi-bin/component/fastregisterweapp?action=search"; + + WxMpService getWxMpServiceByAppid(String appid); /** @@ -55,6 +64,13 @@ public interface WxOpenComponentService { */ WxOpenMaService getWxMaServiceByAppid(String appid); + /** + * 获取指定appid的快速创建的小程序服务 + * @param appid + * @return + */ + WxOpenFastMaService getWxFastMaServiceByAppid(String appid); + WxOpenConfigStorage getWxOpenConfigStorage(); boolean checkSignature(String timestamp, String nonce, String signature); @@ -182,4 +198,37 @@ public interface WxOpenComponentService { * @return */ WxOpenCreateResult createOpenAccount(String appId) throws WxErrorException; + + /** + * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=21538208049W8uwq&token=&lang=zh_CN + * 第三方平台快速创建小程序 + *
+   *      注意:创建任务逻辑串行,单次任务结束后才可以使用相同信息下发第二次任务,请注意规避任务阻塞
+   *  
+ * @param name 企业名(需与工商部门登记信息一致) + * @param code 企业代码 + * @param codeType 企业代码类型 1:统一社会信用代码(18位) 2:组织机构代码(9位xxxxxxxx-x) 3:营业执照注册号(15位) + * @param legalPersonaWechat 法人微信号 + * @param legalPersonaName 法人姓名(绑定银行卡) + * @param componentPhone 第三方联系电话(方便法人与第三方联系) + * @return + * @throws WxErrorException + */ + WxOpenResult fastRegisterWeapp(String name, String code, String codeType, String legalPersonaWechat, String legalPersonaName, String componentPhone) throws WxErrorException; + + /** + * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=21538208049W8uwq&token=&lang=zh_CN + * 查询第三方平台快速创建小程序的任务状态 + *
+   *      注意:该接口只提供当下任务结果查询,不建议过分依赖该接口查询所创建小程序。
+   *            小程序的成功状态可在第三方服务器中自行对账、查询。
+   *            不要频繁调用search接口,消息接收需通过服务器查看。调用search接口会消耗接口整体调用quato
+   *  
+ * + * @param name 企业名(需与工商部门登记信息一致) + * @param legalPersonaWechat 法人微信号 + * @param legalPersonaName 法人姓名(绑定银行卡) + * @throws WxErrorException + */ + WxOpenResult fastRegisterWeappSearch(String name, String legalPersonaWechat, String legalPersonaName) throws WxErrorException; } diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenFastMaService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenFastMaService.java new file mode 100644 index 0000000000..987a6b9793 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenFastMaService.java @@ -0,0 +1,188 @@ +package me.chanjar.weixin.open.api; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.open.bean.fastma.WxFastMaCategory; +import me.chanjar.weixin.open.bean.result.*; + +import java.util.List; + +/** + *
+ *     微信开放平台【快速创建小程序】的专用接口
+ *     https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=21528465979XX32V&token=&lang=zh_CN
+ *    注意:该类的接口仅限通过快速创建小程序接口的小程序使用
+ * 
+ * TODO 完善相应API的respons实体 + * + * @author Hipple + * @date 2019/01/23 + */ +public interface WxOpenFastMaService extends WxMaService { + + /** + * 1 获取帐号基本信息 + */ + String OPEN_GET_ACCOUNT_BASIC_INFO = "https://api.weixin.qq.com/cgi-bin/account/getaccountbasicinfo"; + + /** + * 2 小程序名称设置及改名 + */ + String OPEN_SET_NICKNAME = "https://api.weixin.qq.com/wxa/setnickname"; + + /** + * 3 小程序改名审核状态查询 + */ + String OPEN_API_WXA_QUERYNICKNAME = "https://api.weixin.qq.com/wxa/api_wxa_querynickname"; + + /** + * 4 微信认证名称检测 + */ + String OPEN_CHECK_WX_VERIFY_NICKNAME = "https://api.weixin.qq.com/cgi-bin/wxverify/checkwxverifynickname"; + + /** + * 5 修改头像 + */ + String OPEN_MODIFY_HEADIMAGE = "https://api.weixin.qq.com/cgi-bin/account/modifyheadimage"; + + /** + * 6修改功能介绍 + */ + String OPEN_MODIFY_SIGNATURE = "https://api.weixin.qq.com/cgi-bin/account/modifysignature"; + + /** + * 7 换绑小程序管理员接口 + */ + String OPEN_COMPONENT_REBIND_ADMIN = "https://api.weixin.qq.com/cgi- bin/account/componentrebindadmin"; + + /** + * 8.1 获取账号可以设置的所有类目 + */ + String OPEN_GET_ALL_CATEGORIES = "https://api.weixin.qq.com/cgi-bin/wxopen/getallcategories"; + /** + * 8.2 添加类目 + */ + String OPEN_ADD_CATEGORY = "https://api.weixin.qq.com/cgi-bin/wxopen/addcategory"; + /** + * 8.3 删除类目 + */ + String OPEN_DELETE_CATEGORY = "https://api.weixin.qq.com/cgi-bin/wxopen/deletecategory"; + /** + * 8.4 获取账号已经设置的所有类目 + */ + String OPEN_GET_CATEGORY = "https://api.weixin.qq.com/cgi-bin/wxopen/getcategory"; + /** + * 8.5 修改类目 + */ + String OPEN_MODIFY_CATEGORY = "https://api.weixin.qq.com/cgi-bin/wxopen/modifycategory"; + + + /** + * 1.获取小程序的信息 + * + * @return + * @throws WxErrorException + */ + WxFastMaAccountBasicInfoResult getAccountBasicInfo() throws WxErrorException; + + /** + * 2.小程序名称设置及改名 + *
+   *      若接口未返回audit_id,说明名称已直接设置成功,无需审核;若返回audit_id则名称正在审核中。
+   *  
+ * @param nickname 昵称 + * @param idCard 身份证照片–临时素材mediaid(个人号必填) + * @param license 组织机构代码证或营业执照–临时素材mediaid(组织号必填) + * @param namingOtherStuff1 其他证明材料---临时素材 mediaid + * @param namingOtherStuff2 其他证明材料---临时素材 mediaid + * @throws WxErrorException + */ + WxFastMaSetNickameResult setNickname(String nickname, String idCard, String license, String namingOtherStuff1, String namingOtherStuff2) throws WxErrorException; + + /** + * 3 小程序改名审核状态查询 + * @param auditId 审核单id + * @return + * @throws WxErrorException + */ + WxFastMaQueryNicknameStatusResult querySetNicknameStatus(String auditId) throws WxErrorException; + + /** + * 4. 微信认证名称检测 + * @param nickname 名称 + * @throws WxErrorException + */ + WxFastMaCheckNickameResult checkWxVerifyNickname(String nickname) throws WxErrorException; + + /** + * 5.修改头像 + *
+   *     图片格式只支持:BMP、JPEG、JPG、GIF、PNG,大小不超过2M
+   *      注:实际头像始终为正方形
+   * 
+ * @param headImgMediaId 头像素材media_id + * @param x1 裁剪框左上角x坐标(取值范围:[0, 1]) + * @param y1 裁剪框左上角y坐标(取值范围:[0, 1]) + * @param x2 裁剪框右下角x坐标(取值范围:[0, 1]) + * @param y2 裁剪框右下角y坐标(取值范围:[0, 1]) + * @throws WxErrorException + */ + WxOpenResult modifyHeadImage(String headImgMediaId, float x1, float y1, float x2, float y2) throws WxErrorException; + + /** + * 6.修改功能介绍 + * @param signature 简介:4-120字 + * @throws WxErrorException + */ + WxOpenResult modifySignature(String signature) throws WxErrorException; + + /** + * 7.3 管理员换绑 + * @param taskid 换绑管理员任务序列号(公众平台最终点击提交回跳到第三方平台时携带) + * @return + * @throws WxErrorException + */ + WxOpenResult componentRebindAdmin(String taskid) throws WxErrorException; + + /** + * 8.1 获取账号可以设置的所有类目 + *
+   *     因为不同类目含有特定字段
+   *     目前没有完整的类目信息数据
+   *     为保证兼容性,放弃将response转换为实体
+   * 
+ * @return + */ + String getAllCategories() throws WxErrorException; + + /** + *8.2添加类目 + * @return + * @throws WxErrorException + */ + WxOpenResult addCategory(List categoryList) throws WxErrorException; + + /** + * 8.3删除类目 + * @param first 一级类目ID + * @param second 二级类目ID + * @return + * @throws WxErrorException + */ + WxOpenResult deleteCategory(int first, int second) throws WxErrorException; + + /** + * 8.4获取账号已经设置的所有类目 + * @return + * @throws WxErrorException + */ + WxFastMaBeenSetCategoryResult getCategory() throws WxErrorException; + + /** + * 8.5修改类目 + * @param category 实体 + * @return + * @throws WxErrorException + */ + WxOpenResult modifyCategory(WxFastMaCategory category) throws WxErrorException; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java index 4c2a0ee275..8c4cad0071 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java @@ -11,10 +11,7 @@ import me.chanjar.weixin.common.util.json.WxGsonBuilder; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; -import me.chanjar.weixin.open.api.WxOpenComponentService; -import me.chanjar.weixin.open.api.WxOpenConfigStorage; -import me.chanjar.weixin.open.api.WxOpenMaService; -import me.chanjar.weixin.open.api.WxOpenService; +import me.chanjar.weixin.open.api.*; import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; import me.chanjar.weixin.open.bean.WxOpenCreateResult; @@ -24,6 +21,7 @@ import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; +import me.chanjar.weixin.open.bean.result.WxOpenResult; import me.chanjar.weixin.open.util.json.WxOpenGsonBuilder; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -40,6 +38,7 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService { private static final JsonParser JSON_PARSER = new JsonParser(); private static final Map WX_OPEN_MA_SERVICE_MAP = new Hashtable<>(); private static final Map WX_OPEN_MP_SERVICE_MAP = new Hashtable<>(); + private static final Map WX_OPEN_FAST_MA_SERVICE_MAP = new Hashtable<>(); protected final Logger log = LoggerFactory.getLogger(this.getClass()); private WxOpenService wxOpenService; @@ -79,6 +78,21 @@ public WxOpenMaService getWxMaServiceByAppid(String appId) { return wxOpenMaService; } + @Override + public WxOpenFastMaService getWxFastMaServiceByAppid(String appId) { + WxOpenFastMaService fastMaService = WX_OPEN_FAST_MA_SERVICE_MAP.get(appId); + if (fastMaService == null) { + synchronized (WX_OPEN_FAST_MA_SERVICE_MAP) { + fastMaService = WX_OPEN_FAST_MA_SERVICE_MAP.get(appId); + if (fastMaService == null) { + fastMaService = new WxOpenFastMaServiceImpl(this, appId, getWxOpenConfigStorage().getWxMaConfig(appId)); + WX_OPEN_FAST_MA_SERVICE_MAP.put(appId, fastMaService); + } + } + } + return fastMaService; + } + public WxOpenService getWxOpenService() { return wxOpenService; } @@ -238,7 +252,7 @@ public String route(final WxOpenXmlMessage wxMessage) throws WxErrorException { getWxOpenConfigStorage().setComponentVerifyTicket(wxMessage.getComponentVerifyTicket()); return "success"; } - //新增、跟新授权 + //新增、更新授权 if (StringUtils.equalsAnyIgnoreCase(wxMessage.getInfoType(), "authorized", "updateauthorized")) { WxOpenQueryAuthResult queryAuth = wxOpenService.getWxOpenComponentService().getQueryAuth(wxMessage.getAuthorizationCode()); if (queryAuth == null || queryAuth.getAuthorizationInfo() == null || queryAuth.getAuthorizationInfo().getAuthorizerAppid() == null) { @@ -246,6 +260,14 @@ public String route(final WxOpenXmlMessage wxMessage) throws WxErrorException { } return "success"; } + //快速创建小程序 + if (StringUtils.equalsIgnoreCase(wxMessage.getInfoType(), "notify_third_fasteregister") && wxMessage.getStatus () == 0) { + WxOpenQueryAuthResult queryAuth = wxOpenService.getWxOpenComponentService().getQueryAuth(wxMessage.getAuthCode ()); + if (queryAuth == null || queryAuth.getAuthorizationInfo() == null || queryAuth.getAuthorizationInfo().getAuthorizerAppid() == null) { + throw new NullPointerException("getQueryAuth"); + } + return "success"; + } return ""; } @@ -398,4 +420,27 @@ public WxOpenCreateResult createOpenAccount(String appId) throws WxErrorExceptio return WxOpenCreateResult.fromJson(json); } + + @Override + public WxOpenResult fastRegisterWeapp(String name, String code, String codeType, String legalPersonaWechat, String legalPersonaName, String componentPhone) throws WxErrorException{ + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("name",name); + jsonObject.addProperty("code", code); + jsonObject.addProperty("code_type", codeType); + jsonObject.addProperty("legal_persona_wechat", legalPersonaWechat); + jsonObject.addProperty("legal_persona_name", legalPersonaName); + jsonObject.addProperty("component_phone", componentPhone); + String response = post(FAST_REGISTER_WEAPP_URL, jsonObject.toString (), "component_access_token"); + return WxOpenGsonBuilder.create ().fromJson (response, WxOpenResult.class); + } + + @Override + public WxOpenResult fastRegisterWeappSearch(String name, String legalPersonaWechat, String legalPersonaName) throws WxErrorException{ + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("name",name); + jsonObject.addProperty("legal_persona_wechat", legalPersonaWechat); + jsonObject.addProperty("legal_persona_name", legalPersonaName); + String response = post(FAST_REGISTER_WEAPP_SEARCH_URL, jsonObject.toString (), "component_access_token"); + return WxOpenGsonBuilder.create ().fromJson (response, WxOpenResult.class); + } } diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenFastMaServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenFastMaServiceImpl.java new file mode 100644 index 0000000000..1314f37f44 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenFastMaServiceImpl.java @@ -0,0 +1,256 @@ +package me.chanjar.weixin.open.api.impl; + +import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; +import cn.binarywang.wx.miniapp.config.WxMaConfig; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.open.api.WxOpenComponentService; +import me.chanjar.weixin.open.api.WxOpenFastMaService; +import me.chanjar.weixin.open.bean.fastma.WxFastMaCategory; +import me.chanjar.weixin.open.bean.result.*; +import me.chanjar.weixin.open.util.json.WxOpenGsonBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author Hipple + * @description + * @since 2019/1/23 15:27 + */ +public class WxOpenFastMaServiceImpl extends WxMaServiceImpl implements WxOpenFastMaService { + + protected final Logger log = LoggerFactory.getLogger (this.getClass ()); + + private WxOpenComponentService wxOpenComponentService; + private WxMaConfig wxMaConfig; + private String appId; + + public WxOpenFastMaServiceImpl (WxOpenComponentService wxOpenComponentService, String appId, WxMaConfig wxMaConfig) { + this.wxOpenComponentService = wxOpenComponentService; + this.appId = appId; + this.wxMaConfig = wxMaConfig; + initHttp (); + } + + @Override + public WxMaConfig getWxMaConfig () { + return wxMaConfig; + } + + @Override + public String getAccessToken (boolean forceRefresh) throws WxErrorException { + return wxOpenComponentService.getAuthorizerAccessToken (appId, forceRefresh); + } + + /** + * 1.获取小程序的信息,GET请求 + *
+   *     注意:这里不能直接用小程序的access_token
+   * 
+ * + * @return + * @throws WxErrorException + */ + @Override + public WxFastMaAccountBasicInfoResult getAccountBasicInfo () throws WxErrorException { + String response = get (OPEN_GET_ACCOUNT_BASIC_INFO, ""); + return WxOpenGsonBuilder.create ().fromJson (response, WxFastMaAccountBasicInfoResult.class); + } + + /** + * 2.小程序名称设置及改名 + * + * @param nickname 昵称 + * @param idCard 身份证照片–临时素材mediaid(个人号必填) + * @param license 组织机构代码证或营业执照–临时素材mediaid(组织号必填) + * @param namingOtherStuff1 其他证明材料---临时素材 mediaid + * @param namingOtherStuff2 其他证明材料---临时素材 mediaid + * @throws WxErrorException + */ + @Override + public WxFastMaSetNickameResult setNickname (String nickname, String idCard, String license, String namingOtherStuff1, String namingOtherStuff2) throws WxErrorException { + JsonObject params = new JsonObject (); + params.addProperty ("nick_name", nickname); + params.addProperty ("id_card", idCard); + params.addProperty ("license", license); + params.addProperty ("naming_other_stuff_1", namingOtherStuff1); + params.addProperty ("naming_other_stuff_2", namingOtherStuff2); + String response = post (OPEN_SET_NICKNAME, GSON.toJson (params)); + return WxOpenGsonBuilder.create ().fromJson (response, WxFastMaSetNickameResult.class); + } + + /** + * 3 小程序改名审核状态查询 + * + * @param auditId 审核单id + * @return + * @throws WxErrorException + */ + @Override + public WxFastMaQueryNicknameStatusResult querySetNicknameStatus (String auditId) throws WxErrorException { + JsonObject params = new JsonObject (); + params.addProperty ("audit_id", auditId); + String response = post (OPEN_API_WXA_QUERYNICKNAME, GSON.toJson (params)); + return WxOpenGsonBuilder.create ().fromJson (response, WxFastMaQueryNicknameStatusResult.class); + } + + /** + * 4. 微信认证名称检测 + *
+   *      命中关键字策略时返回命中关键字的说明描述
+   *  
+ * + * @param nickname 名称 + * @throws WxErrorException + */ + @Override + public WxFastMaCheckNickameResult checkWxVerifyNickname (String nickname) throws WxErrorException { + JsonObject params = new JsonObject (); + params.addProperty ("nick_name", nickname); + String response = post (OPEN_CHECK_WX_VERIFY_NICKNAME, GSON.toJson (params)); + return WxOpenGsonBuilder.create ().fromJson (response, WxFastMaCheckNickameResult.class); + } + + /** + * 5.修改头像 + *
+   *     图片格式只支持:BMP、JPEG、JPG、GIF、PNG,大小不超过2M
+   *      注:实际头像始终为正方形
+   * 
+ * + * @param headImgMediaId 头像素材media_id + * @param x1 裁剪框左上角x坐标(取值范围:[0, 1]) + * @param y1 裁剪框左上角y坐标(取值范围:[0, 1]) + * @param x2 裁剪框右下角x坐标(取值范围:[0, 1]) + * @param y2 裁剪框右下角y坐标(取值范围:[0, 1]) + * @throws WxErrorException + */ + @Override + public WxOpenResult modifyHeadImage (String headImgMediaId, float x1, float y1, float x2, float y2) throws WxErrorException { + JsonObject params = new JsonObject (); + params.addProperty ("head_img_media_id", headImgMediaId); + params.addProperty ("x1", x1); + params.addProperty ("y1", y1); + params.addProperty ("x2", x2); + params.addProperty ("y2", y2); + String response = post (OPEN_MODIFY_HEADIMAGE, GSON.toJson (params)); + return WxOpenGsonBuilder.create ().fromJson (response, WxOpenResult.class); + } + + /** + * 6.修改功能介绍 + * + * @param signature 简介:4-120字 + * @throws WxErrorException + */ + @Override + public WxOpenResult modifySignature (String signature) throws WxErrorException { + JsonObject params = new JsonObject (); + params.addProperty ("signature", signature); + String response = post (OPEN_MODIFY_SIGNATURE, GSON.toJson (params)); + return WxOpenGsonBuilder.create ().fromJson (response, WxOpenResult.class); + } + + /** + * 7.3 管理员换绑 + * + * @param taskid 换绑管理员任务序列号(公众平台最终点击提交回跳到第三方平台时携带) + * @return + * @throws WxErrorException + */ + @Override + public WxOpenResult componentRebindAdmin (String taskid) throws WxErrorException { + JsonObject params = new JsonObject (); + params.addProperty ("taskid", taskid); + String response = post (OPEN_COMPONENT_REBIND_ADMIN, GSON.toJson (params)); + return WxOpenGsonBuilder.create ().fromJson (response, WxOpenResult.class); + } + + /** + * 8.1 获取账号可以设置的所有类目 + * + * @return + */ + @Override + public String getAllCategories () throws WxErrorException { + return get (OPEN_GET_ALL_CATEGORIES, ""); + } + + /** + * 8.2添加类目 + * + * @param categoryList + * @return + * @throws WxErrorException + */ + @Override + public WxOpenResult addCategory (List categoryList) throws WxErrorException { + Map map = new HashMap<> (); + map.put ("categories", categoryList); + String response = post (OPEN_ADD_CATEGORY, WxOpenGsonBuilder.create ().toJson (map)); + return WxOpenGsonBuilder.create ().fromJson (response, WxOpenResult.class); + } + + /** + * 8.3删除类目 + * + * @param first 一级类目ID + * @param second 二级类目ID + * @return + * @throws WxErrorException + */ + @Override + public WxOpenResult deleteCategory (int first, int second) throws WxErrorException { + JsonObject params = new JsonObject (); + params.addProperty ("first", first); + params.addProperty ("Second", second); + String response = post (OPEN_DELETE_CATEGORY, GSON.toJson (params)); + return WxOpenGsonBuilder.create ().fromJson (response, WxOpenResult.class); + } + + /** + * 8.4获取账号已经设置的所有类目 + * + * @return + * @throws WxErrorException + */ + @Override + public WxFastMaBeenSetCategoryResult getCategory () throws WxErrorException { + String response = get (OPEN_GET_CATEGORY, ""); + return WxOpenGsonBuilder.create ().fromJson (response, WxFastMaBeenSetCategoryResult.class); + } + + /** + * 8.5修改类目 + * + * @param category 实体 + * @return + * @throws WxErrorException + */ + @Override + public WxOpenResult modifyCategory (WxFastMaCategory category) throws WxErrorException { + String response = post (OPEN_MODIFY_CATEGORY, GSON.toJson (category)); + return WxOpenGsonBuilder.create ().fromJson (response, WxOpenResult.class); + } + + /** + * 将字符串对象转化为GsonArray对象 + * + * @param strList + * @return + */ + private JsonArray toJsonArray (List strList) { + JsonArray jsonArray = new JsonArray (); + if (strList != null && ! strList.isEmpty ()) { + for (String str : strList) { + jsonArray.add (str); + } + } + return jsonArray; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/fastma/WxFastMaCategory.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/fastma/WxFastMaCategory.java new file mode 100644 index 0000000000..b854877a87 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/fastma/WxFastMaCategory.java @@ -0,0 +1,36 @@ +package me.chanjar.weixin.open.bean.fastma; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author Hipple + * @description 修改更新类目所需实体 + * @since 2019/1/25 10:49 + */ +@Data +public class WxFastMaCategory implements Serializable { + + /** + * 一级类目ID + */ + private int first; + + /** + * 二级类目ID + */ + private int second; + + /** + * 资质信息 + */ + private List certicates; + + @Data + public class certicaty { + private String key; + private String value; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java index a6ba9945d3..0473cc3c5e 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenXmlMessage.java @@ -1,12 +1,5 @@ package me.chanjar.weixin.open.bean.message; -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.nio.charset.StandardCharsets; - -import org.apache.commons.io.IOUtils; - import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; import lombok.Data; @@ -17,6 +10,12 @@ import me.chanjar.weixin.open.api.WxOpenConfigStorage; import me.chanjar.weixin.open.util.WxOpenCryptUtil; import me.chanjar.weixin.open.util.xml.XStreamTransformer; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.nio.charset.StandardCharsets; /** * @author 007 @@ -57,6 +56,53 @@ public class WxOpenXmlMessage implements Serializable { @XStreamConverter(value = XStreamCDataConverter.class) private String preAuthCode; + // 以下为快速创建小程序接口推送的的信息 + + @XStreamAlias ("appid") + private String registAppId; + + @XStreamAlias ("status") + private int status; + + @XStreamAlias ("auth_code") + private String authCode; + + @XStreamAlias ("msg") + @XStreamConverter (value = XStreamCDataConverter.class) + private String msg; + + @XStreamAlias ("info") + private Info info = new Info(); + + @XStreamAlias ("info") + @Data + public static class Info implements Serializable { + private static final long serialVersionUID = 7706235740094081194L; + + @XStreamAlias ("name") + @XStreamConverter (value = XStreamCDataConverter.class) + private String name; + + @XStreamAlias ("code") + @XStreamConverter (value = XStreamCDataConverter.class) + private String code; + + @XStreamAlias ("code_type") + private int codeType; + + @XStreamAlias ("legal_persona_wechat") + @XStreamConverter (value = XStreamCDataConverter.class) + private String legalPersonaWechat; + + @XStreamAlias ("legal_persona_name") + @XStreamConverter (value = XStreamCDataConverter.class) + private String legalPersonaName; + + @XStreamAlias ("component_phone") + @XStreamConverter (value = XStreamCDataConverter.class) + private String componentPhone; + } + public static String wxMpOutXmlMessageToEncryptedXml(WxMpXmlOutMessage message, WxOpenConfigStorage wxOpenConfigStorage) { String plainXml = message.toXml(); WxOpenCryptUtil pc = new WxOpenCryptUtil(wxOpenConfigStorage); diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaAccountBasicInfoResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaAccountBasicInfoResult.java new file mode 100644 index 0000000000..b8bf8d83ba --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaAccountBasicInfoResult.java @@ -0,0 +1,135 @@ +package me.chanjar.weixin.open.bean.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author Hipple + * @description 快速创建的小程序的账号基本信息 + * @since 2019/1/23 14:39 + */ +@Data +@EqualsAndHashCode (callSuper = true) +public class WxFastMaAccountBasicInfoResult extends WxOpenResult{ + private static final long serialVersionUID = - 8713680081353954208L; + + /** + * 小程序ID + */ + @SerializedName ("appid") + private String appId; + + /** + * 帐号类型(1:订阅号,2:服务号,3:小程序) + */ + @SerializedName ("account_type") + private Integer accountType; + + /** + * 主体类型(1:企业) + */ + @SerializedName ("principal_type") + private Integer principalType; + + /** + * 主体名称 + */ + @SerializedName ("principal_name") + private String principalName; + + /** + * 实名验证状态(1:实名验证成功,2:实名验证中,3:实名验证失败)调用接口1.1创建帐号时,realname_status会初始化为2对于注册方式为微信认证的帐号,资质认证成功时,realname_status会更新为1 注意!!!当realname_status不为1时,帐号只允许调用本文档内的以下API:(即无权限调用其他API) 微信认证相关接口(参考2.x) 帐号设置相关接口(参考3.x) + */ + @SerializedName ("realname_status") + private Integer realnameStatus; + + + /** + * 微信认证信息 + */ + @SerializedName ("wx_verify_info") + private WxVerifyInfo wxVerifyInfo; + /** + * 功能介绍信息 + */ + @SerializedName ("signature_info") + private SignatureInfo signatureInfo; + /** + * 头像信息 + */ + @SerializedName ("head_image_info") + private HeadImageInfo headImageInfo; + + @Data + public static class WxVerifyInfo { + /** + * 是否资质认证(true:是,false:否)若是,拥有微信认证相关的权限 + */ + @SerializedName ("qualification_verify") + private Boolean qualificationVerify; + /** + * 是否名称认证(true:是,false:否)对于公众号(订阅号、服务号),是名称认证,微信客户端才会有微信认证打勾的标识。 + */ + @SerializedName ("naming_verify") + private Boolean namingVerify; + /** + * 是否需要年审(true:是,false:否)(qualification_verify = true时才有该字段) + */ + @SerializedName ("annual_review") + private Boolean annualReview; + + /** + * 年审开始时间,时间戳(qualification_verify = true时才有该字段) + */ + @SerializedName ("annual_review_begin_time") + private String annualReviewBeginTime; + + /** + * 年审截止时间,时间戳(qualification_verify = true时才有该字段) + */ + @SerializedName ("annual_review_end_time") + private String annualReviewEndTime; + } + + + @Data + public static class SignatureInfo { + /** + * 功能介绍 + */ + @SerializedName ("signature") + private String signature; + /** + * 头像已使用修改次数(本月) + */ + @SerializedName ("modify_used_count") + private Integer modifyUsedCount; + /** + * 头像修改次数总额度(本月) + */ + @SerializedName ("modify_quota") + private Integer modifyQuota; + } + + + @Data + public static class HeadImageInfo { + /** + * 头像url + */ + @SerializedName ("head_image_url") + private String headImageUrl; + /** + * 头像已使用修改次数(本月) + */ + @SerializedName ("modify_used_count") + private Integer modifyUsedCount; + + /** + * 头像修改次数总额度(本月) + */ + @SerializedName ("modify_quota") + private Integer modifyQuota; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaBeenSetCategoryResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaBeenSetCategoryResult.java new file mode 100644 index 0000000000..11d6693c5b --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaBeenSetCategoryResult.java @@ -0,0 +1,73 @@ +package me.chanjar.weixin.open.bean.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.List; + +/** + * @author Hipple + * @description 获取小程序已经设置的类目结果类 + * @since 2019/1/26 18:27 + */ +@Data +@EqualsAndHashCode (callSuper = true) +public class WxFastMaBeenSetCategoryResult extends WxOpenResult { + private static final long serialVersionUID = - 7662344448437700644L; + + /** + * 一个更改周期内可以设置类目的次数 + */ + @SerializedName ("limit") + private int limit; + /** + * 本更改周期内还可以设置类目的次数 + */ + @SerializedName ("quota") + private int quota; + /** + * 最多可以设置的类目数量 + */ + @SerializedName ("category_limit") + private int categoryLimit; + /** + * 类目 + */ + @SerializedName ("categories") + private List categories; + + @Data + public static class CategoriesBean { + /** + * 一级类目ID + */ + @SerializedName ("first") + private int first; + /** + * 一级类目名称 + */ + @SerializedName ("first_name") + private String firstName; + /** + * 二级类目ID + */ + @SerializedName ("second") + private int second; + /** + * 二级类目名称 + */ + @SerializedName ("second_name") + private String secondName; + /** + * 审核状态(1审核中 2审核不通过 3审核通过) + */ + @SerializedName ("audit_status") + private int auditStatus; + /** + * 审核不通过原因 + */ + @SerializedName ("audit_reason") + private String auditReason; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaCanSetCategoryResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaCanSetCategoryResult.java new file mode 100644 index 0000000000..59d1f45653 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaCanSetCategoryResult.java @@ -0,0 +1,58 @@ +package me.chanjar.weixin.open.bean.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.util.List; + +/** + * @author Hipple + * @description 获取账号所有可以设置的类目 + * @since 2019/1/26 18:43 + */ +@Data +public class WxFastMaCanSetCategoryResult extends WxOpenResult { + private static final long serialVersionUID = - 2469386233538980102L; + @SerializedName ("errcode") + private int errcodeX; + @SerializedName ("categories_list") + private CategoriesListBean categoriesList; + + @Data + public static class CategoriesListBean { + private List categories; + @Data + public static class CategoriesBean { + private int id; + private QualifyBean qualify; + private String name; + private int level; + private int father; + @SerializedName ("sensitive_type") + private int sensitiveType; + @SerializedName ("available_for_plugin") + private boolean availableForPlugin; + @SerializedName ("is_hidden") + private boolean isHidden; + private String type; + @SerializedName ("need_report") + private int needReport; + @SerializedName ("can_use_cityserivce") + private int canUseCityserivce; + private List children; + @SerializedName ("type_list") + private List typeList; + @SerializedName ("available_api_list") + private List availableApiList; + private List apis; + + @Data + public static class QualifyBean { + private String remark; + @SerializedName ("exter_list") + private List exterList; + } + + } + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaCheckNickameResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaCheckNickameResult.java new file mode 100644 index 0000000000..943645e35f --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaCheckNickameResult.java @@ -0,0 +1,29 @@ +package me.chanjar.weixin.open.bean.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author Hipple + * @description 微信认证名称检测结果类 + * @since 2019/1/26 17:39 + */ +@Data +@EqualsAndHashCode (callSuper = true) +public class WxFastMaCheckNickameResult extends WxOpenResult { + private static final long serialVersionUID = 8022192589710319473L; + + /** + * 审核编号. + */ + @SerializedName ("hit_condition") + boolean hitCondition; + + /** + * 材料说明 + */ + @SerializedName ("wording") + String wording; + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaQueryNicknameStatusResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaQueryNicknameStatusResult.java new file mode 100644 index 0000000000..6594c48322 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaQueryNicknameStatusResult.java @@ -0,0 +1,43 @@ +package me.chanjar.weixin.open.bean.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author Hipple + * @description 查询改名状态实体类 + * @since 2019/1/26 17:52 + */ +@EqualsAndHashCode (callSuper = true) +@Data +public class WxFastMaQueryNicknameStatusResult extends WxOpenResult { + + private static final long serialVersionUID = 8492116046290791757L; + + /** + * 审核昵称 + */ + @SerializedName ("nickname") + private String nickname; + /** + * 审核状态,1:审核中,2:审核失败,3:审核成功 + */ + @SerializedName ("audit_stat") + private int auditStat; + /** + * 失败原因 + */ + @SerializedName ("fail_reason") + private String failReason; + /** + * 审核提交时间 + */ + @SerializedName ("create_time") + private String createTime; + /** + * 审核提交时间 + */ + @SerializedName ("audit_time") + private String auditTime; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaSetNickameResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaSetNickameResult.java new file mode 100644 index 0000000000..7a2cab2304 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxFastMaSetNickameResult.java @@ -0,0 +1,29 @@ +package me.chanjar.weixin.open.bean.result; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * @author Hipple + * @description 设置小程序名称结果类 + * @since 2019/1/26 17:39 + */ +@Data +@EqualsAndHashCode (callSuper = true) +public class WxFastMaSetNickameResult extends WxOpenResult { + private static final long serialVersionUID = 8022192589710319473L; + + /** + * 审核编号. + */ + @SerializedName ("audit_id") + Long auditId; + + /** + * 材料说明 + */ + @SerializedName ("wording") + String wording; + +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxFastMaAccountBasicInfoGsonAdapter.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxFastMaAccountBasicInfoGsonAdapter.java new file mode 100644 index 0000000000..a21d334ed8 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxFastMaAccountBasicInfoGsonAdapter.java @@ -0,0 +1,44 @@ +package me.chanjar.weixin.open.util.json; + +import com.google.gson.*; +import com.google.gson.reflect.TypeToken; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.open.bean.result.WxFastMaAccountBasicInfoResult; + +import java.lang.reflect.Type; + +/** + * @author Hipple + * @description + * @since 2019/1/23 15:02 + */ +public class WxFastMaAccountBasicInfoGsonAdapter implements JsonDeserializer { + @Override + public WxFastMaAccountBasicInfoResult deserialize (JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + WxFastMaAccountBasicInfoResult accountBasicInfo = new WxFastMaAccountBasicInfoResult (); + JsonObject jsonObject = jsonElement.getAsJsonObject(); + + accountBasicInfo.setAppId (GsonHelper.getString(jsonObject, "appid")); + accountBasicInfo.setAccountType (GsonHelper.getInteger (jsonObject, "account_type")); + accountBasicInfo.setPrincipalType (GsonHelper.getInteger (jsonObject, "principal_type")); + accountBasicInfo.setPrincipalName (GsonHelper.getString(jsonObject, "principal_name")); + accountBasicInfo.setRealnameStatus (GsonHelper.getInteger (jsonObject, "realname_status")); + + WxFastMaAccountBasicInfoResult.WxVerifyInfo verifyInfo = WxOpenGsonBuilder.create().fromJson(jsonObject.get("wx_verify_info"), + new TypeToken () { + }.getType()); + accountBasicInfo.setWxVerifyInfo (verifyInfo); + + WxFastMaAccountBasicInfoResult.SignatureInfo signatureInfo = WxOpenGsonBuilder.create().fromJson(jsonObject.get("signature_info"), + new TypeToken () { + }.getType()); + accountBasicInfo.setSignatureInfo (signatureInfo); + + WxFastMaAccountBasicInfoResult.HeadImageInfo headImageInfo = WxOpenGsonBuilder.create().fromJson(jsonObject.get("head_image_info"), + new TypeToken () { + }.getType()); + accountBasicInfo.setHeadImageInfo (headImageInfo); + + return accountBasicInfo; + } +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenGsonBuilder.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenGsonBuilder.java index 703aff1218..10c2911df2 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenGsonBuilder.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/util/json/WxOpenGsonBuilder.java @@ -6,6 +6,7 @@ import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizationInfo; import me.chanjar.weixin.open.bean.auth.WxOpenAuthorizerInfo; +import me.chanjar.weixin.open.bean.result.WxFastMaAccountBasicInfoResult; import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerOptionResult; import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; @@ -27,6 +28,8 @@ public class WxOpenGsonBuilder { INSTANCE.registerTypeAdapter(WxOpenAuthorizerInfoResult.class, new WxOpenAuthorizerInfoResultGsonAdapter()); INSTANCE.registerTypeAdapter(WxOpenAuthorizerOptionResult.class, new WxOpenAuthorizerOptionResultGsonAdapter()); + INSTANCE.registerTypeAdapter(WxFastMaAccountBasicInfoResult.class, new WxFastMaAccountBasicInfoGsonAdapter ()); + } public static Gson create() { diff --git a/weixin-java-open/src/test/java/me/chanjar/weixin/open/bean/result/WxFastMaAccountBasicInfoResultTest.java b/weixin-java-open/src/test/java/me/chanjar/weixin/open/bean/result/WxFastMaAccountBasicInfoResultTest.java new file mode 100644 index 0000000000..5232881c50 --- /dev/null +++ b/weixin-java-open/src/test/java/me/chanjar/weixin/open/bean/result/WxFastMaAccountBasicInfoResultTest.java @@ -0,0 +1,51 @@ +package me.chanjar.weixin.open.bean.result; + +import me.chanjar.weixin.open.util.json.WxOpenGsonBuilder; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + + +public class WxFastMaAccountBasicInfoResultTest { + @Test + public void testFromJson() throws Exception { + String json = "{\n" + + " \"errcode\": 0,\n" + + " \"errmsg\": \"ok\",\n" + + "\t\"appid\": \"wxdc685123d955453\",\n" + + " \"account_type\": 2,\n" + + "\t\"principal_type\": 1,\n" + + "\t\"principal_name\": \"深圳市腾讯计算机系统有限公司\",\n" + + " \"realname_status\": 1,\n" + + " \"wx_verify_info\": {\n" + + " \"qualification_verify\": true,\n" + + " \"naming_verify\": true,\n" + + " \"annual_review\": true,\n" + + " \"annual_review_begin_time\": 1550490981,\n" + + " \"annual_review_end_time\": 1558266981\n" + + " },\n" + + " \"signature_info\": {\n" + + " \"signature\": \"功能介绍\",\n" + + " \"modify_used_count\": 1,\n" + + " \"modify_quota\": 5\n" + + " },\n" + + "\t\"head_image_info\": {\n" + + " \"head_image_url\": \"http://mmbiz.qpic.cn/mmbiz/a5icZrUmbV8p5jb6RZ8aYfjfS2AVle8URwBt8QIu6XbGewB9wiaWYWkPwq4R7pfdsFibuLkic16UcxDSNYtB8HnC1Q/0\",\n" + + " \"modify_used_count\": 3,\n" + + " \"modify_quota\": 5\n" + + " }\n" + + "}"; + + WxFastMaAccountBasicInfoResult res = WxOpenGsonBuilder.create ().fromJson (json, WxFastMaAccountBasicInfoResult.class); + + assertNotNull(res); + assertNotNull(res.getAppId ()); + assertNotNull(res.getSignatureInfo ().getModifyQuota ()); + assertNotNull(res.getHeadImageInfo ().getHeadImageUrl ()); + assertNotNull(res.getWxVerifyInfo ().getNamingVerify ()); + assertTrue(res.getWxVerifyInfo ().getNamingVerify ()); + System.out.println(res); + } + +} diff --git a/weixin-java-open/src/test/java/me/chanjar/weixin/open/bean/result/WxFastMaBeenSetCategoryResultTest.java b/weixin-java-open/src/test/java/me/chanjar/weixin/open/bean/result/WxFastMaBeenSetCategoryResultTest.java new file mode 100644 index 0000000000..3cd952542b --- /dev/null +++ b/weixin-java-open/src/test/java/me/chanjar/weixin/open/bean/result/WxFastMaBeenSetCategoryResultTest.java @@ -0,0 +1,40 @@ +package me.chanjar.weixin.open.bean.result; + +import me.chanjar.weixin.open.util.json.WxOpenGsonBuilder; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + + +public class WxFastMaBeenSetCategoryResultTest { + @Test + public void testFromJson() throws Exception { + String json = "{\n" + + " \"errcode\": 0,\n" + + " \"errmsg\":\"ok\",\n" + + " \"categories\": [\n" + + " {\n" + + " \"first\": 8,\n" + + " \"first_name\": \"教育\",\n" + + " \"second\": 39,\n" + + " \"second_name\": \"出国移民\",\n" + + " \"audit_status\": 1,\n" + + " \"audit_reason\": \"不通过啊啊\"\n" + + " }\n" + + " ],\n" + + "\t\"limit\": 5,\n" + + " \"quota\": 4,\n" + + " \"category_limit\": 20\n" + + "}"; + + WxFastMaBeenSetCategoryResult res = WxOpenGsonBuilder.create ().fromJson (json, WxFastMaBeenSetCategoryResult.class); + + assertNotNull(res); + assertTrue(res.getCategories ().size ()> 0); + assertNotNull(res.getCategories ().get (0)); + assertNotNull(res.getCategories ().get (0).getFirstName ()); + System.out.println(res); + } + +} diff --git a/weixin-java-open/src/test/java/me/chanjar/weixin/open/bean/result/WxFastMaCanSetCategoryResultTest.java b/weixin-java-open/src/test/java/me/chanjar/weixin/open/bean/result/WxFastMaCanSetCategoryResultTest.java new file mode 100644 index 0000000000..7e7d220a3a --- /dev/null +++ b/weixin-java-open/src/test/java/me/chanjar/weixin/open/bean/result/WxFastMaCanSetCategoryResultTest.java @@ -0,0 +1,79 @@ +package me.chanjar.weixin.open.bean.result; + +import me.chanjar.weixin.open.util.json.WxOpenGsonBuilder; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertNotNull; + + +public class WxFastMaCanSetCategoryResultTest { + @Test + public void testFromJson() throws Exception { + String json = "{\n" + + " \"errcode\": 0, \n" + + " \"errmsg\": \"ok\", \n" + + " \"categories_list\": {\n" + + " \"categories\": [\n" + + " {\n" + + " \"id\": 1, \n" + + " \"name\": \"快递业与邮政\", \n" + + " \"level\": 1, \n" + + " \"father\": 0, \n" + + " \"children\": [\n" + + " 2, \n" + + " 5, \n" + + " 556, \n" + + " 558, \n" + + " 1033\n" + + " ], \n" + + " \"sensitive_type\": 0, \n" + + " \"type_list\": [ ], \n" + + " \"qualify\": {\n" + + " \"exter_list\": [ ], \n" + + " \"remark\": \"\"\n" + + " }, \n" + + " \"available_api_list\": [ ], \n" + + " \"apis\": [ ], \n" + + " \"available_for_plugin\": true\n" + + " }, \n" + + " {\n" + + " \"id\": 8, \n" + + " \"name\": \"教育\", \n" + + " \"level\": 1, \n" + + " \"father\": 0, \n" + + " \"children\": [\n" + + " 9, \n" + + " 590, \n" + + " 592, \n" + + " 27, \n" + + " 32, \n" + + " 37, \n" + + " 39, \n" + + " 578, \n" + + " 580, \n" + + " 582, \n" + + " 1043\n" + + " ], \n" + + " \"sensitive_type\": 0, \n" + + " \"type_list\": [ ], \n" + + " \"qualify\": {\n" + + " \"exter_list\": [ ], \n" + + " \"remark\": \"\"\n" + + " }, \n" + + " \"is_hidden\": false, \n" + + " \"available_api_list\": [ ], \n" + + " \"type\": \"NORMAL\", \n" + + " \"apis\": [ ], \n" + + " \"available_for_plugin\": true\n" + + " }\n" + + " ]\n" + + " }\n" + + "}"; + WxFastMaCanSetCategoryResult res = WxOpenGsonBuilder.create ().fromJson (json, WxFastMaCanSetCategoryResult.class); + + assertNotNull(res); + assertNotNull(res.getCategoriesList ()); + System.out.println(res); + } + +} diff --git a/weixin-java-open/src/test/resources/logback-test.xml b/weixin-java-open/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..e4a33acd88 --- /dev/null +++ b/weixin-java-open/src/test/resources/logback-test.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %replace(%caller{1}){'Caller', ''} - %msg%n + + + + + + + + diff --git a/weixin-java-open/src/test/resources/test-config.sample.xml b/weixin-java-open/src/test/resources/test-config.sample.xml new file mode 100644 index 0000000000..896969e438 --- /dev/null +++ b/weixin-java-open/src/test/resources/test-config.sample.xml @@ -0,0 +1,7 @@ + + 第三方平台appID + 第三方平台appsecret + 第三方平台Token + 第三方平台EncodingAESKey + 测试APPID + diff --git a/weixin-java-open/src/test/resources/testng.xml b/weixin-java-open/src/test/resources/testng.xml new file mode 100644 index 0000000000..8ade76f3e3 --- /dev/null +++ b/weixin-java-open/src/test/resources/testng.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + From 343ed7a70845c07c4e6844c18c0b105ad34ae8f7 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 27 Jan 2019 19:12:36 +0800 Subject: [PATCH 26/81] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/cp/bean/WxCpAppChatMessage.java | 165 +++++++++--------- .../chanjar/weixin/cp/bean/WxCpMessage.java | 144 +++++++++++++-- .../weixin/cp/util/json/WxCpGsonBuilder.java | 2 - .../cp/util/json/WxCpMessageGsonAdapter.java | 139 --------------- .../chanjar/weixin/cp/bean/WxCpAgentTest.java | 15 +- .../weixin/cp/bean/WxCpMessageTest.java | 32 +++- 6 files changed, 254 insertions(+), 243 deletions(-) delete mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java index 65a13badd0..a3f9a62d68 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java @@ -9,8 +9,7 @@ import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.cp.WxCpConsts; +import me.chanjar.weixin.cp.WxCpConsts.AppChatMsgType; import me.chanjar.weixin.cp.bean.article.MpnewsArticle; import me.chanjar.weixin.cp.bean.article.NewArticle; @@ -46,7 +45,7 @@ public class WxCpAppChatMessage implements Serializable { */ public static WxCpAppChatMessage buildTextMsg(String chatId, String content, boolean safe) { final WxCpAppChatMessage message = new WxCpAppChatMessage(); - message.setMsgType(WxCpConsts.AppChatMsgType.TEXT); + message.setMsgType(AppChatMsgType.TEXT); message.setContent(content); message.setChatId(chatId); message.setSafe(safe); @@ -61,94 +60,104 @@ public String toJson() { messageJson.addProperty("msgtype", this.getMsgType()); messageJson.addProperty("chatid", this.getChatId()); - if (WxConsts.KefuMsgType.TEXT.equals(this.getMsgType())) { - JsonObject text = new JsonObject(); - text.addProperty("content", this.getContent()); - messageJson.add("text", text); - } - - if (WxConsts.KefuMsgType.MARKDOWN.equals(this.getMsgType())) { - JsonObject text = new JsonObject(); - text.addProperty("content", this.getContent()); - messageJson.add("markdown", text); - } - - if (WxConsts.KefuMsgType.TEXTCARD.equals(this.getMsgType())) { - JsonObject text = new JsonObject(); - text.addProperty("title", this.getTitle()); - text.addProperty("description", this.getDescription()); - text.addProperty("url", this.getUrl()); - text.addProperty("btntxt", this.getBtnTxt()); - messageJson.add("textcard", text); - } - - if (WxConsts.KefuMsgType.IMAGE.equals(this.getMsgType())) { - JsonObject image = new JsonObject(); - image.addProperty("media_id", this.getMediaId()); - messageJson.add("image", image); - } - - if (WxConsts.KefuMsgType.FILE.equals(this.getMsgType())) { - JsonObject image = new JsonObject(); - image.addProperty("media_id", this.getMediaId()); - messageJson.add("file", image); - } - - if (WxConsts.KefuMsgType.VOICE.equals(this.getMsgType())) { - JsonObject voice = new JsonObject(); - voice.addProperty("media_id", this.getMediaId()); - messageJson.add("voice", voice); - } - if (this.getSafe() != null && this.getSafe()) { messageJson.addProperty("safe", 1); } - if (WxConsts.KefuMsgType.VIDEO.equals(this.getMsgType())) { - JsonObject video = new JsonObject(); - video.addProperty("media_id", this.getMediaId()); - video.addProperty("title", this.getTitle()); - video.addProperty("description", this.getDescription()); - messageJson.add("video", video); - } + this.handleMsgType(messageJson); - if (WxConsts.KefuMsgType.NEWS.equals(this.getMsgType())) { - JsonObject newsJsonObject = new JsonObject(); - JsonArray articleJsonArray = new JsonArray(); - for (NewArticle article : this.getArticles()) { - JsonObject articleJson = new JsonObject(); - articleJson.addProperty("title", article.getTitle()); - articleJson.addProperty("description", article.getDescription()); - articleJson.addProperty("url", article.getUrl()); - articleJson.addProperty("picurl", article.getPicUrl()); - articleJsonArray.add(articleJson); - } - newsJsonObject.add("articles", articleJsonArray); - messageJson.add("news", newsJsonObject); - } + return messageJson.toString(); + } - if (WxConsts.KefuMsgType.MPNEWS.equals(this.getMsgType())) { - JsonObject newsJsonObject = new JsonObject(); - if (this.getMediaId() != null) { - newsJsonObject.addProperty("media_id", this.getMediaId()); - } else { + private void handleMsgType(JsonObject messageJson) { + switch (this.getMsgType()) { + case AppChatMsgType.TEXT: { + JsonObject text = new JsonObject(); + text.addProperty("content", this.getContent()); + messageJson.add("text", text); + break; + } + case AppChatMsgType.MARKDOWN: { + JsonObject text = new JsonObject(); + text.addProperty("content", this.getContent()); + messageJson.add("markdown", text); + break; + } + case AppChatMsgType.TEXTCARD: { + JsonObject text = new JsonObject(); + text.addProperty("title", this.getTitle()); + text.addProperty("description", this.getDescription()); + text.addProperty("url", this.getUrl()); + text.addProperty("btntxt", this.getBtnTxt()); + messageJson.add("textcard", text); + break; + } + case AppChatMsgType.IMAGE: { + JsonObject image = new JsonObject(); + image.addProperty("media_id", this.getMediaId()); + messageJson.add("image", image); + break; + } + case AppChatMsgType.FILE: { + JsonObject image = new JsonObject(); + image.addProperty("media_id", this.getMediaId()); + messageJson.add("file", image); + break; + } + case AppChatMsgType.VOICE: { + JsonObject voice = new JsonObject(); + voice.addProperty("media_id", this.getMediaId()); + messageJson.add("voice", voice); + break; + } + case AppChatMsgType.VIDEO: { + JsonObject video = new JsonObject(); + video.addProperty("media_id", this.getMediaId()); + video.addProperty("title", this.getTitle()); + video.addProperty("description", this.getDescription()); + messageJson.add("video", video); + break; + } + case AppChatMsgType.NEWS: { + JsonObject newsJsonObject = new JsonObject(); JsonArray articleJsonArray = new JsonArray(); - for (MpnewsArticle article : this.getMpnewsArticles()) { + for (NewArticle article : this.getArticles()) { JsonObject articleJson = new JsonObject(); articleJson.addProperty("title", article.getTitle()); - articleJson.addProperty("thumb_media_id", article.getThumbMediaId()); - articleJson.addProperty("author", article.getAuthor()); - articleJson.addProperty("content_source_url", article.getContentSourceUrl()); - articleJson.addProperty("content", article.getContent()); - articleJson.addProperty("digest", article.getDigest()); + articleJson.addProperty("description", article.getDescription()); + articleJson.addProperty("url", article.getUrl()); + articleJson.addProperty("picurl", article.getPicUrl()); articleJsonArray.add(articleJson); } - newsJsonObject.add("articles", articleJsonArray); + messageJson.add("news", newsJsonObject); + break; + } + case AppChatMsgType.MPNEWS: { + JsonObject newsJsonObject = new JsonObject(); + if (this.getMediaId() != null) { + newsJsonObject.addProperty("media_id", this.getMediaId()); + } else { + JsonArray articleJsonArray = new JsonArray(); + for (MpnewsArticle article : this.getMpnewsArticles()) { + JsonObject articleJson = new JsonObject(); + articleJson.addProperty("title", article.getTitle()); + articleJson.addProperty("thumb_media_id", article.getThumbMediaId()); + articleJson.addProperty("author", article.getAuthor()); + articleJson.addProperty("content_source_url", article.getContentSourceUrl()); + articleJson.addProperty("content", article.getContent()); + articleJson.addProperty("digest", article.getDigest()); + articleJsonArray.add(articleJson); + } + + newsJsonObject.add("articles", articleJsonArray); + } + messageJson.add("mpnews", newsJsonObject); + break; + } + default: { + //do nothing } - messageJson.add("mpnews", newsJsonObject); } - - return messageJson.toString(); } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java index cd455d88ce..df90775b5e 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java @@ -4,8 +4,12 @@ import java.util.ArrayList; import java.util.List; +import org.apache.commons.lang3.StringUtils; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; import lombok.Data; -import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.common.api.WxConsts.KefuMsgType; import me.chanjar.weixin.cp.bean.article.MpnewsArticle; import me.chanjar.weixin.cp.bean.article.NewArticle; import me.chanjar.weixin.cp.bean.messagebuilder.FileBuilder; @@ -17,7 +21,6 @@ import me.chanjar.weixin.cp.bean.messagebuilder.TextCardBuilder; import me.chanjar.weixin.cp.bean.messagebuilder.VideoBuilder; import me.chanjar.weixin.cp.bean.messagebuilder.VoiceBuilder; -import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; /** * 消息. @@ -113,14 +116,14 @@ public static FileBuilder FILE() { /** *
    * 请使用
-   * {@link WxConsts.KefuMsgType#TEXT}
-   * {@link WxConsts.KefuMsgType#IMAGE}
-   * {@link WxConsts.KefuMsgType#VOICE}
-   * {@link WxConsts.KefuMsgType#MUSIC}
-   * {@link WxConsts.KefuMsgType#VIDEO}
-   * {@link WxConsts.KefuMsgType#NEWS}
-   * {@link WxConsts.KefuMsgType#MPNEWS}
-   * {@link WxConsts.KefuMsgType#MARKDOWN}
+   * {@link KefuMsgType#TEXT}
+   * {@link KefuMsgType#IMAGE}
+   * {@link KefuMsgType#VOICE}
+   * {@link KefuMsgType#MUSIC}
+   * {@link KefuMsgType#VIDEO}
+   * {@link KefuMsgType#NEWS}
+   * {@link KefuMsgType#MPNEWS}
+   * {@link KefuMsgType#MARKDOWN}
    * 
* * @param msgType 消息类型 @@ -130,7 +133,126 @@ public void setMsgType(String msgType) { } public String toJson() { - return WxCpGsonBuilder.create().toJson(this); + JsonObject messageJson = new JsonObject(); + if (this.getAgentId() != null) { + messageJson.addProperty("agentid", this.getAgentId()); + } + + if (StringUtils.isNotBlank(this.getToUser())) { + messageJson.addProperty("touser", this.getToUser()); + } + + messageJson.addProperty("msgtype", this.getMsgType()); + + if (StringUtils.isNotBlank(this.getToParty())) { + messageJson.addProperty("toparty", this.getToParty()); + } + + if (StringUtils.isNotBlank(this.getToTag())) { + messageJson.addProperty("totag", this.getToTag()); + } + + this.handleMsgType(messageJson); + + if (StringUtils.isNotBlank(this.getSafe())) { + messageJson.addProperty("safe", this.getSafe()); + } + + return messageJson.toString(); + } + + private void handleMsgType(JsonObject messageJson) { + switch (this.getMsgType()) { + case KefuMsgType.TEXT: { + JsonObject text = new JsonObject(); + text.addProperty("content", this.getContent()); + messageJson.add("text", text); + break; + } + case KefuMsgType.MARKDOWN: { + JsonObject text = new JsonObject(); + text.addProperty("content", this.getContent()); + messageJson.add("markdown", text); + break; + } + case KefuMsgType.TEXTCARD: { + JsonObject text = new JsonObject(); + text.addProperty("title", this.getTitle()); + text.addProperty("description", this.getDescription()); + text.addProperty("url", this.getUrl()); + text.addProperty("btntxt", this.getBtnTxt()); + messageJson.add("textcard", text); + break; + } + case KefuMsgType.IMAGE: { + JsonObject image = new JsonObject(); + image.addProperty("media_id", this.getMediaId()); + messageJson.add("image", image); + break; + } + case KefuMsgType.FILE: { + JsonObject image = new JsonObject(); + image.addProperty("media_id", this.getMediaId()); + messageJson.add("file", image); + break; + } + case KefuMsgType.VOICE: { + JsonObject voice = new JsonObject(); + voice.addProperty("media_id", this.getMediaId()); + messageJson.add("voice", voice); + break; + } + case KefuMsgType.VIDEO: { + JsonObject video = new JsonObject(); + video.addProperty("media_id", this.getMediaId()); + video.addProperty("thumb_media_id", this.getThumbMediaId()); + video.addProperty("title", this.getTitle()); + video.addProperty("description", this.getDescription()); + messageJson.add("video", video); + break; + } + case KefuMsgType.NEWS: { + JsonObject newsJsonObject = new JsonObject(); + JsonArray articleJsonArray = new JsonArray(); + for (NewArticle article : this.getArticles()) { + JsonObject articleJson = new JsonObject(); + articleJson.addProperty("title", article.getTitle()); + articleJson.addProperty("description", article.getDescription()); + articleJson.addProperty("url", article.getUrl()); + articleJson.addProperty("picurl", article.getPicUrl()); + articleJsonArray.add(articleJson); + } + newsJsonObject.add("articles", articleJsonArray); + messageJson.add("news", newsJsonObject); + break; + } + case KefuMsgType.MPNEWS: { + JsonObject newsJsonObject = new JsonObject(); + if (this.getMediaId() != null) { + newsJsonObject.addProperty("media_id", this.getMediaId()); + } else { + JsonArray articleJsonArray = new JsonArray(); + for (MpnewsArticle article : this.getMpnewsArticles()) { + JsonObject articleJson = new JsonObject(); + articleJson.addProperty("title", article.getTitle()); + articleJson.addProperty("thumb_media_id", article.getThumbMediaId()); + articleJson.addProperty("author", article.getAuthor()); + articleJson.addProperty("content_source_url", article.getContentSourceUrl()); + articleJson.addProperty("content", article.getContent()); + articleJson.addProperty("digest", article.getDigest()); + articleJson.addProperty("show_cover_pic", article.getShowCoverPic()); + articleJsonArray.add(articleJson); + } + + newsJsonObject.add("articles", articleJsonArray); + } + messageJson.add("mpnews", newsJsonObject); + break; + } + default: { + // do nothing + } + } } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpGsonBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpGsonBuilder.java index 654d55111b..16f0108e09 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpGsonBuilder.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpGsonBuilder.java @@ -7,7 +7,6 @@ import me.chanjar.weixin.common.util.json.WxErrorAdapter; import me.chanjar.weixin.cp.bean.WxCpChat; import me.chanjar.weixin.cp.bean.WxCpDepart; -import me.chanjar.weixin.cp.bean.WxCpMessage; import me.chanjar.weixin.cp.bean.WxCpTag; import me.chanjar.weixin.cp.bean.WxCpUser; @@ -20,7 +19,6 @@ public class WxCpGsonBuilder { static { INSTANCE.disableHtmlEscaping(); - INSTANCE.registerTypeAdapter(WxCpMessage.class, new WxCpMessageGsonAdapter()); INSTANCE.registerTypeAdapter(WxCpChat.class, new WxCpChatGsonAdapter()); INSTANCE.registerTypeAdapter(WxCpDepart.class, new WxCpDepartGsonAdapter()); INSTANCE.registerTypeAdapter(WxCpUser.class, new WxCpUserGsonAdapter()); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java deleted file mode 100644 index fbf70bb581..0000000000 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. - * - * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended - * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction - * arose from modification of the original source, or other redistribution of this source - * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. - */ -package me.chanjar.weixin.cp.util.json; - -import java.lang.reflect.Type; - -import org.apache.commons.lang3.StringUtils; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; -import me.chanjar.weixin.common.api.WxConsts; -import me.chanjar.weixin.cp.bean.WxCpMessage; -import me.chanjar.weixin.cp.bean.article.MpnewsArticle; -import me.chanjar.weixin.cp.bean.article.NewArticle; - -/** - * @author Daniel Qian - */ -public class WxCpMessageGsonAdapter implements JsonSerializer { - - @Override - public JsonElement serialize(WxCpMessage message, Type typeOfSrc, JsonSerializationContext context) { - JsonObject messageJson = new JsonObject(); - messageJson.addProperty("agentid", message.getAgentId()); - if (StringUtils.isNotBlank(message.getToUser())) { - messageJson.addProperty("touser", message.getToUser()); - } - messageJson.addProperty("msgtype", message.getMsgType()); - - if (StringUtils.isNotBlank(message.getToParty())) { - messageJson.addProperty("toparty", message.getToParty()); - } - if (StringUtils.isNotBlank(message.getToTag())) { - messageJson.addProperty("totag", message.getToTag()); - } - - if (WxConsts.KefuMsgType.TEXT.equals(message.getMsgType())) { - JsonObject text = new JsonObject(); - text.addProperty("content", message.getContent()); - messageJson.add("text", text); - } - - if (WxConsts.KefuMsgType.MARKDOWN.equals(message.getMsgType())) { - JsonObject text = new JsonObject(); - text.addProperty("content", message.getContent()); - messageJson.add("markdown", text); - } - - if (WxConsts.KefuMsgType.TEXTCARD.equals(message.getMsgType())) { - JsonObject text = new JsonObject(); - text.addProperty("title", message.getTitle()); - text.addProperty("description", message.getDescription()); - text.addProperty("url", message.getUrl()); - text.addProperty("btntxt", message.getBtnTxt()); - messageJson.add("textcard", text); - } - - if (WxConsts.KefuMsgType.IMAGE.equals(message.getMsgType())) { - JsonObject image = new JsonObject(); - image.addProperty("media_id", message.getMediaId()); - messageJson.add("image", image); - } - - if (WxConsts.KefuMsgType.FILE.equals(message.getMsgType())) { - JsonObject image = new JsonObject(); - image.addProperty("media_id", message.getMediaId()); - messageJson.add("file", image); - } - - if (WxConsts.KefuMsgType.VOICE.equals(message.getMsgType())) { - JsonObject voice = new JsonObject(); - voice.addProperty("media_id", message.getMediaId()); - messageJson.add("voice", voice); - } - - if (StringUtils.isNotBlank(message.getSafe())) { - messageJson.addProperty("safe", message.getSafe()); - } - - if (WxConsts.KefuMsgType.VIDEO.equals(message.getMsgType())) { - JsonObject video = new JsonObject(); - video.addProperty("media_id", message.getMediaId()); - video.addProperty("thumb_media_id", message.getThumbMediaId()); - video.addProperty("title", message.getTitle()); - video.addProperty("description", message.getDescription()); - messageJson.add("video", video); - } - - if (WxConsts.KefuMsgType.NEWS.equals(message.getMsgType())) { - JsonObject newsJsonObject = new JsonObject(); - JsonArray articleJsonArray = new JsonArray(); - for (NewArticle article : message.getArticles()) { - JsonObject articleJson = new JsonObject(); - articleJson.addProperty("title", article.getTitle()); - articleJson.addProperty("description", article.getDescription()); - articleJson.addProperty("url", article.getUrl()); - articleJson.addProperty("picurl", article.getPicUrl()); - articleJsonArray.add(articleJson); - } - newsJsonObject.add("articles", articleJsonArray); - messageJson.add("news", newsJsonObject); - } - - if (WxConsts.KefuMsgType.MPNEWS.equals(message.getMsgType())) { - JsonObject newsJsonObject = new JsonObject(); - if (message.getMediaId() != null) { - newsJsonObject.addProperty("media_id", message.getMediaId()); - } else { - JsonArray articleJsonArray = new JsonArray(); - for (MpnewsArticle article : message.getMpnewsArticles()) { - JsonObject articleJson = new JsonObject(); - articleJson.addProperty("title", article.getTitle()); - articleJson.addProperty("thumb_media_id", article.getThumbMediaId()); - articleJson.addProperty("author", article.getAuthor()); - articleJson.addProperty("content_source_url", article.getContentSourceUrl()); - articleJson.addProperty("content", article.getContent()); - articleJson.addProperty("digest", article.getDigest()); - articleJson.addProperty("show_cover_pic", article.getShowCoverPic()); - articleJsonArray.add(articleJson); - } - - newsJsonObject.add("articles", articleJsonArray); - } - messageJson.add("mpnews", newsJsonObject); - } - - return messageJson; - } - -} diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpAgentTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpAgentTest.java index 74b8269d3d..9f187e43aa 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpAgentTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpAgentTest.java @@ -1,7 +1,7 @@ package me.chanjar.weixin.cp.bean; -import org.testng.Assert; -import org.testng.annotations.Test; +import org.testng.*; +import org.testng.annotations.*; /** * Created by huansinho on 2018/4/13. @@ -10,7 +10,13 @@ public class WxCpAgentTest { public void testDeserialize() { - String json = "{\"errcode\": 0,\"errmsg\": \"ok\",\"agentid\": 9,\"name\": \"测试应用\",\"square_logo_url\": \"http://wx.qlogo.cn/mmhead/alksjf;lasdjf;lasjfuodiuj3rj2o34j/0\",\"description\": \"这是一个企业号应用\",\"allow_userinfos\": {\"user\": [{\"userid\": \"0009854\"}, {\"userid\": \"1723\"}, {\"userid\": \"5625\"}]},\"allow_partys\": {\"partyid\": [42762742]},\"allow_tags\": {\"tagid\": [23, 22, 35, 19, 32, 125, 133, 46, 150, 38, 183, 9, 7]},\"close\": 0,\"redirect_domain\": \"weixin.com.cn\",\"report_location_flag\": 0,\"isreportenter\": 0,\"home_url\": \"\"}"; + String json = "{\"errcode\": 0,\"errmsg\": \"ok\",\"agentid\": 9,\"name\": \"测试应用\"," + + "\"square_logo_url\": \"http://wx.qlogo.cn/mmhead/alksjf;lasdjf;lasjfuodiuj3rj2o34j/0\"," + + "\"description\": \"这是一个企业号应用\",\"allow_userinfos\": {\"user\": [{\"userid\": \"0009854\"}," + + " {\"userid\": \"1723\"}, {\"userid\": \"5625\"}]},\"allow_partys\": {\"partyid\": [42762742]}," + + "\"allow_tags\": {\"tagid\": [23, 22, 35, 19, 32, 125, 133, 46, 150, 38, 183, 9, 7]}," + + "\"close\": 0,\"redirect_domain\": \"weixin.com.cn\",\"report_location_flag\": 0," + + "\"isreportenter\": 0,\"home_url\": \"\"}"; WxCpAgent wxCpAgent = WxCpAgent.fromJson(json); @@ -18,7 +24,8 @@ public void testDeserialize() { Assert.assertEquals(new Integer[]{42762742}, wxCpAgent.getAllowParties().getPartyIds().toArray()); - Assert.assertEquals(new Integer[]{23, 22, 35, 19, 32, 125, 133, 46, 150, 38, 183, 9, 7}, wxCpAgent.getAllowTags().getTagIds().toArray()); + Assert.assertEquals(new Integer[]{23, 22, 35, 19, 32, 125, 133, 46, 150, 38, 183, 9, 7}, + wxCpAgent.getAllowTags().getTagIds().toArray()); } diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java index 0af121a835..344d1e8251 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java @@ -1,11 +1,11 @@ package me.chanjar.weixin.cp.bean; +import org.testng.annotations.*; + import me.chanjar.weixin.cp.bean.article.MpnewsArticle; import me.chanjar.weixin.cp.bean.article.NewArticle; -import org.testng.annotations.Test; import static org.assertj.core.api.Assertions.assertThat; -import static org.testng.Assert.assertEquals; @Test public class WxCpMessageTest { @@ -19,12 +19,16 @@ public void testTextBuild() { public void testTextCardBuild() { WxCpMessage reply = WxCpMessage.TEXTCARD().toUser("OPENID") .title("领奖通知") - .description("
2016年9月26日
恭喜你抽中iPhone 7一台,领奖码:xxxx
请于2016年10月10日前联系行政同事领取
") + .description("
2016年9月26日
恭喜你抽中iPhone 7一台," + + "领奖码:xxxx
请于2016年10月10日前联系行政同事领取
") .url("http://www.qq.com") .btnTxt("更多") .build(); assertThat(reply.toJson()) - .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"textcard\",\"textcard\":{\"title\":\"领奖通知\",\"description\":\"
2016年9月26日
恭喜你抽中iPhone 7一台,领奖码:xxxx
请于2016年10月10日前联系行政同事领取
\",\"url\":\"http://www.qq.com\",\"btntxt\":\"更多\"},\"safe\":\"0\"}"); + .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"textcard\",\"textcard\":{\"title\":\"领奖通知\"," + + "\"description\":\"
2016年9月26日
" + + "恭喜你抽中iPhone 7一台,领奖码:xxxx
请于2016年10月10日前联系行政同事领取
\"," + + "\"url\":\"http://www.qq.com\",\"btntxt\":\"更多\"},\"safe\":\"0\"}"); } public void testImageBuild() { @@ -40,9 +44,11 @@ public void testVoiceBuild() { } public void testVideoBuild() { - WxCpMessage reply = WxCpMessage.VIDEO().toUser("OPENID").title("TITLE").mediaId("MEDIA_ID").thumbMediaId("MEDIA_ID").description("DESCRIPTION").build(); + WxCpMessage reply = WxCpMessage.VIDEO().toUser("OPENID").title("TITLE").mediaId("MEDIA_ID").thumbMediaId("MEDIA_ID") + .description("DESCRIPTION").build(); assertThat(reply.toJson()) - .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"video\",\"safe\":\"0\",\"video\":{\"media_id\":\"MEDIA_ID\",\"thumb_media_id\":\"MEDIA_ID\",\"title\":\"TITLE\",\"description\":\"DESCRIPTION\"}}"); + .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"video\",\"video\":{\"media_id\":\"MEDIA_ID\"," + + "\"thumb_media_id\":\"MEDIA_ID\",\"title\":\"TITLE\",\"description\":\"DESCRIPTION\"},\"safe\":\"0\"}"); } public void testNewsBuild() { @@ -61,7 +67,10 @@ public void testNewsBuild() { WxCpMessage reply = WxCpMessage.NEWS().toUser("OPENID").addArticle(article1).addArticle(article2).build(); assertThat(reply.toJson()) - .isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"safe\":\"0\",\"news\":{\"articles\":[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"},{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}}"); + .isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":" + + "[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}," + + "{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}," + + "\"safe\":\"0\"}"); } public void testMpnewsBuild_with_articles() { @@ -88,14 +97,19 @@ public void testMpnewsBuild_with_articles() { WxCpMessage reply = WxCpMessage.MPNEWS().toUser("OPENID").addArticle(article1, article2).build(); assertThat(reply.toJson()) - .isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"safe\":\"0\",\"mpnews\":{\"articles\":[{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\",\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"},{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\",\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"}]}}"); + .isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"mpnews\":{\"articles\":" + + "[{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\"," + + "\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"}" + + ",{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\"," + + "\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"}]}," + + "\"safe\":\"0\"}"); } public void testMpnewsBuild_with_media_id() { WxCpMessage reply = WxCpMessage.MPNEWS().toUser("OPENID").mediaId("mmm").build(); assertThat(reply.toJson()) - .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"safe\":\"0\",\"mpnews\":{\"media_id\":\"mmm\"}}"); + .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"mpnews\":{\"media_id\":\"mmm\"},\"safe\":\"0\"}"); } } From 7b1e411214049e905550774e8fe340d2f0ae9097 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 28 Jan 2019 10:58:50 +0800 Subject: [PATCH 27/81] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bean/message/WxMpXmlOutNewsMessage.java | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessage.java index f7405600ef..00f8d70c88 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/message/WxMpXmlOutNewsMessage.java @@ -1,5 +1,9 @@ package me.chanjar.weixin.mp.bean.message; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; import lombok.Data; @@ -7,18 +11,26 @@ import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - +/** + * 被动回复的图文消息xml. + * @author chanjarster + */ @XStreamAlias("xml") @Data @EqualsAndHashCode(callSuper = true) public class WxMpXmlOutNewsMessage extends WxMpXmlOutMessage { private static final long serialVersionUID = -4604402850905714772L; + /** + * 图文消息信息. + * 注意,如果图文数超过限制,则将只发限制内的条数 + */ @XStreamAlias("Articles") protected final List articles = new ArrayList<>(); + /** + * 图文消息个数. + * 当用户发送文本、图片、视频、图文、地理位置这五种消息时,开发者只能回复1条图文消息;其余场景最多可回复8条图文消息 + */ @XStreamAlias("ArticleCount") protected int articleCount; @@ -36,23 +48,35 @@ public void addArticle(Item item) { public static class Item implements Serializable { private static final long serialVersionUID = -4971456355028904754L; + /** + * 图文消息标题. + */ @XStreamAlias("Title") @XStreamConverter(value = XStreamCDataConverter.class) private String title; + /** + * 图文消息描述. + */ @XStreamAlias("Description") @XStreamConverter(value = XStreamCDataConverter.class) private String description; + /** + * 图片链接. + * 支持JPG、PNG格式,较好的效果为大图360*200,小图200*200 + */ @XStreamAlias("PicUrl") @XStreamConverter(value = XStreamCDataConverter.class) private String picUrl; + /** + * 点击图文消息跳转链接. + */ @XStreamAlias("Url") @XStreamConverter(value = XStreamCDataConverter.class) private String url; } - } From b5230ae98262130106eaa5d7fc9235cd17b11562 Mon Sep 17 00:00:00 2001 From: Hipple <1159828430@qq.com> Date: Mon, 28 Jan 2019 11:05:44 +0800 Subject: [PATCH 28/81] =?UTF-8?q?=E4=BF=AE=E5=A4=8DWxFastMaCategory.java?= =?UTF-8?q?=E9=9D=9E=E9=9D=99=E6=80=81=E5=86=85=E9=83=A8=E7=B1=BB=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E7=9A=84=E5=9C=A8Jackson=E4=B8=8B=E7=9A=84parse?= =?UTF-8?q?=E5=BC=82=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java | 6 +++--- .../me/chanjar/weixin/open/api/WxOpenFastMaService.java | 1 - .../chanjar/weixin/open/bean/fastma/WxFastMaCategory.java | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java index a3f9a62d68..96639f6c51 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpAppChatMessage.java @@ -1,8 +1,5 @@ package me.chanjar.weixin.cp.bean; -import java.io.Serializable; -import java.util.List; - import com.google.gson.JsonArray; import com.google.gson.JsonObject; import lombok.AllArgsConstructor; @@ -13,6 +10,9 @@ import me.chanjar.weixin.cp.bean.article.MpnewsArticle; import me.chanjar.weixin.cp.bean.article.NewArticle; +import java.io.Serializable; +import java.util.List; + /** *
  * 应用推送消息
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenFastMaService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenFastMaService.java
index 987a6b9793..64db79b929 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenFastMaService.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenFastMaService.java
@@ -13,7 +13,6 @@
  *     https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=21528465979XX32V&token=&lang=zh_CN
  *    注意:该类的接口仅限通过快速创建小程序接口的小程序使用
  * 
- * TODO 完善相应API的respons实体 * * @author Hipple * @date 2019/01/23 diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/fastma/WxFastMaCategory.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/fastma/WxFastMaCategory.java index b854877a87..1c0cbeb35a 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/fastma/WxFastMaCategory.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/fastma/WxFastMaCategory.java @@ -29,7 +29,7 @@ public class WxFastMaCategory implements Serializable { private List certicates; @Data - public class certicaty { + public static class certicaty { private String key; private String value; } From 1e23b3b7431827e5d35ef1ce4df3a9695fe6de24 Mon Sep 17 00:00:00 2001 From: shilianwang <47650627+shilianwang@users.noreply.github.com> Date: Fri, 1 Mar 2019 10:48:23 +0800 Subject: [PATCH 29/81] =?UTF-8?q?#942:=20=E4=BF=AE=E5=A4=8D=E4=B8=8B?= =?UTF-8?q?=E8=BD=BDiphone=E7=9A=84=E5=A3=B0=E9=9F=B3=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=97=B6=E5=BE=AE=E4=BF=A1=E8=BF=94=E5=9B=9E=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E5=90=8D=E4=B8=BA=E7=A9=BA=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/http/apache/ApacheMediaDownloadRequestExecutor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheMediaDownloadRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheMediaDownloadRequestExecutor.java index 779a844aa9..da8f435c87 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheMediaDownloadRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheMediaDownloadRequestExecutor.java @@ -57,7 +57,7 @@ public File execute(String uri, String queryParam) throws WxErrorException, IOEx String fileName = new HttpResponseProxy(response).getFileName(); if (StringUtils.isBlank(fileName)) { - return null; + fileName = String.valueOf(System.currentTimeMillis()); } return FileUtils.createTmpFile(inputStream, FilenameUtils.getBaseName(fileName), FilenameUtils.getExtension(fileName), From 28affd2d1173c4bdbebc89f5e52a14e09518a1d5 Mon Sep 17 00:00:00 2001 From: shilianwang <47650627+shilianwang@users.noreply.github.com> Date: Fri, 1 Mar 2019 15:00:56 +0800 Subject: [PATCH 30/81] =?UTF-8?q?#947=20=E4=BF=AE=E5=A4=8DWxCpMessageRoute?= =?UTF-8?q?r=E5=90=8C=E6=97=B6=E5=AD=98=E5=9C=A8=E4=B8=A4=E4=B8=AAStandard?= =?UTF-8?q?SessionManager=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/me/chanjar/weixin/cp/api/WxCpService.java | 7 +++++++ .../me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java | 5 +++++ .../me/chanjar/weixin/cp/message/WxCpMessageRouter.java | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java index afda991b55..64756dfb58 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java @@ -165,6 +165,13 @@ public interface WxCpService { */ WxSession getSession(String id, boolean create); + /** + * 获取WxSessionManager 对象 + * + * @return WxSessionManager + */ + WxSessionManager getSessionManager(); + /** *
    * 设置WxSessionManager,只有当需要使用个性化的WxSessionManager的时候才需要调用此方法,
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
index 89aeb4863e..e985e21141 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
@@ -285,6 +285,11 @@ public void setSessionManager(WxSessionManager sessionManager) {
     this.sessionManager = sessionManager;
   }
 
+  @Override
+  public WxSessionManager getSessionManager() {
+    return this.sessionManager;
+  }
+
   @Override
   public String replaceParty(String mediaId) throws WxErrorException {
     String url = "https://qyapi.weixin.qq.com/cgi-bin/batch/replaceparty";
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java
index 6b778be66c..631abdff8b 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java
@@ -73,7 +73,7 @@ public WxCpMessageRouter(WxCpService wxCpService) {
     this.wxCpService = wxCpService;
     this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE);
     this.messageDuplicateChecker = new WxMessageInMemoryDuplicateChecker();
-    this.sessionManager = new StandardSessionManager();
+    this.sessionManager = wxCpService.getSessionManager();
     this.exceptionHandler = new LogExceptionHandler();
   }
 

From 5d7f69a984ef6c751028a4ac7e6f18ca1a465c11 Mon Sep 17 00:00:00 2001
From: liaochuntao 
Date: Fri, 1 Mar 2019 15:06:54 +0800
Subject: [PATCH 31/81] =?UTF-8?q?#956=20=E4=BD=BF=E7=94=A8ConcurrentHashMa?=
 =?UTF-8?q?p=E6=9B=BF=E6=8D=A2HashTable?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../chanjar/weixin/common/util/res/StringManager.java  |  3 ++-
 .../util/json/WxMaVisitDistributionGsonAdapter.java    |  4 ++--
 .../open/api/impl/WxOpenComponentServiceImpl.java      |  8 ++++----
 .../open/api/impl/WxOpenInMemoryConfigStorage.java     | 10 +++++-----
 4 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/res/StringManager.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/res/StringManager.java
index e3f4aa05e9..e5bdb38804 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/res/StringManager.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/res/StringManager.java
@@ -19,6 +19,7 @@
 
 import java.text.MessageFormat;
 import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * An internationalization / localization helper class which reduces
@@ -46,7 +47,7 @@
  */
 public class StringManager {
 
-  private static final Map> MANAGERS = new Hashtable<>();
+  private static final Map> MANAGERS = new ConcurrentHashMap<>();
   private static int LOCALE_CACHE_SIZE = 10;
   /**
    * The ResourceBundle for this StringManager.
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaVisitDistributionGsonAdapter.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaVisitDistributionGsonAdapter.java
index 45bdbac0ff..0fc79d44bd 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaVisitDistributionGsonAdapter.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaVisitDistributionGsonAdapter.java
@@ -10,9 +10,9 @@
 import me.chanjar.weixin.common.util.json.GsonHelper;
 
 import java.lang.reflect.Type;
-import java.util.Hashtable;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * @author Charming
@@ -36,7 +36,7 @@ public WxMaVisitDistribution deserialize(JsonElement json, Type type, JsonDeseri
     }
 
     JsonArray listArray = object.getAsJsonArray("list");
-    Map> list = new Hashtable<>(listArray.size());
+    Map> list = new ConcurrentHashMap<>(listArray.size());
     for (JsonElement indexElement : listArray) {
       JsonObject indexObject = indexElement.getAsJsonObject();
       String index = GsonHelper.getString(indexObject, "index");
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java
index 8c4cad0071..9bc17374a2 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java
@@ -27,18 +27,18 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * @author 007
  */
 public class WxOpenComponentServiceImpl implements WxOpenComponentService {
   private static final JsonParser JSON_PARSER = new JsonParser();
-  private static final Map WX_OPEN_MA_SERVICE_MAP = new Hashtable<>();
-  private static final Map WX_OPEN_MP_SERVICE_MAP = new Hashtable<>();
-  private static final Map WX_OPEN_FAST_MA_SERVICE_MAP = new Hashtable<>();
+  private static final Map WX_OPEN_MA_SERVICE_MAP = new ConcurrentHashMap<>();
+  private static final Map WX_OPEN_MP_SERVICE_MAP = new ConcurrentHashMap<>();
+  private static final Map WX_OPEN_FAST_MA_SERVICE_MAP = new ConcurrentHashMap<>();
 
   protected final Logger log = LoggerFactory.getLogger(this.getClass());
   private WxOpenService wxOpenService;
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java
index 570721f1fd..36dfc29d0a 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java
@@ -2,8 +2,8 @@
 
 
 import java.io.File;
-import java.util.Hashtable;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
 
@@ -37,10 +37,10 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage {
   private String httpProxyPassword;
   private ApacheHttpClientBuilder apacheHttpClientBuilder;
 
-  private Map authorizerRefreshTokens = new Hashtable<>();
-  private Map authorizerAccessTokens = new Hashtable<>();
-  private Map jsapiTickets = new Hashtable<>();
-  private Map cardApiTickets = new Hashtable<>();
+  private Map authorizerRefreshTokens = new ConcurrentHashMap<>();
+  private Map authorizerAccessTokens = new ConcurrentHashMap<>();
+  private Map jsapiTickets = new ConcurrentHashMap<>();
+  private Map cardApiTickets = new ConcurrentHashMap<>();
 
   @Override
   public String getComponentAppId() {

From 2887c1e47eee15d7e3fabadf0e58da469bac8073 Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sun, 3 Mar 2019 10:29:17 +0800
Subject: [PATCH 32/81] =?UTF-8?q?#936=20=E4=BF=AE=E5=A4=8D=E5=BE=AE?=
 =?UTF-8?q?=E4=BF=A1=E6=94=AF=E4=BB=98=E6=B2=99=E7=AE=B1=E7=8E=AF=E5=A2=83?=
 =?UTF-8?q?=E9=80=80=E6=AC=BE=E6=8E=A5=E5=8F=A3=E7=9A=84=E8=AF=B7=E6=B1=82?=
 =?UTF-8?q?=E5=9C=B0=E5=9D=80?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java   | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java
index 616bf9a579..fdd3bcdd9b 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java
@@ -141,6 +141,10 @@ public WxPayRefundResult refund(WxPayRefundRequest request) throws WxPayExceptio
     request.checkAndSign(this.getConfig());
 
     String url = this.getPayBaseUrl() + "/secapi/pay/refund";
+    if (this.getConfig().isUseSandboxEnv()) {
+      url =  PAY_BASE_URL + "/sandboxnew/pay/refund";
+    }
+
     String responseContent = this.post(url, request.toXML(), true);
     WxPayRefundResult result = WxPayRefundResult.fromXML(responseContent);
     result.checkResult(this, request.getSignType(), true);

From b1a355218a75029f864e5e0e825fad74d12e94b0 Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sun, 3 Mar 2019 10:32:11 +0800
Subject: [PATCH 33/81] =?UTF-8?q?#957=20=E4=BF=AE=E6=94=B9=E5=BE=AE?=
 =?UTF-8?q?=E4=BF=A1=E6=94=AF=E4=BB=98=E9=80=80=E6=AC=BE=E5=93=8D=E5=BA=94?=
 =?UTF-8?q?=E7=B1=BB=E7=9A=84cash=5Frefund=5Ffee=E5=AD=97=E6=AE=B5?=
 =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E4=B8=BAInteger?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../binarywang/wxpay/bean/result/WxPayRefundResult.java       | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResult.java
index b60011baf2..9b971123aa 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResult.java
@@ -90,10 +90,10 @@ public class WxPayRefundResult extends BaseWxPayResult implements Serializable {
   private String cashFeeType;
 
   /**
-   * 现金退款金额.
+   * 现金退款金额,单位为分,只能为整数,详见支付金额.
    */
   @XStreamAlias("cash_refund_fee")
-  private String cashRefundFee;
+  private Integer cashRefundFee;
 
   /**
    * 退款代金券使用数量.

From 3bf866e7ff9d1903d2d682fc059e8ef731dd04ea Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sun, 3 Mar 2019 10:55:01 +0800
Subject: [PATCH 34/81] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BC=80=E6=94=BE?=
 =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E6=8B=BC=E5=86=99=E9=94=99=E8=AF=AF=E7=9A=84?=
 =?UTF-8?q?=E6=96=B9=E6=B3=95=E5=90=8D=20updateComponentAccessTokent?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../me/chanjar/weixin/open/api/WxOpenConfigStorage.java     | 4 ++--
 .../weixin/open/api/impl/WxOpenComponentServiceImpl.java    | 2 +-
 .../weixin/open/api/impl/WxOpenInMemoryConfigStorage.java   | 6 +++---
 .../weixin/open/api/impl/WxOpenInRedisConfigStorage.java    | 2 +-
 .../chanjar/weixin/open/api/impl/WxOpenMaServiceImpl.java   | 2 ++
 5 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java
index de9044ee1b..066cf8c00f 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenConfigStorage.java
@@ -37,7 +37,7 @@ public interface WxOpenConfigStorage {
 
   void expireComponentAccessToken();
 
-  void updateComponentAccessTokent(WxOpenComponentAccessToken componentAccessToken);
+  void updateComponentAccessToken(WxOpenComponentAccessToken componentAccessToken);
 
   String getHttpProxyHost();
 
@@ -59,7 +59,7 @@ public interface WxOpenConfigStorage {
    * @param componentAccessToken 新的accessToken值
    * @param expiresInSeconds     过期时间,以秒为单位
    */
-  void updateComponentAccessTokent(String componentAccessToken, int expiresInSeconds);
+  void updateComponentAccessToken(String componentAccessToken, int expiresInSeconds);
 
   /**
    * 是否自动刷新token
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java
index 9bc17374a2..213fb01995 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java
@@ -124,7 +124,7 @@ public String getComponentAccessToken(boolean forceRefresh) throws WxErrorExcept
 
       String responseContent = this.getWxOpenService().post(API_COMPONENT_TOKEN_URL, jsonObject.toString());
       WxOpenComponentAccessToken componentAccessToken = WxOpenComponentAccessToken.fromJson(responseContent);
-      getWxOpenConfigStorage().updateComponentAccessTokent(componentAccessToken);
+      getWxOpenConfigStorage().updateComponentAccessToken(componentAccessToken);
     }
     return this.getWxOpenConfigStorage().getComponentAccessToken();
   }
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java
index 36dfc29d0a..da34e808d4 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInMemoryConfigStorage.java
@@ -108,8 +108,8 @@ public void expireComponentAccessToken() {
   }
 
   @Override
-  public void updateComponentAccessTokent(WxOpenComponentAccessToken componentAccessToken) {
-    updateComponentAccessTokent(componentAccessToken.getComponentAccessToken(), componentAccessToken.getExpiresIn());
+  public void updateComponentAccessToken(WxOpenComponentAccessToken componentAccessToken) {
+    updateComponentAccessToken(componentAccessToken.getComponentAccessToken(), componentAccessToken.getExpiresIn());
   }
 
   @Override
@@ -168,7 +168,7 @@ public WxMaConfig getWxMaConfig(String appId) {
   }
 
   @Override
-  public void updateComponentAccessTokent(String componentAccessToken, int expiresInSeconds) {
+  public void updateComponentAccessToken(String componentAccessToken, int expiresInSeconds) {
     this.componentAccessToken = componentAccessToken;
     this.componentExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
   }
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInRedisConfigStorage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInRedisConfigStorage.java
index 3745a15034..1ddfc0ff11 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInRedisConfigStorage.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInRedisConfigStorage.java
@@ -91,7 +91,7 @@ public void expireComponentAccessToken(){
   }
 
   @Override
-  public void updateComponentAccessTokent(String componentAccessToken, int expiresInSeconds) {
+  public void updateComponentAccessToken(String componentAccessToken, int expiresInSeconds) {
     try (Jedis jedis = this.jedisPool.getResource()) {
       jedis.setex(this.componentAccessTokenKey, expiresInSeconds - 200, componentAccessToken);
     }
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaServiceImpl.java
index 623338d001..b1ba0f7f65 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaServiceImpl.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenMaServiceImpl.java
@@ -76,6 +76,7 @@ public WxOpenMaDomainResult getDomain() throws WxErrorException {
    * @return
    * @throws WxErrorException
    */
+  @Override
   public WxOpenMaDomainResult modifyDomain(String action, List requestdomainList, List wsrequestdomainList, List uploaddomainList, List downloaddomainList) throws WxErrorException {
 
 //    if (!"get".equals(action) && (requestdomainList == null || wsrequestdomainList == null || uploaddomainList == null || downloaddomainList == null)) {
@@ -252,6 +253,7 @@ public WxOpenMaPageListResult getPageList() throws WxErrorException {
    * @return
    * @throws WxErrorException
    */
+  @Override
   public WxOpenMaSubmitAuditResult submitAudit(WxOpenMaSubmitAuditMessage submitAuditMessage) throws WxErrorException {
     String response = post(API_SUBMIT_AUDIT, GSON.toJson(submitAuditMessage));
     return WxMaGsonBuilder.create().fromJson(response, WxOpenMaSubmitAuditResult.class);

From 8ef459c964d809557075beb2bd763a3c5f7c40f3 Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sun, 3 Mar 2019 10:56:56 +0800
Subject: [PATCH 35/81] =?UTF-8?q?#943=20=E4=BC=98=E5=8C=96=E5=85=AC?=
 =?UTF-8?q?=E4=BC=97=E5=8F=B7=E3=80=81=E5=B0=8F=E7=A8=8B=E5=BA=8F=E3=80=81?=
 =?UTF-8?q?=E4=BC=81=E4=B8=9A=E5=BE=AE=E4=BF=A1=E6=A8=A1=E5=9D=97=E8=8E=B7?=
 =?UTF-8?q?=E5=8F=96accessToken=E5=85=B3=E4=BA=8Elock=E7=9A=84=E9=80=BB?=
 =?UTF-8?q?=E8=BE=91=EF=BC=8C=E7=BC=A9=E5=B0=8F=E9=94=81=E7=9A=84=E8=8C=83?=
 =?UTF-8?q?=E5=9B=B4=EF=BC=8C=E6=8F=90=E9=AB=98=E6=95=88=E7=8E=87=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../impl/WxCpServiceApacheHttpClientImpl.java | 60 ++++++------
 .../cp/api/impl/WxCpServiceJoddHttpImpl.java  | 41 ++++----
 .../cp/api/impl/WxCpServiceOkHttpImpl.java    | 51 +++++-----
 .../wx/miniapp/api/impl/WxMaServiceImpl.java  | 96 ++++++++-----------
 .../api/impl/WxMpServiceHttpClientImpl.java   | 49 +++++-----
 .../mp/api/impl/WxMpServiceJoddHttpImpl.java  | 49 +++++-----
 .../mp/api/impl/WxMpServiceOkHttpImpl.java    | 38 ++++----
 7 files changed, 183 insertions(+), 201 deletions(-)

diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java
index cbf570ce59..eedb0419a3 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java
@@ -39,37 +39,37 @@ public HttpType getRequestType() {
 
   @Override
   public String getAccessToken(boolean forceRefresh) throws WxErrorException {
-    if (this.configStorage.isAccessTokenExpired() || forceRefresh) {
-      synchronized (this.globalAccessTokenRefreshLock) {
-        if (this.configStorage.isAccessTokenExpired()) {
-          String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?"
-            + "&corpid=" + this.configStorage.getCorpId()
-            + "&corpsecret=" + this.configStorage.getCorpSecret();
-          try {
-            HttpGet httpGet = new HttpGet(url);
-            if (this.httpProxy != null) {
-              RequestConfig config = RequestConfig.custom()
-                .setProxy(this.httpProxy).build();
-              httpGet.setConfig(config);
-            }
-            String resultContent = null;
-            try (CloseableHttpClient httpclient = getRequestHttpClient();
-                 CloseableHttpResponse response = httpclient.execute(httpGet)) {
-              resultContent = new BasicResponseHandler().handleResponse(response);
-            } finally {
-              httpGet.releaseConnection();
-            }
-            WxError error = WxError.fromJson(resultContent, WxType.CP);
-            if (error.getErrorCode() != 0) {
-              throw new WxErrorException(error);
-            }
-            WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
-            this.configStorage.updateAccessToken(
-              accessToken.getAccessToken(), accessToken.getExpiresIn());
-          } catch (IOException e) {
-            throw new RuntimeException(e);
-          }
+    if (!this.configStorage.isAccessTokenExpired() && !forceRefresh) {
+      return this.configStorage.getAccessToken();
+    }
+
+    synchronized (this.globalAccessTokenRefreshLock) {
+      String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?"
+        + "&corpid=" + this.configStorage.getCorpId()
+        + "&corpsecret=" + this.configStorage.getCorpSecret();
+      try {
+        HttpGet httpGet = new HttpGet(url);
+        if (this.httpProxy != null) {
+          RequestConfig config = RequestConfig.custom()
+            .setProxy(this.httpProxy).build();
+          httpGet.setConfig(config);
+        }
+        String resultContent;
+        try (CloseableHttpClient httpclient = getRequestHttpClient();
+             CloseableHttpResponse response = httpclient.execute(httpGet)) {
+          resultContent = new BasicResponseHandler().handleResponse(response);
+        } finally {
+          httpGet.releaseConnection();
         }
+        WxError error = WxError.fromJson(resultContent, WxType.CP);
+        if (error.getErrorCode() != 0) {
+          throw new WxErrorException(error);
+        }
+
+        WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
+        this.configStorage.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
+      } catch (IOException e) {
+        throw new RuntimeException(e);
       }
     }
     return this.configStorage.getAccessToken();
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceJoddHttpImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceJoddHttpImpl.java
index 93da174d5a..3603a59b17 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceJoddHttpImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceJoddHttpImpl.java
@@ -30,30 +30,29 @@ public HttpType getRequestType() {
 
   @Override
   public String getAccessToken(boolean forceRefresh) throws WxErrorException {
-    if (this.configStorage.isAccessTokenExpired() || forceRefresh) {
-      synchronized (this.globalAccessTokenRefreshLock) {
-        if (this.configStorage.isAccessTokenExpired()) {
-          String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?"
-            + "&corpid=" + this.configStorage.getCorpId()
-            + "&corpsecret=" + this.configStorage.getCorpSecret();
+    if (!this.configStorage.isAccessTokenExpired() && !forceRefresh) {
+      return this.configStorage.getAccessToken();
+    }
+
+    synchronized (this.globalAccessTokenRefreshLock) {
+      String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?"
+        + "&corpid=" + this.configStorage.getCorpId()
+        + "&corpsecret=" + this.configStorage.getCorpSecret();
 
-          HttpRequest request = HttpRequest.get(url);
-          if (this.httpProxy != null) {
-            httpClient.useProxy(this.httpProxy);
-          }
-          request.withConnectionProvider(httpClient);
-          HttpResponse response = request.send();
+      HttpRequest request = HttpRequest.get(url);
+      if (this.httpProxy != null) {
+        httpClient.useProxy(this.httpProxy);
+      }
+      request.withConnectionProvider(httpClient);
+      HttpResponse response = request.send();
 
-          String resultContent = response.bodyText();
-          WxError error = WxError.fromJson(resultContent, WxType.CP);
-          if (error.getErrorCode() != 0) {
-            throw new WxErrorException(error);
-          }
-          WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
-          this.configStorage.updateAccessToken(
-            accessToken.getAccessToken(), accessToken.getExpiresIn());
-        }
+      String resultContent = response.bodyText();
+      WxError error = WxError.fromJson(resultContent, WxType.CP);
+      if (error.getErrorCode() != 0) {
+        throw new WxErrorException(error);
       }
+      WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
+      this.configStorage.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
     }
     return this.configStorage.getAccessToken();
   }
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java
index 47402fb341..9163ce03a6 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java
@@ -33,34 +33,33 @@ public HttpType getRequestType() {
 
   @Override
   public String getAccessToken(boolean forceRefresh) throws WxErrorException {
-    this.log.debug("WxCpServiceOkHttpImpl is running");
-    if (this.configStorage.isAccessTokenExpired() || forceRefresh) {
-      synchronized (this.globalAccessTokenRefreshLock) {
-        if (this.configStorage.isAccessTokenExpired()) {
-          String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?"
-            + "&corpid=" + this.configStorage.getCorpId()
-            + "&corpsecret=" + this.configStorage.getCorpSecret();
-          //得到httpClient
-          OkHttpClient client = getRequestHttpClient();
-          //请求的request
-          Request request = new Request.Builder().url(url).get().build();
-          String resultContent = null;
-          try {
-            Response response = client.newCall(request).execute();
-            resultContent = response.body().string();
-          } catch (IOException e) {
-            this.log.error(e.getMessage(), e);
-          }
+    if (!this.configStorage.isAccessTokenExpired() && !forceRefresh) {
+      return this.configStorage.getAccessToken();
+    }
+
+    synchronized (this.globalAccessTokenRefreshLock) {
+        String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?"
+          + "&corpid=" + this.configStorage.getCorpId()
+          + "&corpsecret=" + this.configStorage.getCorpSecret();
+        //得到httpClient
+        OkHttpClient client = getRequestHttpClient();
+        //请求的request
+        Request request = new Request.Builder().url(url).get().build();
+        String resultContent = null;
+        try {
+          Response response = client.newCall(request).execute();
+          resultContent = response.body().string();
+        } catch (IOException e) {
+          this.log.error(e.getMessage(), e);
+        }
 
-          WxError error = WxError.fromJson(resultContent, WxType.CP);
-          if (error.getErrorCode() != 0) {
-            throw new WxErrorException(error);
-          }
-          WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
-          this.configStorage.updateAccessToken(accessToken.getAccessToken(),
-            accessToken.getExpiresIn());
+        WxError error = WxError.fromJson(resultContent, WxType.CP);
+        if (error.getErrorCode() != 0) {
+          throw new WxErrorException(error);
         }
-      }
+        WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
+        this.configStorage.updateAccessToken(accessToken.getAccessToken(),
+          accessToken.getExpiresIn());
     }
     return this.configStorage.getAccessToken();
   }
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java
index a12fa1fea1..d4f9721805 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java
@@ -1,31 +1,6 @@
 package cn.binarywang.wx.miniapp.api.impl;
 
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.locks.Lock;
-
-import org.apache.commons.lang3.StringUtils;
-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.HttpGet;
-import org.apache.http.impl.client.BasicResponseHandler;
-import org.apache.http.impl.client.CloseableHttpClient;
-
-import cn.binarywang.wx.miniapp.api.WxMaAnalysisService;
-import cn.binarywang.wx.miniapp.api.WxMaCodeService;
-import cn.binarywang.wx.miniapp.api.WxMaJsapiService;
-import cn.binarywang.wx.miniapp.api.WxMaMediaService;
-import cn.binarywang.wx.miniapp.api.WxMaMsgService;
-import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
-import cn.binarywang.wx.miniapp.api.WxMaRunService;
-import cn.binarywang.wx.miniapp.api.WxMaSecCheckService;
-import cn.binarywang.wx.miniapp.api.WxMaService;
-import cn.binarywang.wx.miniapp.api.WxMaSettingService;
-import cn.binarywang.wx.miniapp.api.WxMaShareService;
-import cn.binarywang.wx.miniapp.api.WxMaTemplateService;
-import cn.binarywang.wx.miniapp.api.WxMaUserService;
+import cn.binarywang.wx.miniapp.api.*;
 import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
 import cn.binarywang.wx.miniapp.config.WxMaConfig;
 import com.google.common.base.Joiner;
@@ -38,13 +13,21 @@
 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.HttpType;
-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.http.*;
 import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
 import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder;
+import org.apache.commons.lang3.StringUtils;
+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.HttpGet;
+import org.apache.http.impl.client.BasicResponseHandler;
+import org.apache.http.impl.client.CloseableHttpClient;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
 
 import static cn.binarywang.wx.miniapp.constant.WxMaConstants.ErrorCode.*;
 
@@ -118,40 +101,41 @@ public RequestHttp getRequestHttp() {
 
   @Override
   public String getAccessToken(boolean forceRefresh) throws WxErrorException {
+    if (!this.getWxMaConfig().isAccessTokenExpired() && !forceRefresh) {
+      return this.getWxMaConfig().getAccessToken();
+    }
+
     Lock lock = this.getWxMaConfig().getAccessTokenLock();
+    lock.lock();
     try {
-      lock.lock();
-
-      if (this.getWxMaConfig().isAccessTokenExpired() || forceRefresh) {
-        String url = String.format(WxMaService.GET_ACCESS_TOKEN_URL, this.getWxMaConfig().getAppid(),
-          this.getWxMaConfig().getSecret());
-        try {
-          HttpGet httpGet = new HttpGet(url);
-          if (this.getRequestHttpProxy() != null) {
-            RequestConfig config = RequestConfig.custom().setProxy(this.getRequestHttpProxy()).build();
-            httpGet.setConfig(config);
-          }
-          try (CloseableHttpResponse response = getRequestHttpClient().execute(httpGet)) {
-            String resultContent = new BasicResponseHandler().handleResponse(response);
-            WxError error = WxError.fromJson(resultContent);
-            if (error.getErrorCode() != 0) {
-              throw new WxErrorException(error);
-            }
-            WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
-            this.getWxMaConfig().updateAccessToken(accessToken.getAccessToken(),
-              accessToken.getExpiresIn());
-          } finally {
-            httpGet.releaseConnection();
+      String url = String.format(WxMaService.GET_ACCESS_TOKEN_URL, this.getWxMaConfig().getAppid(),
+        this.getWxMaConfig().getSecret());
+      try {
+        HttpGet httpGet = new HttpGet(url);
+        if (this.getRequestHttpProxy() != null) {
+          RequestConfig config = RequestConfig.custom().setProxy(this.getRequestHttpProxy()).build();
+          httpGet.setConfig(config);
+        }
+        try (CloseableHttpResponse response = getRequestHttpClient().execute(httpGet)) {
+          String resultContent = new BasicResponseHandler().handleResponse(response);
+          WxError error = WxError.fromJson(resultContent);
+          if (error.getErrorCode() != 0) {
+            throw new WxErrorException(error);
           }
-        } catch (IOException e) {
-          throw new RuntimeException(e);
+          WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
+          this.getWxMaConfig().updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
+          
+          return this.getWxMaConfig().getAccessToken();
+        } finally {
+          httpGet.releaseConnection();
         }
+      } catch (IOException e) {
+        throw new RuntimeException(e);
       }
     } finally {
       lock.unlock();
     }
 
-    return this.getWxMaConfig().getAccessToken();
   }
 
   @Override
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpClientImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpClientImpl.java
index 3db9e9b149..10e2a5b78f 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpClientImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceHttpClientImpl.java
@@ -63,37 +63,38 @@ public void initHttp() {
 
   @Override
   public String getAccessToken(boolean forceRefresh) throws WxErrorException {
+    if (!this.getWxMpConfigStorage().isAccessTokenExpired() && !forceRefresh) {
+      return this.getWxMpConfigStorage().getAccessToken();
+    }
+
     Lock lock = this.getWxMpConfigStorage().getAccessTokenLock();
+    lock.lock();
     try {
-      lock.lock();
-      if (this.getWxMpConfigStorage().isAccessTokenExpired() || forceRefresh) {
-        String url = String.format(WxMpService.GET_ACCESS_TOKEN_URL,
-          this.getWxMpConfigStorage().getAppId(), this.getWxMpConfigStorage().getSecret());
-        try {
-          HttpGet httpGet = new HttpGet(url);
-          if (this.getRequestHttpProxy() != null) {
-            RequestConfig config = RequestConfig.custom().setProxy(this.getRequestHttpProxy()).build();
-            httpGet.setConfig(config);
-          }
-          try (CloseableHttpResponse response = getRequestHttpClient().execute(httpGet)) {
-            String resultContent = new BasicResponseHandler().handleResponse(response);
-            WxError error = WxError.fromJson(resultContent, WxType.MP);
-            if (error.getErrorCode() != 0) {
-              throw new WxErrorException(error);
-            }
-            WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
-            this.getWxMpConfigStorage().updateAccessToken(accessToken.getAccessToken(),
-              accessToken.getExpiresIn());
-          } finally {
-            httpGet.releaseConnection();
+      String url = String.format(WxMpService.GET_ACCESS_TOKEN_URL,
+        this.getWxMpConfigStorage().getAppId(), this.getWxMpConfigStorage().getSecret());
+      try {
+        HttpGet httpGet = new HttpGet(url);
+        if (this.getRequestHttpProxy() != null) {
+          RequestConfig config = RequestConfig.custom().setProxy(this.getRequestHttpProxy()).build();
+          httpGet.setConfig(config);
+        }
+        try (CloseableHttpResponse response = getRequestHttpClient().execute(httpGet)) {
+          String resultContent = new BasicResponseHandler().handleResponse(response);
+          WxError error = WxError.fromJson(resultContent, WxType.MP);
+          if (error.getErrorCode() != 0) {
+            throw new WxErrorException(error);
           }
-        } catch (IOException e) {
-          throw new RuntimeException(e);
+          WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
+          this.getWxMpConfigStorage().updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
+          return this.getWxMpConfigStorage().getAccessToken();
+        } finally {
+          httpGet.releaseConnection();
         }
+      } catch (IOException e) {
+        throw new RuntimeException(e);
       }
     } finally {
       lock.unlock();
     }
-    return this.getWxMpConfigStorage().getAccessToken();
   }
 }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceJoddHttpImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceJoddHttpImpl.java
index ee8411ab73..c00cd43234 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceJoddHttpImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceJoddHttpImpl.java
@@ -48,36 +48,37 @@ public void initHttp() {
 
   @Override
   public String getAccessToken(boolean forceRefresh) throws WxErrorException {
+    if (!this.getWxMpConfigStorage().isAccessTokenExpired() && !forceRefresh) {
+      return this.getWxMpConfigStorage().getAccessToken();
+    }
+
     Lock lock = this.getWxMpConfigStorage().getAccessTokenLock();
+    lock.lock();
     try {
-      lock.lock();
-
-      if (this.getWxMpConfigStorage().isAccessTokenExpired() || forceRefresh) {
-        String url = String.format(WxMpService.GET_ACCESS_TOKEN_URL,
-          this.getWxMpConfigStorage().getAppId(), this.getWxMpConfigStorage().getSecret());
-
-        HttpRequest request = HttpRequest.get(url);
-
-        if (this.getRequestHttpProxy() != null) {
-          SocketHttpConnectionProvider provider = new SocketHttpConnectionProvider();
-          provider.useProxy(getRequestHttpProxy());
-
-          request.withConnectionProvider(provider);
-        }
-        HttpResponse response = request.send();
-        String resultContent = response.bodyText();
-        WxError error = WxError.fromJson(resultContent, WxType.MP);
-        if (error.getErrorCode() != 0) {
-          throw new WxErrorException(error);
-        }
-        WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
-        this.getWxMpConfigStorage().updateAccessToken(accessToken.getAccessToken(),
-          accessToken.getExpiresIn());
+      String url = String.format(WxMpService.GET_ACCESS_TOKEN_URL,
+        this.getWxMpConfigStorage().getAppId(), this.getWxMpConfigStorage().getSecret());
+
+      HttpRequest request = HttpRequest.get(url);
+
+      if (this.getRequestHttpProxy() != null) {
+        SocketHttpConnectionProvider provider = new SocketHttpConnectionProvider();
+        provider.useProxy(getRequestHttpProxy());
+
+        request.withConnectionProvider(provider);
+      }
+      HttpResponse response = request.send();
+      String resultContent = response.bodyText();
+      WxError error = WxError.fromJson(resultContent, WxType.MP);
+      if (error.getErrorCode() != 0) {
+        throw new WxErrorException(error);
       }
+      WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
+      this.getWxMpConfigStorage().updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
+
+      return this.getWxMpConfigStorage().getAccessToken();
     } finally {
       lock.unlock();
     }
-    return this.getWxMpConfigStorage().getAccessToken();
   }
 
 }
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java
index 6d3f5bf29a..e88fad1425 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java
@@ -36,38 +36,36 @@ public HttpType getRequestType() {
 
   @Override
   public String getAccessToken(boolean forceRefresh) throws WxErrorException {
-    this.log.debug("WxMpServiceOkHttpImpl is running");
+    if (!this.getWxMpConfigStorage().isAccessTokenExpired() && !forceRefresh) {
+      return this.getWxMpConfigStorage().getAccessToken();
+    }
+
     Lock lock = this.getWxMpConfigStorage().getAccessTokenLock();
+    lock.lock();
     try {
-      lock.lock();
-
-      if (this.getWxMpConfigStorage().isAccessTokenExpired() || forceRefresh) {
-        String url = String.format(WxMpService.GET_ACCESS_TOKEN_URL,
-          this.getWxMpConfigStorage().getAppId(), this.getWxMpConfigStorage().getSecret());
+      String url = String.format(WxMpService.GET_ACCESS_TOKEN_URL,
+        this.getWxMpConfigStorage().getAppId(), this.getWxMpConfigStorage().getSecret());
 
-        Request request = new Request.Builder().url(url).get().build();
-        Response response = getRequestHttpClient().newCall(request).execute();
-        String resultContent = response.body().string();
-        WxError error = WxError.fromJson(resultContent, WxType.MP);
-        if (error.getErrorCode() != 0) {
-          throw new WxErrorException(error);
-        }
-        WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
-        this.getWxMpConfigStorage().updateAccessToken(accessToken.getAccessToken(),
-          accessToken.getExpiresIn());
+      Request request = new Request.Builder().url(url).get().build();
+      Response response = getRequestHttpClient().newCall(request).execute();
+      String resultContent = response.body().string();
+      WxError error = WxError.fromJson(resultContent, WxType.MP);
+      if (error.getErrorCode() != 0) {
+        throw new WxErrorException(error);
       }
+      WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
+      this.getWxMpConfigStorage().updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
+
+      return this.getWxMpConfigStorage().getAccessToken();
     } catch (IOException e) {
-      this.log.error(e.getMessage(), e);
+      throw new RuntimeException(e);
     } finally {
       lock.unlock();
     }
-    return this.getWxMpConfigStorage().getAccessToken();
   }
 
   @Override
   public void initHttp() {
-    this.log.debug("WxMpServiceOkHttpImpl initHttp");
-
     //设置代理
     if (wxMpConfigStorage.getHttpProxyHost() != null && wxMpConfigStorage.getHttpProxyPort() > 0) {
       httpProxy = OkHttpProxyInfo.httpProxy(wxMpConfigStorage.getHttpProxyHost(),

From 507921be659a7e9e292be6b0a7a0c8d93835320a Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sun, 3 Mar 2019 11:21:24 +0800
Subject: [PATCH 36/81] =?UTF-8?q?=E5=8F=91=E5=B8=833.3.5.B=20=E6=B5=8B?=
 =?UTF-8?q?=E8=AF=95=E7=89=88=E6=9C=AC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 pom.xml                     | 2 +-
 weixin-java-common/pom.xml  | 2 +-
 weixin-java-cp/pom.xml      | 2 +-
 weixin-java-miniapp/pom.xml | 2 +-
 weixin-java-mp/pom.xml      | 2 +-
 weixin-java-open/pom.xml    | 2 +-
 weixin-java-pay/pom.xml     | 2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/pom.xml b/pom.xml
index b8f88ef8b7..dafb86eab5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
   4.0.0
   com.github.binarywang
   wx-java
-  3.3.4.B
+  3.3.5.B
   pom
   WxJava - Weixin/Wechat Java SDK
   微信开发Java SDK
diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml
index 6a153612a6..ff0b835c91 100644
--- a/weixin-java-common/pom.xml
+++ b/weixin-java-common/pom.xml
@@ -7,7 +7,7 @@
   
     com.github.binarywang
     wx-java
-    3.3.4.B
+    3.3.5.B
   
 
   weixin-java-common
diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml
index 7bf4acca36..23f62a4220 100644
--- a/weixin-java-cp/pom.xml
+++ b/weixin-java-cp/pom.xml
@@ -7,7 +7,7 @@
   
     com.github.binarywang
     wx-java
-    3.3.4.B
+    3.3.5.B
   
 
   weixin-java-cp
diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml
index 7bec0add26..5d59d278b9 100644
--- a/weixin-java-miniapp/pom.xml
+++ b/weixin-java-miniapp/pom.xml
@@ -7,7 +7,7 @@
   
     com.github.binarywang
     wx-java
-    3.3.4.B
+    3.3.5.B
   
 
   weixin-java-miniapp
diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml
index 86b1c89104..eec6fc3caa 100644
--- a/weixin-java-mp/pom.xml
+++ b/weixin-java-mp/pom.xml
@@ -7,7 +7,7 @@
   
     com.github.binarywang
     wx-java
-    3.3.4.B
+    3.3.5.B
   
 
   weixin-java-mp
diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml
index 73096345c0..3bbc973835 100644
--- a/weixin-java-open/pom.xml
+++ b/weixin-java-open/pom.xml
@@ -7,7 +7,7 @@
   
     com.github.binarywang
     wx-java
-    3.3.4.B
+    3.3.5.B
   
 
   weixin-java-open
diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml
index f76a66206b..cc39e438aa 100644
--- a/weixin-java-pay/pom.xml
+++ b/weixin-java-pay/pom.xml
@@ -5,7 +5,7 @@
   
     com.github.binarywang
     wx-java
-    3.3.4.B
+    3.3.5.B
   
   4.0.0
 

From b33e1708c0e4e3616b1f3ea6bca5a6e5a84f9cc4 Mon Sep 17 00:00:00 2001
From: RoyZ 
Date: Tue, 12 Mar 2019 16:23:40 +0800
Subject: [PATCH 37/81] =?UTF-8?q?#970=20=E7=AC=AC=E4=B8=89=E6=96=B9?=
 =?UTF-8?q?=E5=B9=B3=E5=8F=B0-=E5=B0=8F=E7=A8=8B=E5=BA=8F=E5=B8=90?=
 =?UTF-8?q?=E5=8F=B7=E4=B8=8A=E4=BC=A0=E5=B0=8F=E7=A8=8B=E5=BA=8F=E4=BB=A3?=
 =?UTF-8?q?=E7=A0=81=E5=A2=9E=E5=8A=A0=E7=BC=BA=E5=A4=B1=E7=9A=84subpackag?=
 =?UTF-8?q?es=E5=88=86=E5=8C=85=E4=B8=8A=E4=BC=A0=E5=8F=82=E6=95=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

 #968 第三方授权-授权注册页面扫码授权地址参数补充完整
---
 .../open/api/WxOpenComponentService.java      |  2 +-
 .../open/bean/ma/WxMaOpenCommitExtInfo.java   |  6 ++++
 .../open/bean/ma/WxMaOpenSubpackage.java      | 35 +++++++++++++++++++
 3 files changed, 42 insertions(+), 1 deletion(-)
 create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenSubpackage.java

diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java
index 7016bd1b6c..b9c7ff1064 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java
@@ -26,7 +26,7 @@ public interface WxOpenComponentService {
   String API_GET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/api_get_authorizer_option";
   String API_SET_AUTHORIZER_OPTION_URL = "https://api.weixin.qq.com/cgi-bin/component/api_set_authorizer_option";
 
-  String COMPONENT_LOGIN_PAGE_URL = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=%s&pre_auth_code=%s&redirect_uri=%s";
+  String COMPONENT_LOGIN_PAGE_URL = "https://mp.weixin.qq.com/cgi-bin/componentloginpage?component_appid=%s&pre_auth_code=%s&redirect_uri=%s&auth_type=xxx&biz_appid=xxx";
 
   /**
    * 手机端打开授权链接
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenCommitExtInfo.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenCommitExtInfo.java
index c38867bae7..66aebec3fd 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenCommitExtInfo.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenCommitExtInfo.java
@@ -43,6 +43,12 @@ public class WxMaOpenCommitExtInfo implements Serializable {
   @SerializedName("pages")
   private List pageList;
 
+  /**
+   * 分包结构配置
+   */
+  @SerializedName("subpackages")
+  private List subpackageList;
+
   @SerializedName("window")
   private WxMaOpenWindow window;
 
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenSubpackage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenSubpackage.java
new file mode 100644
index 0000000000..e74049a530
--- /dev/null
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxMaOpenSubpackage.java
@@ -0,0 +1,35 @@
+package me.chanjar.weixin.open.bean.ma;
+
+import lombok.Builder;
+import lombok.Data;
+
+/**
+ * @author: momorans
+ * @create: 2019-03-12
+ **/
+@Data
+@Builder
+public class WxMaOpenSubpackage {
+  /**
+   * 分包根目录
+   */
+  private String root;
+
+  /**
+   * 分包别名,分包预下载时可以使用
+   */
+  private String name;
+
+
+  /**
+   * 分包页面路径,相对与分包根目录
+   */
+  private String pages;
+
+  /**
+   * 分包是否是独立分包
+   */
+  private Boolean independent;
+
+
+}

From be33986ecd6463b32fb2b8bc980607a25d40898c Mon Sep 17 00:00:00 2001
From: 007gzs <007gzs@gmail.com>
Date: Fri, 15 Mar 2019 17:09:53 +0800
Subject: [PATCH 38/81] =?UTF-8?q?#978=20=E5=A2=9E=E5=8A=A0=E5=BE=AE?=
 =?UTF-8?q?=E4=BF=A1=E8=90=A5=E9=94=80=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../weixin/mp/api/WxMpMarketingService.java   | 71 ++++++++++++++
 .../me/chanjar/weixin/mp/api/WxMpService.java |  9 ++
 .../mp/api/impl/BaseWxMpServiceImpl.java      | 32 +++----
 .../mp/api/impl/WxMpMarketingServiceImpl.java | 92 +++++++++++++++++++
 .../weixin/mp/bean/marketing/WxMpAdLead.java  | 55 +++++++++++
 .../mp/bean/marketing/WxMpAdLeadFilter.java   | 32 +++++++
 .../mp/bean/marketing/WxMpAdLeadInfo.java     | 18 ++++
 .../mp/bean/marketing/WxMpAdLeadPageInfo.java | 23 +++++
 .../mp/bean/marketing/WxMpAdLeadResult.java   | 32 +++++++
 .../mp/bean/marketing/WxMpUserAction.java     | 39 ++++++++
 .../mp/bean/marketing/WxMpUserActionSet.java  | 56 +++++++++++
 .../mp/bean/result/WxMpAdLeadResultTest.java  | 75 +++++++++++++++
 12 files changed, 514 insertions(+), 20 deletions(-)
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMarketingService.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMarketingServiceImpl.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLead.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLeadFilter.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLeadInfo.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLeadPageInfo.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLeadResult.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpUserAction.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpUserActionSet.java
 create mode 100644 weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/result/WxMpAdLeadResultTest.java

diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMarketingService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMarketingService.java
new file mode 100644
index 0000000000..f59158b2bd
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMarketingService.java
@@ -0,0 +1,71 @@
+package me.chanjar.weixin.mp.api;
+
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.bean.marketing.WxMpAdLeadFilter;
+import me.chanjar.weixin.mp.bean.marketing.WxMpAdLeadResult;
+import me.chanjar.weixin.mp.bean.marketing.WxMpUserAction;
+import me.chanjar.weixin.mp.bean.marketing.WxMpUserActionSet;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 
+ * 微信营销接口
+ * 
+ * + * @author 007 + */ +public interface WxMpMarketingService { + String API_URL_PREFIX = "https://api.weixin.qq.com/marketing/"; + + /** + *
+   * 创建数据源
+   * 接口调用请求说明
+   * https://wximg.qq.com/wxp/pdftool/get.html?id=rkalQXDBM&pa=39
+   * 
+ * + * @param type 用户行为源类型 + * @param name 用户行为源名称 必填 + * @param description 用户行为源描述,字段长度最小 1 字节,长度最大 128 字节 + */ + long addUserActionSets(String type, String name, String description) throws WxErrorException; + + /** + *
+   * 获取数据源信息
+   * 
+ * + * @param userActionSetId 数据源唯一ID + */ + List getUserActionSets(Long userActionSetId) throws WxErrorException; + + /** + * 回传数据 + * 接口调用请求说明 + * https://wximg.qq.com/wxp/pdftool/get.html?id=rkalQXDBM&pa=39 + * + * @param actions 用户行为源类型 + */ + void addUserAction(List actions) throws WxErrorException; + + /** + *
+   * 获取朋友圈销售线索数据接口
+   * 接口调用请求说明
+   *
+   * http请求方式: POST
+   * http://api.weixin.qq.com/cgi-bin/media/voice/translatecontent?access_token=ACCESS_TOKEN&lfrom=xxx<o=xxx
+   *
+   * 
+ * + * @param beginDate 开始日期 + * @param endDate 结束日期 + * @param filtering 过滤条件 + * @param page 页码,获取指定页数据 + * @param page_size 一页获取的数据条数(1-100) + */ + WxMpAdLeadResult getAdLeads(Date beginDate, Date endDate, List filtering, Integer page, Integer page_size) throws WxErrorException, IOException; +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java index fead289a36..991e1de15a 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java @@ -411,6 +411,13 @@ public interface WxMpService { */ WxMpMemberCardService getMemberCardService(); + /** + * 返回营销相关接口方法的实现类对象,以方便调用其各个接口. + * + * @return WxMpMarketingService + */ + WxMpMarketingService getMarketingService(); + /** * 初始化http请求对象. */ @@ -473,4 +480,6 @@ public interface WxMpService { void setMassMessageService(WxMpMassMessageService massMessageService); void setAiOpenService(WxMpAiOpenService aiOpenService); + + void setMarketingService(WxMpMarketingService marketingService); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java index f720461652..2db223c337 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.util.concurrent.locks.Lock; +import me.chanjar.weixin.mp.api.*; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,26 +25,6 @@ import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; import me.chanjar.weixin.common.util.http.URIUtil; -import me.chanjar.weixin.mp.api.WxMpAiOpenService; -import me.chanjar.weixin.mp.api.WxMpCardService; -import me.chanjar.weixin.mp.api.WxMpConfigStorage; -import me.chanjar.weixin.mp.api.WxMpDataCubeService; -import me.chanjar.weixin.mp.api.WxMpDeviceService; -import me.chanjar.weixin.mp.api.WxMpKefuService; -import me.chanjar.weixin.mp.api.WxMpMassMessageService; -import me.chanjar.weixin.mp.api.WxMpMaterialService; -import me.chanjar.weixin.mp.api.WxMpMemberCardService; -import me.chanjar.weixin.mp.api.WxMpMenuService; -import me.chanjar.weixin.mp.api.WxMpQrcodeService; -import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.api.WxMpShakeService; -import me.chanjar.weixin.mp.api.WxMpStoreService; -import me.chanjar.weixin.mp.api.WxMpSubscribeMsgService; -import me.chanjar.weixin.mp.api.WxMpTemplateMsgService; -import me.chanjar.weixin.mp.api.WxMpUserBlacklistService; -import me.chanjar.weixin.mp.api.WxMpUserService; -import me.chanjar.weixin.mp.api.WxMpUserTagService; -import me.chanjar.weixin.mp.api.WxMpWifiService; import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; import me.chanjar.weixin.mp.bean.result.WxMpCurrentAutoReplyInfo; import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; @@ -81,6 +62,7 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH private WxMpMassMessageService massMessageService = new WxMpMassMessageServiceImpl(this); private WxMpAiOpenService aiOpenService = new WxMpAiOpenServiceImpl(this); private WxMpWifiService wifiService = new WxMpWifiServiceImpl(this); + private WxMpMarketingService marketingService = new WxMpMarketingServiceImpl(this); private int retrySleepMillis = 1000; private int maxRetryTimes = 5; @@ -545,4 +527,14 @@ public void setAiOpenService(WxMpAiOpenService aiOpenService) { public WxMpWifiService getWifiService() { return this.wifiService; } + + @Override + public WxMpMarketingService getMarketingService() { + return this.marketingService; + } + + @Override + public void setMarketingService(WxMpMarketingService marketingService) { + this.marketingService = marketingService; + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMarketingServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMarketingServiceImpl.java new file mode 100644 index 0000000000..91e7d4c1ba --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMarketingServiceImpl.java @@ -0,0 +1,92 @@ +package me.chanjar.weixin.mp.api.impl; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpMarketingService; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.bean.marketing.WxMpAdLeadFilter; +import me.chanjar.weixin.mp.bean.marketing.WxMpAdLeadResult; +import me.chanjar.weixin.mp.bean.marketing.WxMpUserAction; +import me.chanjar.weixin.mp.bean.marketing.WxMpUserActionSet; +import org.apache.commons.lang3.time.DateFormatUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Date; +import java.util.List; + +/** + * @author 007 + */ +public class WxMpMarketingServiceImpl implements WxMpMarketingService { + protected final Logger log = LoggerFactory.getLogger(this.getClass()); + private WxMpService wxMpService; + + public WxMpMarketingServiceImpl(WxMpService wxMpService) { + this.wxMpService = wxMpService; + } + + @Override + public long addUserActionSets(String type, String name, String description) throws WxErrorException { + String url = API_URL_PREFIX + "user_action_sets/add?version=v1.0"; + JsonObject json = new JsonObject(); + json.addProperty("type", type); + json.addProperty("name", name); + json.addProperty("description", description); + String responseContent = wxMpService.post(url, json.toString()); + JsonElement tmpJsonElement = new JsonParser().parse(responseContent); + return tmpJsonElement.getAsJsonObject().get("data").getAsJsonObject().get("user_action_set_id").getAsLong(); + } + + @Override + public List getUserActionSets(Long userActionSetId) throws WxErrorException { + String url = API_URL_PREFIX + "user_action_sets/get"; + String responseContent = wxMpService.get(url, "version=v1.0&user_action_set_id=" + userActionSetId); + return WxMpUserActionSet.fromJson(responseContent); + } + + @Override + public void addUserAction(List actions) throws WxErrorException { + String url = API_URL_PREFIX + "user_actions/add?version=v1.0"; + JsonArray json = new JsonArray(); + for (WxMpUserAction action : actions) { + json.add(action.toJsonObject()); + } + wxMpService.post(url, json.toString()); + } + + @Override + public WxMpAdLeadResult getAdLeads(Date beginDate, Date endDate, List filtering, Integer page, Integer page_size) throws WxErrorException, IOException { + Date today = new Date(); + if (beginDate == null) { + beginDate = today; + } + if (endDate == null) { + endDate = today; + } + String url = API_URL_PREFIX + "wechat_ad_leads/get"; + String params = "version=v1.0"; + JsonObject dateRange = new JsonObject(); + dateRange.addProperty("begin_date", DateFormatUtils.format(beginDate, "yyyy-MM-dd")); + dateRange.addProperty("end_date", DateFormatUtils.format(endDate, "yyyy-MM-dd")); + params += "&date_range=" + URLEncoder.encode(dateRange.toString(), StandardCharsets.UTF_8.name()); + params += "&page=" + page; + params += "&page_size=" + page_size; + if (filtering != null) { + JsonArray filterJson = new JsonArray(); + for (WxMpAdLeadFilter filter : filtering) { + filterJson.add(filter.toJsonObject()); + } + params += "&filtering=" + URLEncoder.encode(filterJson.toString(), StandardCharsets.UTF_8.name()); + ; + } + String responseContent = wxMpService.get(url, params); + return WxMpAdLeadResult.fromJson(responseContent); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLead.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLead.java new file mode 100644 index 0000000000..868d22a96b --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLead.java @@ -0,0 +1,55 @@ +package me.chanjar.weixin.mp.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author 007 + */ +@Data +public class WxMpAdLead implements Serializable { + private static final long serialVersionUID = -8889087268596440407L; + /** + * 点击ID + */ + @SerializedName("click_id") + private String click_id; + /** + * 广告组ID + */ + @SerializedName("adgroup_id") + private Long adgroup_id; + /** + * 广告组名称 + */ + @SerializedName("adgroup_name") + private String adgroup_name; + /** + * 推广计划ID + */ + @SerializedName("campaign_id") + private Long campaign_id; + /** + * 推广计划名称 + */ + @SerializedName("campaign_name") + private String campaign_name; + /** + * 代理ID + */ + @SerializedName("agency_id") + private String agency_id; + /** + * 代理名称 + */ + @SerializedName("agency_name") + private String agency_name; + /** + * 销售线索信息 + */ + @SerializedName("leads_info") + private List leads_info; +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLeadFilter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLeadFilter.java new file mode 100644 index 0000000000..3923025336 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLeadFilter.java @@ -0,0 +1,32 @@ +package me.chanjar.weixin.mp.bean.marketing; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author 007 + */ +@Data +public class WxMpAdLeadFilter implements Serializable { + private static final long serialVersionUID = -1469998986497327439L; + private String field; + private String operator; + private List values; + + public JsonObject toJsonObject() { + JsonObject json = new JsonObject(); + json.addProperty("field", field); + json.addProperty("operator", operator); + if (values != null) { + JsonArray vs = new JsonArray(); + for (String value : values) { + vs.add(value); + } + } + return json; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLeadInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLeadInfo.java new file mode 100644 index 0000000000..859a0dca5e --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLeadInfo.java @@ -0,0 +1,18 @@ +package me.chanjar.weixin.mp.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author 007 + */ +@Data +public class WxMpAdLeadInfo implements Serializable { + private static final long serialVersionUID = -6462312242780350479L; + @SerializedName("key") + private String key; + @SerializedName("value") + private String value; +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLeadPageInfo.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLeadPageInfo.java new file mode 100644 index 0000000000..296a3fef82 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLeadPageInfo.java @@ -0,0 +1,23 @@ +package me.chanjar.weixin.mp.bean.marketing; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author 007 + */ +@Data +public class WxMpAdLeadPageInfo implements Serializable { + private static final long serialVersionUID = -896765006445604780L; + @SerializedName("page") + private Integer page; + @SerializedName("page_size") + private Integer pageSize; + @SerializedName("total_page") + private Integer totalPage; + @SerializedName("total_number") + private Integer totalNumber; + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLeadResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLeadResult.java new file mode 100644 index 0000000000..61805018b0 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpAdLeadResult.java @@ -0,0 +1,32 @@ +package me.chanjar.weixin.mp.bean.marketing; + +import com.google.gson.JsonParser; +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +/** + * @author 007 + */ +@Data +public class WxMpAdLeadResult implements Serializable { + private static final long serialVersionUID = -1526796632563660821L; + protected static final JsonParser JSON_PARSER = new JsonParser(); + + @SerializedName("page_info") + private WxMpAdLeadPageInfo pageInfo; + @SerializedName("list") + private List adLeads; + + public static WxMpAdLeadResult fromJson(String json) { + + return WxMpGsonBuilder.create().fromJson( + JSON_PARSER.parse(json).getAsJsonObject().get("data"), + new TypeToken() { + }.getType()); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpUserAction.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpUserAction.java new file mode 100644 index 0000000000..69fced907a --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpUserAction.java @@ -0,0 +1,39 @@ +package me.chanjar.weixin.mp.bean.marketing; + +import com.google.gson.JsonObject; +import lombok.Data; + +import java.io.Serializable; + +/** + * @author 007 + */ + +@Data +public class WxMpUserAction implements Serializable { + private static final long serialVersionUID = 7042393762652152209L; + private Long userActionSetId; + private String url; + private Boolean actionTime; + private String actionType; + private String clickId; + private Integer actionParam; + + public JsonObject toJsonObject() { + JsonObject json = new JsonObject(); + json.addProperty("user_action_set_id", this.userActionSetId); + json.addProperty("url", this.url); + json.addProperty("action_time", this.actionTime); + if (this.clickId != null) { + JsonObject traceJson = new JsonObject(); + traceJson.addProperty("click_id", this.clickId); + json.add("trace", traceJson); + } + if (this.actionParam != null) { + JsonObject actionParamJson = new JsonObject(); + actionParamJson.addProperty("value", actionParam); + json.add("action_param", actionParamJson); + } + return json; + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpUserActionSet.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpUserActionSet.java new file mode 100644 index 0000000000..84b0f4bba0 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/marketing/WxMpUserActionSet.java @@ -0,0 +1,56 @@ +package me.chanjar.weixin.mp.bean.marketing; + +import com.google.gson.JsonParser; +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +/** + * @author 007 + */ + +@Data +public class WxMpUserActionSet implements Serializable { + private static final long serialVersionUID = 1979861770645159905L; + protected static final JsonParser JSON_PARSER = new JsonParser(); + + /** + * user_action_set_id + * 用户行为源名称 + */ + @SerializedName("user_action_set_id") + private Long userActionSetId; + + /** + * title. + * 用户行为源描述 + */ + @SerializedName("description") + private String description; + + /** + * activate_status. + * 数据接入状态, true 表示已接入, false 表示未接入 + */ + @SerializedName("activate_status") + private Boolean activate_status; + + /** + * created_time. + * 创建时间 + */ + @SerializedName("created_time") + private String createdTime; + + public static List fromJson(String json) { + return WxMpGsonBuilder.create().fromJson( + JSON_PARSER.parse(json).getAsJsonObject().get("data").getAsJsonObject().get("list"), + new TypeToken>() { + }.getType()); + } + +} diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/result/WxMpAdLeadResultTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/result/WxMpAdLeadResultTest.java new file mode 100644 index 0000000000..faf354f11d --- /dev/null +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/result/WxMpAdLeadResultTest.java @@ -0,0 +1,75 @@ +package me.chanjar.weixin.mp.bean.result; + +import me.chanjar.weixin.mp.bean.marketing.WxMpAdLeadResult; +import org.testng.annotations.Test; + +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +/** + * @author 007 + */ +public class WxMpAdLeadResultTest { + @Test + public void testFromJson() throws Exception { + String json = "{\n" + + "\t\"data\": {\n" + + "\t\t\"page_info\": {\n" + + "\t\t\t\"total_number\": 39,\n" + + "\t\t\t\"page\": 1,\n" + + "\t\t\t\"page_size\": 100,\n" + + "\t\t\t\"total_page\": 1\n" + + "\t\t},\n" + + "\t\t\"list\": [{\n" + + "\t\t\t\"click_id\": \"\",\n" + + "\t\t\t\"adgroup_name\": \"\",\n" + + "\t\t\t\"campaign_id\": 1800000001,\n" + + "\t\t\t\"leads_info\": [{\n" + + "\t\t\t\t\"value\": \"13800138000\",\n" + + "\t\t\t\t\"key\": \"电话号码\"\n" + + "\t\t\t}, {\n" + + "\t\t\t\t\"value\": \"2019-03-14 00:54:34\",\n" + + "\t\t\t\t\"key\": \"提交时间\"\n" + + "\t\t\t}, {\n" + + "\t\t\t\t\"value\": \"123\",\n" + + "\t\t\t\t\"key\": \"自定义问题\"\n" + + "\t\t\t}],\n" + + "\t\t\t\"agency_name\": \"\",\n" + + "\t\t\t\"agency_id\": \"\",\n" + + "\t\t\t\"campaign_name\": \"\",\n" + + "\t\t\t\"adgroup_id\": 1800000002\n" + + "\t\t}, {\n" + + "\t\t\t\"click_id\": \"\",\n" + + "\t\t\t\"adgroup_name\": \"\",\n" + + "\t\t\t\"campaign_id\": 1800000001,\n" + + "\t\t\t\"leads_info\": [{\n" + + "\t\t\t\t\"value\": \"13800138001\",\n" + + "\t\t\t\t\"key\": \"电话号码\"\n" + + "\t\t\t}, {\n" + + "\t\t\t\t\"value\": \"2019-03-14 02:10:39\",\n" + + "\t\t\t\t\"key\": \"提交时间\"\n" + + "\t\t\t}, {\n" + + "\t\t\t\t\"value\": \"321\",\n" + + "\t\t\t\t\"key\": \"自定义问题\"\n" + + "\t\t\t}],\n" + + "\t\t\t\"agency_name\": \"\",\n" + + "\t\t\t\"agency_id\": \"\",\n" + + "\t\t\t\"campaign_name\": \"\",\n" + + "\t\t\t\"adgroup_id\": 1800000002\n" + + "\t\t}]\n" + + "\t},\n" + + "\t\"errcode\": 0,\n" + + "\t\"errmsg\": \"\"\n" + + "}"; + + WxMpAdLeadResult adLeadResult = WxMpAdLeadResult.fromJson(json); + + assertNotNull(adLeadResult); + assertNotNull(adLeadResult.getPageInfo()); + assertNotNull(adLeadResult.getAdLeads()); + assertTrue(adLeadResult.getAdLeads().size() > 0); + + System.out.println(adLeadResult); + } + +} From 89521cdb1eecbdd326e27035433a795456b434c9 Mon Sep 17 00:00:00 2001 From: yuansc Date: Fri, 15 Mar 2019 17:10:30 +0800 Subject: [PATCH 39/81] =?UTF-8?q?#977=20WxMaKefuMessage=E5=AD=90=E7=B1=BB?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0Serializable=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wx/miniapp/bean/WxMaKefuMessage.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java index ee11476878..73ca435d62 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java @@ -41,20 +41,26 @@ public class WxMaKefuMessage implements Serializable { @Data @AllArgsConstructor - public static class KfText { + public static class KfText implements Serializable { + private static final long serialVersionUID = 151122958720941270L; + private String content; } @Data @AllArgsConstructor - public static class KfImage { + public static class KfImage implements Serializable { + private static final long serialVersionUID = -5409342945117300782L; + @SerializedName("media_id") private String mediaId; } @Data @Builder - public static class KfLink { + public static class KfLink implements Serializable { + private static final long serialVersionUID = -6728776817556127413L; + private String title; private String description; private String url; @@ -65,7 +71,9 @@ public static class KfLink { @Data @Builder - public static class KfMaPage { + public static class KfMaPage implements Serializable { + private static final long serialVersionUID = -5633492281871634466L; + private String title; @SerializedName("pagepath") From f6285f049ec6fe84bb8c8a1c13f9e5e40a7f5154 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 17 Mar 2019 14:09:42 +0800 Subject: [PATCH 40/81] =?UTF-8?q?#974=20=E5=BE=AE=E4=BF=A1=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E8=AE=BE=E7=BD=AE=E4=BB=A3=E7=90=86=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E8=AF=B7=E6=B1=82=E4=BB=A3=E7=A0=81=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/WxPayServiceApacheHttpImpl.java | 4 ++++ .../service/impl/WxPayServiceJoddHttpImpl.java | 13 ++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java index df9a82fbe2..5d6f3be4a8 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java @@ -100,6 +100,10 @@ private HttpClientBuilder createHttpClientBuilder(boolean useKey) throws WxPayEx } if (StringUtils.isNotBlank(this.getConfig().getHttpProxyHost()) && this.getConfig().getHttpProxyPort() > 0) { + if (StringUtils.isEmpty(this.getConfig().getHttpProxyUsername())) { + this.getConfig().setHttpProxyUsername("whatever"); + } + // 使用代理服务器 需要用户认证的代理服务器 CredentialsProvider provider = new BasicCredentialsProvider(); provider.setCredentials(new AuthScope(this.getConfig().getHttpProxyHost(), this.getConfig().getHttpProxyPort()), diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceJoddHttpImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceJoddHttpImpl.java index a598809938..72f2539fb1 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceJoddHttpImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceJoddHttpImpl.java @@ -1,10 +1,5 @@ package com.github.binarywang.wxpay.service.impl; -import java.nio.charset.StandardCharsets; -import javax.net.ssl.SSLContext; - -import org.apache.commons.lang3.StringUtils; - import com.github.binarywang.wxpay.bean.WxPayApiData; import com.github.binarywang.wxpay.exception.WxPayException; import jodd.http.HttpConnectionProvider; @@ -15,6 +10,10 @@ import jodd.http.net.SSLSocketHttpConnectionProvider; import jodd.http.net.SocketHttpConnectionProvider; import jodd.util.Base64; +import org.apache.commons.lang3.StringUtils; + +import javax.net.ssl.SSLContext; +import java.nio.charset.StandardCharsets; /** * 微信支付请求实现类,jodd-http实现. @@ -76,6 +75,10 @@ private HttpRequest buildHttpRequest(String url, String requestStr, boolean useK } if (StringUtils.isNotBlank(this.getConfig().getHttpProxyHost()) && this.getConfig().getHttpProxyPort() > 0) { + if (StringUtils.isEmpty(this.getConfig().getHttpProxyUsername())) { + this.getConfig().setHttpProxyUsername("whatever"); + } + ProxyInfo httpProxy = new ProxyInfo(ProxyType.HTTP, this.getConfig().getHttpProxyHost(), this.getConfig().getHttpProxyPort(), this.getConfig().getHttpProxyUsername(), this.getConfig().getHttpProxyPassword()); HttpConnectionProvider provider = request.connectionProvider(); From 53a4da00cd142c1dd922b240a316d6fac5fa3d05 Mon Sep 17 00:00:00 2001 From: liaochuntao Date: Fri, 22 Mar 2019 21:55:37 +0800 Subject: [PATCH 41/81] =?UTF-8?q?#959=20=E5=85=AC=E4=BC=97=E5=8F=B7?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E9=85=8D=E7=BD=AE=E5=8A=A0=E5=85=A5=E5=A4=9A?= =?UTF-8?q?=E5=85=AC=E4=BC=97=E5=8F=B7=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .vscode/settings.json | 3 +++ .../me/chanjar/weixin/mp/api/WxMpService.java | 15 +++++++++++ .../mp/api/impl/BaseWxMpServiceImpl.java | 25 +++++++++++++++++++ .../mp/util/WxMpConfigStorageHolder.java | 20 +++++++++++++++ 5 files changed, 64 insertions(+) create mode 100644 .vscode/settings.json create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/WxMpConfigStorageHolder.java diff --git a/.gitignore b/.gitignore index d97b22b768..a231e6c659 100644 --- a/.gitignore +++ b/.gitignore @@ -42,6 +42,7 @@ Icon .Spotlight-V100 .TemporaryItems .Trashes +.vscode .VolumeIcon.icns .AppleDB .AppleDesktop diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000..c5f3f6b9c7 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "java.configuration.updateBuildConfiguration": "interactive" +} \ No newline at end of file diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java index 991e1de15a..307ab0dc72 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java @@ -12,6 +12,8 @@ import me.chanjar.weixin.mp.bean.result.WxMpUser; import me.chanjar.weixin.mp.enums.TicketType; +import java.util.HashMap; + /** * 微信公众号API的Service. * @@ -306,6 +308,19 @@ public interface WxMpService { */ void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider); + /** + * 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String label} 值 + * @return + */ + void setMultiWxMpConfigStorage(HashMap configStorages); + + /** + * 进行相应的 WxApp 切换 + * @param label + * @return + */ + boolean switchover(String label); + /** * 返回客服接口方法实现类,以方便调用其各个接口. * diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java index 2db223c337..a5f163b45f 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java @@ -1,9 +1,11 @@ package me.chanjar.weixin.mp.api.impl; import java.io.IOException; +import java.util.HashMap; import java.util.concurrent.locks.Lock; import me.chanjar.weixin.mp.api.*; +import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,6 +66,9 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH private WxMpWifiService wifiService = new WxMpWifiServiceImpl(this); private WxMpMarketingService marketingService = new WxMpMarketingServiceImpl(this); + private HashMap wxMpConfigStoragePool; + private boolean isMultiWxApp = false; + private int retrySleepMillis = 1000; private int maxRetryTimes = 5; @@ -334,6 +339,10 @@ public T executeInternal(RequestExecutor executor, String uri, E da @Override public WxMpConfigStorage getWxMpConfigStorage() { + if (isMultiWxApp) { + String label = WxMpConfigStorageHolder.get(); + return wxMpConfigStoragePool.getOrDefault(label, null); + } return this.wxMpConfigStorage; } @@ -343,6 +352,22 @@ public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { this.initHttp(); } + @Override + public void setMultiWxMpConfigStorage(HashMap configStorages) { + wxMpConfigStoragePool = configStorages; + isMultiWxApp = true; + this.initHttp(); + } + + @Override + public boolean switchover(String label) { + if (wxMpConfigStoragePool.containsKey(label)) { + WxMpConfigStorageHolder.set(label); + return true; + } + return false; + } + @Override public void setRetrySleepMillis(int retrySleepMillis) { this.retrySleepMillis = retrySleepMillis; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/WxMpConfigStorageHolder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/WxMpConfigStorageHolder.java new file mode 100644 index 0000000000..f73bc37ca2 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/WxMpConfigStorageHolder.java @@ -0,0 +1,20 @@ +package me.chanjar.weixin.mp.util; + + +/** + * @Author: yd + * @Date: 2019-03-20 22:06 + */ +public class WxMpConfigStorageHolder { + + private final static ThreadLocal WX_MP_CONFIG_STORAGE_CHOSE = new ThreadLocal<>(); + + public static String get() { + return WX_MP_CONFIG_STORAGE_CHOSE.get(); + } + + public static void set(String label) { + WX_MP_CONFIG_STORAGE_CHOSE.set(label); + } + +} From 4beeca276271e6e76be1b05af6204e3c28bde762 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 23 Mar 2019 18:57:26 +0800 Subject: [PATCH 42/81] =?UTF-8?q?#981=20WxMpMemberCardServiceImpl=E7=9A=84?= =?UTF-8?q?=E6=9E=84=E9=80=A0=E5=87=BD=E6=95=B0=E8=AE=BE=E4=B8=BApublic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java index 9bdc11b365..d0a1c347bc 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java @@ -51,7 +51,7 @@ public class WxMpMemberCardServiceImpl implements WxMpMemberCardService { private static final Gson GSON = WxMpGsonBuilder.create(); - WxMpMemberCardServiceImpl(WxMpService wxMpService) { + public WxMpMemberCardServiceImpl(WxMpService wxMpService) { this.wxMpService = wxMpService; } From 7eeceef2c1a42b5a851966283d6850f339b6c5f1 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 23 Mar 2019 19:01:58 +0800 Subject: [PATCH 43/81] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=83=A8=E5=88=86?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/mp/api/WxMpService.java | 3 +- .../mp/api/impl/BaseWxMpServiceImpl.java | 33 ++++++++----------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java index 307ab0dc72..01faeb8400 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java @@ -13,6 +13,7 @@ import me.chanjar.weixin.mp.enums.TicketType; import java.util.HashMap; +import java.util.Map; /** * 微信公众号API的Service. @@ -312,7 +313,7 @@ public interface WxMpService { * 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String label} 值 * @return */ - void setMultiWxMpConfigStorage(HashMap configStorages); + void setMultiWxMpConfigStorage(Map configStorages); /** * 进行相应的 WxApp 切换 diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java index a5f163b45f..1a313def50 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java @@ -1,15 +1,5 @@ package me.chanjar.weixin.mp.api.impl; -import java.io.IOException; -import java.util.HashMap; -import java.util.concurrent.locks.Lock; - -import me.chanjar.weixin.mp.api.*; -import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -22,17 +12,22 @@ import me.chanjar.weixin.common.util.DataUtils; import me.chanjar.weixin.common.util.RandomUtils; 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.http.URIUtil; +import me.chanjar.weixin.common.util.http.*; +import me.chanjar.weixin.mp.api.*; import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; import me.chanjar.weixin.mp.bean.result.WxMpCurrentAutoReplyInfo; import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; import me.chanjar.weixin.mp.bean.result.WxMpUser; import me.chanjar.weixin.mp.enums.TicketType; +import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Map; +import java.util.concurrent.locks.Lock; /** * 基础实现类. @@ -66,7 +61,7 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH private WxMpWifiService wifiService = new WxMpWifiServiceImpl(this); private WxMpMarketingService marketingService = new WxMpMarketingServiceImpl(this); - private HashMap wxMpConfigStoragePool; + private Map wxMpConfigStoragePool; private boolean isMultiWxApp = false; private int retrySleepMillis = 1000; @@ -340,9 +335,9 @@ public T executeInternal(RequestExecutor executor, String uri, E da @Override public WxMpConfigStorage getWxMpConfigStorage() { if (isMultiWxApp) { - String label = WxMpConfigStorageHolder.get(); - return wxMpConfigStoragePool.getOrDefault(label, null); + return wxMpConfigStoragePool.get(WxMpConfigStorageHolder.get()); } + return this.wxMpConfigStorage; } @@ -353,7 +348,7 @@ public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { } @Override - public void setMultiWxMpConfigStorage(HashMap configStorages) { + public void setMultiWxMpConfigStorage(Map configStorages) { wxMpConfigStoragePool = configStorages; isMultiWxApp = true; this.initHttp(); From 7b6f3bbdc21fda69e5d66459e32631bc73f69a81 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 23 Mar 2019 19:06:00 +0800 Subject: [PATCH 44/81] =?UTF-8?q?#973=20=E4=BF=AE=E5=A4=8D=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=95=86=E5=8F=91=E9=80=81=E5=BE=AE=E4=BF=A1=E7=BA=A2?= =?UTF-8?q?=E5=8C=85=E6=97=B6=E7=9A=84=E7=AD=BE=E5=90=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wxpay/bean/request/WxPaySendRedpackRequest.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java index efa04d17f2..977f363f6a 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.java @@ -1,11 +1,7 @@ package com.github.binarywang.wxpay.bean.request; import com.thoughtworks.xstream.annotations.XStreamAlias; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; +import lombok.*; /** * 发送红包请求参数对象. @@ -20,9 +16,11 @@ @AllArgsConstructor @XStreamAlias("xml") public class WxPaySendRedpackRequest extends BaseWxPayRequest { + private static final long serialVersionUID = -2035425086824987567L; + @Override protected String[] getIgnoredParamsForSign() { - return new String[]{"sign_type"}; + return new String[]{"sign_type", "sub_appid"}; } /** From d0de3f864d3dcc3a0532b68cc3a6d7cf340335ff Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 23 Mar 2019 19:23:50 +0800 Subject: [PATCH 45/81] =?UTF-8?q?=E5=8F=91=E5=B8=833.3.6.B=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- weixin-java-common/pom.xml | 2 +- weixin-java-cp/pom.xml | 2 +- weixin-java-miniapp/pom.xml | 2 +- weixin-java-mp/pom.xml | 2 +- weixin-java-open/pom.xml | 2 +- weixin-java-pay/pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index dafb86eab5..361ef0dbb1 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.github.binarywang wx-java - 3.3.5.B + 3.3.6.B pom WxJava - Weixin/Wechat Java SDK 微信开发Java SDK diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index ff0b835c91..85febb450b 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.5.B + 3.3.6.B weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 23f62a4220..db77108ae5 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.5.B + 3.3.6.B weixin-java-cp diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index 5d59d278b9..7a74c478c1 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.5.B + 3.3.6.B weixin-java-miniapp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index eec6fc3caa..10f2001b82 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.5.B + 3.3.6.B weixin-java-mp diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index 3bbc973835..611e3cf05c 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.5.B + 3.3.6.B weixin-java-open diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index cc39e438aa..db0d284c35 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ com.github.binarywang wx-java - 3.3.5.B + 3.3.6.B 4.0.0 From 28c03d71dbfdf05a3299e719a4773bea92369d03 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 23 Mar 2019 20:26:15 +0800 Subject: [PATCH 46/81] =?UTF-8?q?#960=20=E4=BF=AE=E5=A4=8DWxPayRefundNotif?= =?UTF-8?q?yResult=E7=9A=84successTime=E5=AD=97=E6=AE=B5=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../binarywang/wxpay/bean/notify/WxPayRefundNotifyResult.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResult.java index 513dbfa84e..ad56852824 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResult.java @@ -215,7 +215,8 @@ public String toString() { * 变量名:success_time * 是否必填:否 * 类型: String(20) - * 示例值:20160725152626 + * 示例值:2017-12-15 09:46:01 + * 资金退款至用户帐号的时间,格式2017-12-15 09:46:01 *
*/ @XStreamAlias("success_time") From 0937ac85b155703bc6414966dd390d9d8e9f1cb5 Mon Sep 17 00:00:00 2001 From: liaochuntao Date: Tue, 26 Mar 2019 22:09:49 +0800 Subject: [PATCH 47/81] =?UTF-8?q?#985=20=E4=BF=AE=E5=A4=8D=E5=A4=9AWxApp?= =?UTF-8?q?=E5=9C=BA=E6=99=AF=E4=B8=8BinitHttp=E6=96=B9=E6=B3=95=E6=89=A7?= =?UTF-8?q?=E8=A1=8C=E6=97=B6=E7=9A=84=E7=A9=BA=E6=8C=87=E9=92=88=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/mp/api/WxMpService.java | 23 +++++++- .../mp/api/impl/BaseWxMpServiceImpl.java | 55 +++++++++++++------ .../mp/api/impl/WxMpServiceOkHttpImpl.java | 2 + .../mp/util/WxMpConfigStorageHolder.java | 7 ++- .../mp/api/impl/WxMpMenuServiceImplTest.java | 47 ++++++++++++++++ .../weixin/mp/api/test/ApiTestModule.java | 11 +++- 6 files changed, 122 insertions(+), 23 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java index 01faeb8400..d23afc640e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java @@ -12,7 +12,6 @@ import me.chanjar.weixin.mp.bean.result.WxMpUser; import me.chanjar.weixin.mp.enums.TicketType; -import java.util.HashMap; import java.util.Map; /** @@ -309,12 +308,32 @@ public interface WxMpService { */ void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider); + /** + * {@link Map} 加入新的 {@link WxMpConfigStorage},适用于动态添加新的微信应用 + * @param configStorages + */ + void addWxMpConfigStorage(String label, WxMpConfigStorage configStorages); + + /** + * 从{@link Map} 移除 {@link String label} 所对应的 {@link WxMpConfigStorage},适用于动态移除的微信应用 + * @param label + */ + void removeWxMpConfigStorage(String label); + /** * 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String label} 值 - * @return + * 随机采用一个{@link String lable}进行Http初始化操作 + * @param configStorages */ void setMultiWxMpConfigStorage(Map configStorages); + /** + * 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String label} 值 + * @param configStorages + * @param defaultInitLabel 设置一个{@link WxMpConfigStorage} 所对应的{@link String label}进行Http初始化 + */ + void setMultiWxMpConfigStorage(Map configStorages, String defaultInitLabel); + /** * 进行相应的 WxApp 切换 * @param label diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java index 1a313def50..59fcf7926f 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java @@ -1,5 +1,15 @@ package me.chanjar.weixin.mp.api.impl; +import java.io.IOException; +import java.util.HashMap; +import java.util.concurrent.locks.Lock; + +import me.chanjar.weixin.mp.api.*; +import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -13,21 +23,14 @@ import me.chanjar.weixin.common.util.RandomUtils; import me.chanjar.weixin.common.util.crypto.SHA1; import me.chanjar.weixin.common.util.http.*; -import me.chanjar.weixin.mp.api.*; import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; import me.chanjar.weixin.mp.bean.result.WxMpCurrentAutoReplyInfo; import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; import me.chanjar.weixin.mp.bean.result.WxMpUser; import me.chanjar.weixin.mp.enums.TicketType; -import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.io.IOException; import java.util.Map; -import java.util.concurrent.locks.Lock; /** * 基础实现类. @@ -40,7 +43,6 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH protected final Logger log = LoggerFactory.getLogger(this.getClass()); protected WxSessionManager sessionManager = new StandardSessionManager(); - protected WxMpConfigStorage wxMpConfigStorage; private WxMpKefuService kefuService = new WxMpKefuServiceImpl(this); private WxMpMaterialService materialService = new WxMpMaterialServiceImpl(this); private WxMpMenuService menuService = new WxMpMenuServiceImpl(this); @@ -62,7 +64,6 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH private WxMpMarketingService marketingService = new WxMpMarketingServiceImpl(this); private Map wxMpConfigStoragePool; - private boolean isMultiWxApp = false; private int retrySleepMillis = 1000; private int maxRetryTimes = 5; @@ -334,26 +335,46 @@ public T executeInternal(RequestExecutor executor, String uri, E da @Override public WxMpConfigStorage getWxMpConfigStorage() { - if (isMultiWxApp) { - return wxMpConfigStoragePool.get(WxMpConfigStorageHolder.get()); - } - - return this.wxMpConfigStorage; + return wxMpConfigStoragePool.get(WxMpConfigStorageHolder.get()); } @Override public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { - this.wxMpConfigStorage = wxConfigProvider; - this.initHttp(); + Map map = new HashMap<>(1); + map.put(WxMpConfigStorageHolder.get(), wxConfigProvider); + setMultiWxMpConfigStorage(map, WxMpConfigStorageHolder.get()); } @Override public void setMultiWxMpConfigStorage(Map configStorages) { + String randomKey = configStorages.keySet().iterator().next(); + setMultiWxMpConfigStorage(configStorages, randomKey); + } + + @Override + public void setMultiWxMpConfigStorage(Map configStorages, String defaultInitLabel) { wxMpConfigStoragePool = configStorages; - isMultiWxApp = true; + WxMpConfigStorageHolder.set(defaultInitLabel); this.initHttp(); } + @Override + public void addWxMpConfigStorage(String label, WxMpConfigStorage configStorages) { + synchronized (this) { + if (wxMpConfigStoragePool.containsKey(label)) { + throw new RuntimeException("该label已存在,请重新设置一个label"); + } + wxMpConfigStoragePool.put(label, configStorages); + } + } + + @Override + public void removeWxMpConfigStorage(String label) { + synchronized (this) { + wxMpConfigStoragePool.remove(label); + } + } + @Override public boolean switchover(String label) { if (wxMpConfigStoragePool.containsKey(label)) { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java index e88fad1425..89771250ef 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceOkHttpImpl.java @@ -6,6 +6,7 @@ import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.HttpType; import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo; +import me.chanjar.weixin.mp.api.WxMpConfigStorage; import me.chanjar.weixin.mp.api.WxMpService; import okhttp3.*; @@ -66,6 +67,7 @@ public String getAccessToken(boolean forceRefresh) throws WxErrorException { @Override public void initHttp() { + WxMpConfigStorage wxMpConfigStorage = getWxMpConfigStorage(); //设置代理 if (wxMpConfigStorage.getHttpProxyHost() != null && wxMpConfigStorage.getHttpProxyPort() > 0) { httpProxy = OkHttpProxyInfo.httpProxy(wxMpConfigStorage.getHttpProxyHost(), diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/WxMpConfigStorageHolder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/WxMpConfigStorageHolder.java index f73bc37ca2..af2f9226db 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/WxMpConfigStorageHolder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/WxMpConfigStorageHolder.java @@ -7,7 +7,12 @@ */ public class WxMpConfigStorageHolder { - private final static ThreadLocal WX_MP_CONFIG_STORAGE_CHOSE = new ThreadLocal<>(); + private final static ThreadLocal WX_MP_CONFIG_STORAGE_CHOSE = new ThreadLocal() { + @Override + protected String initialValue() { + return "default"; + } + }; public static String get() { return WX_MP_CONFIG_STORAGE_CHOSE.get(); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java index c25c946df4..8afb9d095c 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java @@ -85,6 +85,53 @@ public void testCreateConditionalMenu() throws WxErrorException { "}"; this.menuId = this.wxService.getMenuService().menuCreate(json); + if (this.wxService.switchover("test-1")) { + this.menuId = this.wxService.getMenuService().menuCreate(json); + } + System.out.println(this.menuId); + } + + @Test + public void testMultiCreateConditionalMenu() throws WxErrorException { + String json = "{\n" + + " \"button\":[\n" + + " { \n" + + " \"type\":\"click\",\n" + + " \"name\":\"今日歌曲\",\n" + + " \"key\":\"V1001_TODAY_MUSIC\" \n" + + " },\n" + + " { \n" + + " \"name\":\"菜单\",\n" + + " \"sub_button\":[\n" + + " { \n" + + " \"type\":\"view\",\n" + + " \"name\":\"搜索\",\n" + + " \"url\":\"http://www.soso.com/\"\n" + + " },\n" + + " {\n" + + " \"type\":\"view\",\n" + + " \"name\":\"视频\",\n" + + " \"url\":\"http://v.qq.com/\"\n" + + " },\n" + + " {\n" + + " \"type\":\"click\",\n" + + " \"name\":\"赞一下我们\",\n" + + " \"key\":\"V1001_GOOD\"\n" + + " }]\n" + + " }],\n" + + "\"matchrule\":{\n" + + " \"tag_id\":\"2\",\n" + + " \"sex\":\"1\",\n" + + " \"country\":\"中国\",\n" + + " \"province\":\"广东\",\n" + + " \"city\":\"广州\",\n" + + " \"client_platform_type\":\"2\",\n" + + " \"language\":\"zh_CN\"\n" + + " }\n" + + "}"; + if (this.wxService.switchover("test-1")) { + this.menuId = this.wxService.getMenuService().menuCreate(json); + } System.out.println(this.menuId); } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java index 98173f7d35..8d6a0d03b4 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java @@ -2,6 +2,8 @@ import java.io.IOException; import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.locks.ReentrantLock; import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpClientImpl; @@ -29,11 +31,14 @@ public void configure(Binder binder) { TestConfigStorage config = this.fromXml(TestConfigStorage.class, inputStream); config.setAccessTokenLock(new ReentrantLock()); - WxMpService wxService = new WxMpServiceHttpClientImpl(); - wxService.setWxMpConfigStorage(config); + WxMpService wxMpServiceMulti = new WxMpServiceHttpClientImpl(); + + // TODO 多WxAppId + wxMpServiceMulti.setWxMpConfigStorage(config); + wxMpServiceMulti.addWxMpConfigStorage("test-1", config); - binder.bind(WxMpService.class).toInstance(wxService); binder.bind(WxMpConfigStorage.class).toInstance(config); + binder.bind(WxMpService.class).toInstance(wxMpServiceMulti); } catch (IOException e) { this.log.error(e.getMessage(), e); } From d17bb257f0a86cb83356bb78a5595231633dcdea Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Fri, 29 Mar 2019 21:17:22 +0800 Subject: [PATCH 48/81] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/mp/bean/card/GiftCardCreateRequest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GiftCardCreateRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GiftCardCreateRequest.java index 8791b70a9d..5271763f8e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GiftCardCreateRequest.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GiftCardCreateRequest.java @@ -2,6 +2,7 @@ import com.google.gson.annotations.SerializedName; import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; @@ -12,7 +13,10 @@ * @Date 2018/12/29 */ @Data +@EqualsAndHashCode(callSuper = true) public class GiftCardCreateRequest extends CardCreateRequest implements Serializable { + private static final long serialVersionUID = 1283655452584811858L; + @SerializedName("card_type") private String cardType = "GIFT"; From fb6efe9e0b5fbe97653ee06df494a314f1462bda Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Fri, 29 Mar 2019 21:28:23 +0800 Subject: [PATCH 49/81] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=A4=9A=E5=85=AC?= =?UTF-8?q?=E4=BC=97=E5=8F=B7=E6=94=AF=E6=8C=81=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/mp/api/WxMpService.java | 44 +++++++----- .../mp/api/impl/BaseWxMpServiceImpl.java | 70 +++++++++++-------- .../mp/api/impl/BaseWxMpServiceImplTest.java | 40 +++++++++++ .../mp/api/impl/WxMpMenuServiceImplTest.java | 17 ++--- .../weixin/mp/api/test/ApiTestModule.java | 12 ++-- 5 files changed, 116 insertions(+), 67 deletions(-) create mode 100644 weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImplTest.java diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java index d23afc640e..4ccfe30a14 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java @@ -5,6 +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.mp.api.impl.BaseWxMpServiceImpl; import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; import me.chanjar.weixin.mp.bean.result.WxMpCurrentAutoReplyInfo; import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; @@ -304,42 +305,49 @@ public interface WxMpService { WxMpConfigStorage getWxMpConfigStorage(); /** - * 注入 {@link WxMpConfigStorage} 的实现. + * 设置 {@link WxMpConfigStorage} 的实现. 兼容老版本 */ void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider); /** - * {@link Map} 加入新的 {@link WxMpConfigStorage},适用于动态添加新的微信应用 - * @param configStorages + * {@link Map} 加入新的 {@link WxMpConfigStorage},适用于动态添加新的微信公众号配置 + * @param configStorage 新的微信配置 */ - void addWxMpConfigStorage(String label, WxMpConfigStorage configStorages); + void addConfigStorage(String mpId, WxMpConfigStorage configStorage); /** - * 从{@link Map} 移除 {@link String label} 所对应的 {@link WxMpConfigStorage},适用于动态移除的微信应用 - * @param label + * 从{@link Map} 移除 {@link String mpId} 所对应的 {@link WxMpConfigStorage},适用于动态移除微信公众号配置 + * @param mpId 对应公众号的标识 */ - void removeWxMpConfigStorage(String label); + void removeConfigStorage(String mpId); /** - * 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String label} 值 - * 随机采用一个{@link String lable}进行Http初始化操作 - * @param configStorages + * 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String mpId} 值 + * 随机采用一个{@link String mpId}进行Http初始化操作 + * @param configStorages WxMpConfigStorage map */ - void setMultiWxMpConfigStorage(Map configStorages); + void setMultiConfigStorages(Map configStorages); /** * 注入多个 {@link WxMpConfigStorage} 的实现. 并为每个 {@link WxMpConfigStorage} 赋予不同的 {@link String label} 值 - * @param configStorages - * @param defaultInitLabel 设置一个{@link WxMpConfigStorage} 所对应的{@link String label}进行Http初始化 + * @param configStorages WxMpConfigStorage map + * @param defaultMpId 设置一个{@link WxMpConfigStorage} 所对应的{@link String mpId}进行Http初始化 + */ + void setMultiConfigStorages(Map configStorages, String defaultMpId); + + /** + * 进行相应的公众号切换 + * @param mpId 公众号标识 + * @return 切换是否成功 */ - void setMultiWxMpConfigStorage(Map configStorages, String defaultInitLabel); + boolean switchover(String mpId); /** - * 进行相应的 WxApp 切换 - * @param label - * @return + * 进行相应的公众号切换 + * @param mpId 公众号标识 + * @return 切换成功,则返回当前对象,方便链式调用,否则抛出异常 */ - boolean switchover(String label); + WxMpService switchover1(String mpId); /** * 返回客服接口方法实现类,以方便调用其各个接口. diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java index 59fcf7926f..31b88f5f2e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java @@ -1,15 +1,7 @@ package me.chanjar.weixin.mp.api.impl; -import java.io.IOException; -import java.util.HashMap; -import java.util.concurrent.locks.Lock; - -import me.chanjar.weixin.mp.api.*; -import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Maps; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -23,14 +15,21 @@ import me.chanjar.weixin.common.util.RandomUtils; import me.chanjar.weixin.common.util.crypto.SHA1; import me.chanjar.weixin.common.util.http.*; +import me.chanjar.weixin.mp.api.*; import me.chanjar.weixin.mp.bean.WxMpSemanticQuery; import me.chanjar.weixin.mp.bean.result.WxMpCurrentAutoReplyInfo; import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken; import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; import me.chanjar.weixin.mp.bean.result.WxMpUser; import me.chanjar.weixin.mp.enums.TicketType; +import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import java.io.IOException; import java.util.Map; +import java.util.concurrent.locks.Lock; /** * 基础实现类. @@ -63,12 +62,11 @@ public abstract class BaseWxMpServiceImpl implements WxMpService, RequestH private WxMpWifiService wifiService = new WxMpWifiServiceImpl(this); private WxMpMarketingService marketingService = new WxMpMarketingServiceImpl(this); - private Map wxMpConfigStoragePool; + private Map configStorageMap; private int retrySleepMillis = 1000; private int maxRetryTimes = 5; - @Override public boolean checkSignature(String timestamp, String nonce, String signature) { try { @@ -335,52 +333,62 @@ public T executeInternal(RequestExecutor executor, String uri, E da @Override public WxMpConfigStorage getWxMpConfigStorage() { - return wxMpConfigStoragePool.get(WxMpConfigStorageHolder.get()); + return this.configStorageMap.get(WxMpConfigStorageHolder.get()); } @Override public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { - Map map = new HashMap<>(1); - map.put(WxMpConfigStorageHolder.get(), wxConfigProvider); - setMultiWxMpConfigStorage(map, WxMpConfigStorageHolder.get()); + final String defaultMpId = WxMpConfigStorageHolder.get(); + this.setMultiConfigStorages(ImmutableMap.of(defaultMpId, wxConfigProvider), defaultMpId); } @Override - public void setMultiWxMpConfigStorage(Map configStorages) { - String randomKey = configStorages.keySet().iterator().next(); - setMultiWxMpConfigStorage(configStorages, randomKey); + public void setMultiConfigStorages(Map configStorages) { + this.setMultiConfigStorages(configStorages, configStorages.keySet().iterator().next()); } @Override - public void setMultiWxMpConfigStorage(Map configStorages, String defaultInitLabel) { - wxMpConfigStoragePool = configStorages; - WxMpConfigStorageHolder.set(defaultInitLabel); + public void setMultiConfigStorages(Map configStorages, String defaultMpId) { + this.configStorageMap = Maps.newHashMap(configStorages); + WxMpConfigStorageHolder.set(defaultMpId); this.initHttp(); } @Override - public void addWxMpConfigStorage(String label, WxMpConfigStorage configStorages) { + public void addConfigStorage(String mpId, WxMpConfigStorage configStorages) { synchronized (this) { - if (wxMpConfigStoragePool.containsKey(label)) { - throw new RuntimeException("该label已存在,请重新设置一个label"); + if (this.configStorageMap.containsKey(mpId)) { + throw new RuntimeException("该公众号标识已存在,请更换其他标识!"); } - wxMpConfigStoragePool.put(label, configStorages); + this.configStorageMap.put(mpId, configStorages); } } @Override - public void removeWxMpConfigStorage(String label) { + public void removeConfigStorage(String mpId) { synchronized (this) { - wxMpConfigStoragePool.remove(label); + this.configStorageMap.remove(mpId); } } @Override - public boolean switchover(String label) { - if (wxMpConfigStoragePool.containsKey(label)) { - WxMpConfigStorageHolder.set(label); + public WxMpService switchover1(String mpId) { + if (this.configStorageMap.containsKey(mpId)) { + WxMpConfigStorageHolder.set(mpId); + return this; + } + + throw new RuntimeException(String.format("无法找到对应【%s】的公众号配置信息,请核实!", mpId)); + } + + @Override + public boolean switchover(String mpId) { + if (this.configStorageMap.containsKey(mpId)) { + WxMpConfigStorageHolder.set(mpId); return true; } + + log.error("无法找到对应【{}】的公众号配置信息,请核实!", mpId); return false; } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImplTest.java new file mode 100644 index 0000000000..52dfbb9e15 --- /dev/null +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImplTest.java @@ -0,0 +1,40 @@ +package me.chanjar.weixin.mp.api.impl; + +import com.google.inject.Inject; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.test.ApiTestModule; +import me.chanjar.weixin.mp.util.WxMpConfigStorageHolder; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +/** + *
+ *  Created by BinaryWang on 2019/3/29.
+ * 
+ * + * @author Binary Wang + */ +@Test +@Guice(modules = ApiTestModule.class) +public class BaseWxMpServiceImplTest { + @Inject + private WxMpService wxService; + + @Test + public void testSwitchover() { + assertTrue(this.wxService.switchover("another")); + assertThat(WxMpConfigStorageHolder.get()).isEqualTo("another"); + assertFalse(this.wxService.switchover("whatever")); + } + + @Test + public void testSwitchover1() throws WxErrorException { + assertThat(this.wxService.switchover1("another").getAccessToken()).isNotEmpty(); + assertThat(WxMpConfigStorageHolder.get()).isEqualTo("another"); + } +} diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java index 8afb9d095c..45c5e8af99 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMenuServiceImplTest.java @@ -9,9 +9,11 @@ import me.chanjar.weixin.mp.api.test.ApiTestModule; import me.chanjar.weixin.mp.bean.menu.WxMpGetSelfMenuInfoResult; import me.chanjar.weixin.mp.bean.menu.WxMpMenu; -import org.testng.annotations.*; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.testng.Assert.assertNotNull; /** * 测试菜单 @@ -19,7 +21,7 @@ * @author chanjarster * @author Binary Wang */ -@Test(groups = "menuAPI") +@Test @Guice(modules = ApiTestModule.class) public class WxMpMenuServiceImplTest { @@ -85,9 +87,6 @@ public void testCreateConditionalMenu() throws WxErrorException { "}"; this.menuId = this.wxService.getMenuService().menuCreate(json); - if (this.wxService.switchover("test-1")) { - this.menuId = this.wxService.getMenuService().menuCreate(json); - } System.out.println(this.menuId); } @@ -129,9 +128,7 @@ public void testMultiCreateConditionalMenu() throws WxErrorException { " \"language\":\"zh_CN\"\n" + " }\n" + "}"; - if (this.wxService.switchover("test-1")) { - this.menuId = this.wxService.getMenuService().menuCreate(json); - } + this.menuId = this.wxService.getMenuService().menuCreate(json); System.out.println(this.menuId); } @@ -194,7 +191,7 @@ public void testMenuGet() throws WxErrorException { System.out.println(wxMenu.toJson()); } - @Test(dependsOnMethods = {"testMenuGet","testMenuCreate"}) + @Test(dependsOnMethods = {"testMenuGet", "testMenuCreate"}) public void testMenuDelete() throws WxErrorException { this.wxService.getMenuService().menuDelete(); } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java index 8d6a0d03b4..29c8d2e2b8 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java @@ -2,8 +2,6 @@ import java.io.IOException; import java.io.InputStream; -import java.util.HashMap; -import java.util.Map; import java.util.concurrent.locks.ReentrantLock; import me.chanjar.weixin.mp.api.impl.WxMpServiceHttpClientImpl; @@ -16,7 +14,6 @@ import me.chanjar.weixin.common.util.xml.XStreamInitializer; import me.chanjar.weixin.mp.api.WxMpConfigStorage; import me.chanjar.weixin.mp.api.WxMpService; -import me.chanjar.weixin.mp.api.impl.WxMpServiceOkHttpImpl; public class ApiTestModule implements Module { private final Logger log = LoggerFactory.getLogger(this.getClass()); @@ -31,14 +28,13 @@ public void configure(Binder binder) { TestConfigStorage config = this.fromXml(TestConfigStorage.class, inputStream); config.setAccessTokenLock(new ReentrantLock()); - WxMpService wxMpServiceMulti = new WxMpServiceHttpClientImpl(); + WxMpService mpService = new WxMpServiceHttpClientImpl(); - // TODO 多WxAppId - wxMpServiceMulti.setWxMpConfigStorage(config); - wxMpServiceMulti.addWxMpConfigStorage("test-1", config); + mpService.setWxMpConfigStorage(config); + mpService.addConfigStorage("another", config); binder.bind(WxMpConfigStorage.class).toInstance(config); - binder.bind(WxMpService.class).toInstance(wxMpServiceMulti); + binder.bind(WxMpService.class).toInstance(mpService); } catch (IOException e) { this.log.error(e.getMessage(), e); } From bfe89b9dddc289ef820bd42d9b53df14647d3142 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Fri, 29 Mar 2019 21:31:31 +0800 Subject: [PATCH 50/81] Upgrade org.eclipse.jetty:jetty-server to version 9.4.12.v20180830 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 361ef0dbb1..2ab6f67684 100644 --- a/pom.xml +++ b/pom.xml @@ -114,7 +114,7 @@ UTF-8 4.5 - 9.3.24.v20180605 + 9.4.12.v20180830 From c40c6c5797235b277b984f4a0d27941081e16e67 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Fri, 29 Mar 2019 21:50:36 +0800 Subject: [PATCH 51/81] =?UTF-8?q?#966=20=E4=BF=AE=E5=A4=8D=E5=BC=80?= =?UTF-8?q?=E6=94=BE=E5=B9=B3=E5=8F=B0=E7=A7=BB=E5=8A=A8=E7=AB=AF=E5=BF=AB?= =?UTF-8?q?=E9=80=9F=E6=8E=88=E6=9D=83=E9=93=BE=E6=8E=A5=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E5=AD=97=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/open/api/WxOpenComponentService.java | 2 +- .../weixin/open/api/impl/WxOpenComponentServiceImpl.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java index b9c7ff1064..4b2ddbc412 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenComponentService.java @@ -31,7 +31,7 @@ public interface WxOpenComponentService { /** * 手机端打开授权链接 */ - String COMPONENT_MOBILE_LOGIN_PAGE_URL = "https://mp.weixin.qq.com/safe/bindcomponent?action=bindcomponent&no_scan=1&auth_type=3&component_appid=%s&pre_auth_code=%s&redirect_uri=%s&auth_type=xxx&biz_appid=xxx$#wechat_redirect"; + String COMPONENT_MOBILE_LOGIN_PAGE_URL = "https://mp.weixin.qq.com/safe/bindcomponent?action=bindcomponent&no_scan=1&auth_type=3&component_appid=%s&pre_auth_code=%s&redirect_uri=%s&auth_type=xxx&biz_appid=xxx#wechat_redirect"; String CONNECT_OAUTH2_AUTHORIZE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s&component_appid=%s#wechat_redirect"; /** diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java index 213fb01995..319e12ffa2 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenComponentServiceImpl.java @@ -196,14 +196,17 @@ public String getPreAuthUrl(String redirectURI) throws WxErrorException { return getPreAuthUrl(redirectURI, null, null); } + @Override public String getPreAuthUrl(String redirectURI, String authType, String bizAppid) throws WxErrorException { return createPreAuthUrl(redirectURI, authType, bizAppid, false); } + @Override public String getMobilePreAuthUrl(String redirectURI) throws WxErrorException { return getMobilePreAuthUrl(redirectURI, null, null); } + @Override public String getMobilePreAuthUrl(String redirectURI, String authType, String bizAppid) throws WxErrorException { return createPreAuthUrl(redirectURI, authType, bizAppid, true); } From 7538b8ec72e7fe26d71c0d53f21b33d4447a1b9d Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 31 Mar 2019 16:07:46 +0800 Subject: [PATCH 52/81] =?UTF-8?q?=E6=8A=BD=E5=8F=96=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=9C=B0=E5=9D=80=E4=B8=BA=E5=B8=B8=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/cp/api/WxCpService.java | 7 +++++++ .../cp/api/impl/BaseWxCpServiceImpl.java | 20 +++++++++---------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java index 64756dfb58..c57f8e95db 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java @@ -16,6 +16,13 @@ * @author chanjaster */ public interface WxCpService { + String GET_JSAPI_TICKET = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket"; + String MESSAGE_SEND = "https://qyapi.weixin.qq.com/cgi-bin/message/send"; + String GET_CALLBACK_IP = "https://qyapi.weixin.qq.com/cgi-bin/getcallbackip"; + String BATCH_REPLACE_PARTY = "https://qyapi.weixin.qq.com/cgi-bin/batch/replaceparty"; + String BATCH_REPLACE_USER = "https://qyapi.weixin.qq.com/cgi-bin/batch/replaceuser"; + String BATCH_GET_RESULT = "https://qyapi.weixin.qq.com/cgi-bin/batch/getresult?jobid="; + /** *
    * 验证推送过来的消息的正确性
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
index e985e21141..b8bcf666cf 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
@@ -36,6 +36,9 @@
 import me.chanjar.weixin.cp.bean.WxCpMessageSendResult;
 import me.chanjar.weixin.cp.config.WxCpConfigStorage;
 
+/**
+ * @author chanjarster
+ */
 public abstract class BaseWxCpServiceImpl implements WxCpService, RequestHttp {
   protected final Logger log = LoggerFactory.getLogger(this.getClass());
 
@@ -99,8 +102,7 @@ public String getJsapiTicket(boolean forceRefresh) throws WxErrorException {
     if (this.configStorage.isJsapiTicketExpired()) {
       synchronized (this.globalJsapiTicketRefreshLock) {
         if (this.configStorage.isJsapiTicketExpired()) {
-          String url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket";
-          String responseContent = execute(SimpleGetRequestExecutor.create(this), url, null);
+          String responseContent = execute(SimpleGetRequestExecutor.create(this), WxCpService.GET_JSAPI_TICKET, null);
           JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
           JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
           String jsapiTicket = tmpJsonObject.get("ticket").getAsString();
@@ -138,19 +140,17 @@ public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException
 
   @Override
   public WxCpMessageSendResult messageSend(WxCpMessage message) throws WxErrorException {
-    String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send";
     Integer agentId = message.getAgentId();
     if (null == agentId) {
       message.setAgentId(this.getWxCpConfigStorage().getAgentId());
     }
 
-    return WxCpMessageSendResult.fromJson(this.post(url, message.toJson()));
+    return WxCpMessageSendResult.fromJson(this.post(WxCpService.MESSAGE_SEND, message.toJson()));
   }
 
   @Override
   public String[] getCallbackIp() throws WxErrorException {
-    String url = "https://qyapi.weixin.qq.com/cgi-bin/getcallbackip";
-    String responseContent = get(url, null);
+    String responseContent = get(WxCpService.GET_CALLBACK_IP, null);
     JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
     JsonArray jsonArray = tmpJsonElement.getAsJsonObject().get("ip_list").getAsJsonArray();
     String[] ips = new String[jsonArray.size()];
@@ -292,23 +292,21 @@ public WxSessionManager getSessionManager() {
 
   @Override
   public String replaceParty(String mediaId) throws WxErrorException {
-    String url = "https://qyapi.weixin.qq.com/cgi-bin/batch/replaceparty";
     JsonObject jsonObject = new JsonObject();
     jsonObject.addProperty("media_id", mediaId);
-    return post(url, jsonObject.toString());
+    return post(WxCpService.BATCH_REPLACE_PARTY, jsonObject.toString());
   }
 
   @Override
   public String replaceUser(String mediaId) throws WxErrorException {
-    String url = "https://qyapi.weixin.qq.com/cgi-bin/batch/replaceuser";
     JsonObject jsonObject = new JsonObject();
     jsonObject.addProperty("media_id", mediaId);
-    return post(url, jsonObject.toString());
+    return post(WxCpService.BATCH_REPLACE_USER, jsonObject.toString());
   }
 
   @Override
   public String getTaskResult(String joinId) throws WxErrorException {
-    String url = "https://qyapi.weixin.qq.com/cgi-bin/batch/getresult?jobid=" + joinId;
+    String url = WxCpService.BATCH_GET_RESULT + joinId;
     return get(url, null);
   }
 

From a8933c5123863b4170120812464fe624a67ee99e Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sun, 31 Mar 2019 16:59:47 +0800
Subject: [PATCH 53/81] =?UTF-8?q?#901=20=E4=BC=81=E4=B8=9A=E5=BE=AE?=
 =?UTF-8?q?=E4=BF=A1=E5=A2=9E=E5=8A=A0=E8=8E=B7=E5=8F=96=E7=94=A8=E4=BA=8E?=
 =?UTF-8?q?=E8=AE=A1=E7=AE=97agentConfig=E7=AD=BE=E5=90=8D=E7=9A=84?=
 =?UTF-8?q?=E5=BA=94=E7=94=A8jsapi=5Fticket=E7=9A=84=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../me/chanjar/weixin/cp/api/WxCpService.java | 28 ++++++++
 .../cp/api/impl/BaseWxCpServiceImpl.java      | 67 ++++++++++++-------
 .../weixin/cp/config/WxCpConfigStorage.java   | 16 ++++-
 .../cp/config/WxCpInMemoryConfigStorage.java  | 29 +++++++-
 .../cp/config/WxCpJedisConfigStorage.java     | 50 +++++++++++---
 .../cp/api/impl/BaseWxCpServiceImplTest.java  | 31 +++++++++
 6 files changed, 185 insertions(+), 36 deletions(-)
 create mode 100644 weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImplTest.java

diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
index c57f8e95db..4cff71e620 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java
@@ -17,6 +17,7 @@
  */
 public interface WxCpService {
   String GET_JSAPI_TICKET = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket";
+  String GET_AGENT_CONFIG_TICKET = "https://qyapi.weixin.qq.com/cgi-bin/ticket/get?&type=agent_config";
   String MESSAGE_SEND = "https://qyapi.weixin.qq.com/cgi-bin/message/send";
   String GET_CALLBACK_IP = "https://qyapi.weixin.qq.com/cgi-bin/getcallbackip";
   String BATCH_REPLACE_PARTY = "https://qyapi.weixin.qq.com/cgi-bin/batch/replaceparty";
@@ -75,6 +76,33 @@ public interface WxCpService {
    */
   String getJsapiTicket(boolean forceRefresh) throws WxErrorException;
 
+  /**
+   * 获得jsapi_ticket,不强制刷新jsapi_ticket
+   * 应用的jsapi_ticket用于计算agentConfig(参见“通过agentConfig注入应用的权限”)的签名,签名计算方法与上述介绍的config的签名算法完全相同,但需要注意以下区别:
+   *
+   * 签名的jsapi_ticket必须使用以下接口获取。且必须用wx.agentConfig中的agentid对应的应用secret去获取access_token。
+   * 签名用的noncestr和timestamp必须与wx.agentConfig中的nonceStr和timestamp相同。
+   * @see #getJsapiTicket(boolean)
+   */
+  String getAgentJsapiTicket() throws WxErrorException;
+
+  /**
+   * 
+   * 获取应用的jsapi_ticket
+   * 应用的jsapi_ticket用于计算agentConfig(参见“通过agentConfig注入应用的权限”)的签名,签名计算方法与上述介绍的config的签名算法完全相同,但需要注意以下区别:
+   *
+   * 签名的jsapi_ticket必须使用以下接口获取。且必须用wx.agentConfig中的agentid对应的应用secret去获取access_token。
+   * 签名用的noncestr和timestamp必须与wx.agentConfig中的nonceStr和timestamp相同。
+   *
+   * 获得时会检查jsapiToken是否过期,如果过期了,那么就刷新一下,否则就什么都不干
+   *
+   * 详情请见:https://work.weixin.qq.com/api/doc#10029/%E8%8E%B7%E5%8F%96%E5%BA%94%E7%94%A8%E7%9A%84jsapi_ticket
+   * 
+ * + * @param forceRefresh 强制刷新 + */ + String getAgentJsapiTicket(boolean forceRefresh) throws WxErrorException; + /** *
    * 创建调用jsapi时所需要的签名
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
index b8bcf666cf..e418982e88 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
@@ -1,11 +1,5 @@
 package me.chanjar.weixin.cp.api.impl;
 
-import java.io.File;
-import java.io.IOException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
@@ -23,18 +17,15 @@
 import me.chanjar.weixin.common.util.http.RequestHttp;
 import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
 import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
-import me.chanjar.weixin.cp.api.WxCpAgentService;
-import me.chanjar.weixin.cp.api.WxCpChatService;
-import me.chanjar.weixin.cp.api.WxCpDepartmentService;
-import me.chanjar.weixin.cp.api.WxCpMediaService;
-import me.chanjar.weixin.cp.api.WxCpMenuService;
-import me.chanjar.weixin.cp.api.WxCpOAuth2Service;
-import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.api.WxCpTagService;
-import me.chanjar.weixin.cp.api.WxCpUserService;
+import me.chanjar.weixin.cp.api.*;
 import me.chanjar.weixin.cp.bean.WxCpMessage;
 import me.chanjar.weixin.cp.bean.WxCpMessageSendResult;
 import me.chanjar.weixin.cp.config.WxCpConfigStorage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.io.IOException;
 
 /**
  * @author chanjarster
@@ -61,14 +52,19 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH
    */
   protected final Object globalJsapiTicketRefreshLock = new Object();
 
+  /**
+   * 全局的是否正在刷新agent的jsapi_ticket的锁
+   */
+  protected final Object globalAgentJsapiTicketRefreshLock = new Object();
+
   protected WxCpConfigStorage configStorage;
 
+  private WxSessionManager sessionManager = new StandardSessionManager();
 
-  protected WxSessionManager sessionManager = new StandardSessionManager();
   /**
    * 临时文件目录
    */
-  protected File tmpDirFile;
+  private File tmpDirFile;
   private int retrySleepMillis = 1000;
   private int maxRetryTimes = 5;
 
@@ -88,6 +84,30 @@ public String getAccessToken() throws WxErrorException {
     return getAccessToken(false);
   }
 
+  @Override
+  public String getAgentJsapiTicket() throws WxErrorException {
+    return this.getAgentJsapiTicket(false);
+  }
+
+  @Override
+  public String getAgentJsapiTicket(boolean forceRefresh) throws WxErrorException {
+    if (forceRefresh) {
+      this.configStorage.expireAgentJsapiTicket();
+    }
+
+    if (this.configStorage.isAgentJsapiTicketExpired()) {
+      synchronized (this.globalAgentJsapiTicketRefreshLock) {
+        if (this.configStorage.isAgentJsapiTicketExpired()) {
+          String responseContent = this.get(WxCpService.GET_AGENT_CONFIG_TICKET, null);
+          JsonObject jsonObject = new JsonParser().parse(responseContent).getAsJsonObject();
+          this.configStorage.updateAgentJsapiTicket(jsonObject.get("ticket").getAsString(),
+            jsonObject.get("expires_in").getAsInt());
+        }
+      }
+    }
+
+    return this.configStorage.getAgentJsapiTicket();
+  }
 
   @Override
   public String getJsapiTicket() throws WxErrorException {
@@ -99,19 +119,18 @@ public String getJsapiTicket(boolean forceRefresh) throws WxErrorException {
     if (forceRefresh) {
       this.configStorage.expireJsapiTicket();
     }
+
     if (this.configStorage.isJsapiTicketExpired()) {
       synchronized (this.globalJsapiTicketRefreshLock) {
         if (this.configStorage.isJsapiTicketExpired()) {
-          String responseContent = execute(SimpleGetRequestExecutor.create(this), WxCpService.GET_JSAPI_TICKET, null);
-          JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
-          JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
-          String jsapiTicket = tmpJsonObject.get("ticket").getAsString();
-          int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
-          this.configStorage.updateJsapiTicket(jsapiTicket,
-            expiresInSeconds);
+          String responseContent = this.get(WxCpService.GET_JSAPI_TICKET, null);
+          JsonObject tmpJsonObject = new JsonParser().parse(responseContent).getAsJsonObject();
+          this.configStorage.updateJsapiTicket(tmpJsonObject.get("ticket").getAsString(),
+            tmpJsonObject.get("expires_in").getAsInt());
         }
       }
     }
+
     return this.configStorage.getJsapiTicket();
   }
 
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpConfigStorage.java
index 65dd3affff..e13738142f 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpConfigStorage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpConfigStorage.java
@@ -36,11 +36,23 @@ public interface WxCpConfigStorage {
 
   /**
    * 应该是线程安全的
-   *
-   * @param jsapiTicket
    */
   void updateJsapiTicket(String jsapiTicket, int expiresInSeconds);
 
+  String getAgentJsapiTicket();
+
+  boolean isAgentJsapiTicketExpired();
+
+  /**
+   * 强制将jsapi ticket过期掉
+   */
+  void expireAgentJsapiTicket();
+
+  /**
+   * 应该是线程安全的
+   */
+  void updateAgentJsapiTicket(String jsapiTicket, int expiresInSeconds);
+
   String getCorpId();
 
   String getCorpSecret();
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpInMemoryConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpInMemoryConfigStorage.java
index 1b9f8a61b5..a501edeb6e 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpInMemoryConfigStorage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpInMemoryConfigStorage.java
@@ -1,11 +1,11 @@
 package me.chanjar.weixin.cp.config;
 
-import java.io.File;
-
 import me.chanjar.weixin.common.bean.WxAccessToken;
 import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
 import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
 
+import java.io.File;
+
 /**
  * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化
  *
@@ -32,6 +32,9 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {
   protected volatile String jsapiTicket;
   protected volatile long jsapiTicketExpiresTime;
 
+  protected volatile String agentJsapiTicket;
+  protected volatile long agentJsapiTicketExpiresTime;
+
   protected volatile File tmpDirFile;
 
   private volatile ApacheHttpClientBuilder apacheHttpClientBuilder;
@@ -95,6 +98,28 @@ public synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeco
     this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
   }
 
+  @Override
+  public String getAgentJsapiTicket() {
+    return this.agentJsapiTicket;
+  }
+
+  @Override
+  public boolean isAgentJsapiTicketExpired() {
+    return System.currentTimeMillis() > this.agentJsapiTicketExpiresTime;
+  }
+
+  @Override
+  public void expireAgentJsapiTicket() {
+    this.agentJsapiTicketExpiresTime = 0;
+  }
+
+  @Override
+  public void updateAgentJsapiTicket(String jsapiTicket, int expiresInSeconds) {
+    this.agentJsapiTicket = jsapiTicket;
+    // 预留200秒的时间
+    this.agentJsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
+  }
+
   @Override
   public void expireJsapiTicket() {
     this.jsapiTicketExpiresTime = 0;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpJedisConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpJedisConfigStorage.java
index 6ae48f0e64..7f9fcf654b 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpJedisConfigStorage.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpJedisConfigStorage.java
@@ -26,6 +26,8 @@ public class WxCpJedisConfigStorage implements WxCpConfigStorage {
   private static final String ACCESS_TOKEN_EXPIRES_TIME_KEY = "WX_CP_ACCESS_TOKEN_EXPIRES_TIME";
   private static final String JS_API_TICKET_KEY = "WX_CP_JS_API_TICKET";
   private static final String JS_API_TICKET_EXPIRES_TIME_KEY = "WX_CP_JS_API_TICKET_EXPIRES_TIME";
+  private static final String AGENT_JSAPI_TICKET_KEY = "WX_CP_AGENT_%s_JSAPI_TICKET";
+  private static final String AGENT_JSAPI_TICKET_EXPIRES_TIME_KEY = "WX_CP_AGENT_%s_JSAPI_TICKET_EXPIRES_TIME";
   /**
    * Redis clients pool
    */
@@ -46,7 +48,7 @@ public class WxCpJedisConfigStorage implements WxCpConfigStorage {
   public WxCpJedisConfigStorage(JedisPool jedisPool) {
     this.jedisPool = jedisPool;
   }
-  
+
   public WxCpJedisConfigStorage(String host, int port) {
     jedisPool = new JedisPool(host, port);
   }
@@ -83,8 +85,7 @@ public boolean isAccessTokenExpired() {
       String expiresTimeStr = jedis.get(ACCESS_TOKEN_EXPIRES_TIME_KEY);
 
       if (expiresTimeStr != null) {
-        Long expiresTime = Long.parseLong(expiresTimeStr);
-        return System.currentTimeMillis() > expiresTime;
+        return System.currentTimeMillis() > Long.parseLong(expiresTimeStr);
       }
 
       return true;
@@ -123,17 +124,15 @@ public String getJsapiTicket() {
 
   @Override
   public boolean isJsapiTicketExpired() {
-
     try (Jedis jedis = this.jedisPool.getResource()) {
       String expiresTimeStr = jedis.get(JS_API_TICKET_EXPIRES_TIME_KEY);
 
       if (expiresTimeStr != null) {
-        Long expiresTime = Long.parseLong(expiresTimeStr);
+        long expiresTime = Long.parseLong(expiresTimeStr);
         return System.currentTimeMillis() > expiresTime;
       }
 
       return true;
-
     }
   }
 
@@ -146,16 +145,51 @@ public void expireJsapiTicket() {
 
   @Override
   public synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
-
     try (Jedis jedis = this.jedisPool.getResource()) {
       jedis.set(JS_API_TICKET_KEY, jsapiTicket);
-
       jedis.set(JS_API_TICKET_EXPIRES_TIME_KEY,
         (System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L + ""));
     }
 
   }
 
+  @Override
+  public String getAgentJsapiTicket() {
+    try (Jedis jedis = this.jedisPool.getResource()) {
+      return jedis.get(String.format(AGENT_JSAPI_TICKET_KEY, agentId));
+    }
+  }
+
+  @Override
+  public boolean isAgentJsapiTicketExpired() {
+    try (Jedis jedis = this.jedisPool.getResource()) {
+      String expiresTimeStr = jedis.get(String.format(AGENT_JSAPI_TICKET_EXPIRES_TIME_KEY, agentId));
+
+      if (expiresTimeStr != null) {
+        return System.currentTimeMillis() > Long.parseLong(expiresTimeStr);
+      }
+
+      return true;
+    }
+  }
+
+  @Override
+  public void expireAgentJsapiTicket() {
+    try (Jedis jedis = this.jedisPool.getResource()) {
+      jedis.set(String.format(AGENT_JSAPI_TICKET_EXPIRES_TIME_KEY, agentId), "0");
+    }
+  }
+
+  @Override
+  public void updateAgentJsapiTicket(String jsapiTicket, int expiresInSeconds) {
+    try (Jedis jedis = this.jedisPool.getResource()) {
+      jedis.set(String.format(AGENT_JSAPI_TICKET_KEY, agentId), jsapiTicket);
+      jedis.set(String.format(AGENT_JSAPI_TICKET_EXPIRES_TIME_KEY, agentId),
+        (System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L + ""));
+    }
+
+  }
+
   @Override
   public String getCorpId() {
     return this.corpId;
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImplTest.java
new file mode 100644
index 0000000000..7470430a19
--- /dev/null
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImplTest.java
@@ -0,0 +1,31 @@
+package me.chanjar.weixin.cp.api.impl;
+
+import com.google.inject.Inject;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.cp.api.ApiTestModule;
+import me.chanjar.weixin.cp.api.WxCpService;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.testng.Assert.*;
+
+/**
+ * 
+ *  Created by BinaryWang on 2019/3/31.
+ * 
+ * + * @author Binary Wang + */ +@Test +@Guice(modules = ApiTestModule.class) +public class BaseWxCpServiceImplTest { + @Inject + protected WxCpService wxService; + + @Test + public void testGetAgentJsapiTicket() throws WxErrorException { + assertThat(this.wxService.getAgentJsapiTicket()).isNotEmpty(); + assertThat(this.wxService.getAgentJsapiTicket(true)).isNotEmpty(); + } +} From 970ee5136c71037083df4a0161f70121da7904b6 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 31 Mar 2019 17:53:23 +0800 Subject: [PATCH 54/81] =?UTF-8?q?=E5=8F=91=E5=B8=833.3.7.B=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- weixin-java-common/pom.xml | 2 +- weixin-java-cp/pom.xml | 2 +- weixin-java-miniapp/pom.xml | 2 +- weixin-java-mp/pom.xml | 2 +- weixin-java-open/pom.xml | 2 +- weixin-java-pay/pom.xml | 2 +- .../bean/request/WxPaySendRedpackRequest.zip | Bin 0 -> 2180 bytes 8 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.zip diff --git a/pom.xml b/pom.xml index 2ab6f67684..aabc6c50c3 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.github.binarywang wx-java - 3.3.6.B + 3.3.7.B pom WxJava - Weixin/Wechat Java SDK 微信开发Java SDK diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 85febb450b..751cde12b4 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.6.B + 3.3.7.B weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index db77108ae5..d1346f5728 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.6.B + 3.3.7.B weixin-java-cp diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index 7a74c478c1..f56965ad35 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.6.B + 3.3.7.B weixin-java-miniapp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 10f2001b82..d857ad9a28 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.6.B + 3.3.7.B weixin-java-mp diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index 611e3cf05c..c8a6dd436a 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.6.B + 3.3.7.B weixin-java-open diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index db0d284c35..fc9f46af28 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ com.github.binarywang wx-java - 3.3.6.B + 3.3.7.B 4.0.0 diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.zip b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.zip new file mode 100644 index 0000000000000000000000000000000000000000..b02696333a4441acee91f7a592a0401b49654d93 GIT binary patch literal 2180 zcmaKuXE+;*8pk83d1@4;9II%Z2!fzAMpPO*Xd63C6)}UfW={k;4VS1r$~9wCqngm_ zp+;$`B4(_jwW>;u5=Y(B^W3lZzVGw={{Ii}^M3xJtT?&E003TIz~|a*>plwP(rX?7 zAXfwckO2Sy=m-=x($OpEu7lUzV63OVgICCXFTy=_KWrGb9_{KlGa*4-MdKp$&C(}c z>oQs`&TxJiW0GkKF9#!ccq4iIhkMiRYBJZ8`5?JT5MOyEE>UDBwDOe-MJyrkLq|aw z_>J9>fRBZ%F1?AsvONKedVI%&>z{??dL!0Fu0a&PN@BB6cc&nO{4F{VTY-xyJGk7! zV8M$n!N@gJt~YPbgTZQY63V^lDEOVbO0?vp(W=daxBnvJ=1m3Ss)qSN{LRaK3ZDo2 znp*xccTPWdgbf)Bk-B$90~1uD?x?@tDwaRC+pq(l?f=#HtL)O4S)iBPs*&VZx^)T> zRaPtyy=uDe{KMXu6rXt+wH1cW*{xyDEdq=(p5>&FFrxRV6>!n#F)yLC%h>79_gFiz z%R{@8uJ{}4FIH%H62FhtS3vzR_$9_DVYp!PTpWfOT7?lT)qS|qT7s0c7`tzornu%{ zg~yOT#UcHqRZj5=jj}SdNG`Q{;04BdeW$@?Hcg~WE|tR>AyS_0A=l@wUyG=(hrT7q zOQ#4D)XX3<;DIrr5yQP6VbQp7drd*9cB^!=k}4oYYyA2^|B~uCqF+f>V^0dl!^{8` zO39Yll*~sUDl@HTboM(kUBP$Zh^KSsy}SCORln=ejM^77%=z(=k>#CPGTA;eON&3a zLP}ZQB=@6DG^Udv)t)&PGsmzk*k-7wH*=8*TW5nCKX49P4{lg*TbktY&Zr=N&-9kf z@xV(?JDw=j!cIs@s_^}}cB$6S(lUp30aAV1<<-`{;PU!a<8BbsWeMq;`)V2rz9qkO zn8RKA%WrnBMt=~XMU=Q>C%568g+*pv6ulh0I@YCK+S?zrK7I3QMxWKAnmPFjsvfH0 zeZU_+A?^FFj$E6h3yPhf@1z?^fbJ$F3K%ejh=e7s(zkb$jgu$8?;r-lZpT<+hHy!S z`uhk>G}qb5r#jo^rO(r}$!kKBQ3SABi8S34)hHs%9ibw2JDx7xVGML?=_S)4=C}K* z%TBGDJ>$C1`>;28U`6WMPSwt^8+JqT23>Bf2n*rY(X}oI;WJ>L-UdX-LQk*bnq4t^!b?xMt>1$fjpVcIjT%MR3zz zQ!8Q+lSh(!&l8V!`?6sn+PZz9UYJtbXW_X))5++WvCxhmK0dg0DjkiqSE^;L@PPB` zwS~lMz}Ao9JHJ-B6%cvFYc#f`DIug^Dnla-EG#*7pz*6$dl18bXF>__cbIVbM3Ru) zow@J<8ybr+IPPY+=}8 z8>@l!)qV+AE(y1!Wm$fmwH#hR956n;mBF7cUk!b zRA_!?#lB+GHylZPD`~u&SvPNCc!agTC6;~NL-gr^QgvZnJ{7y)*uwU(l9@WOAlsdf z9AAdwO4z2R8tq#1l_j$_6Vs8}lioQlof@{m2Pkm+h~6dR24VRbZ}y}oBI=vvCuzP? zNVaJ}>bGw?W@%ET%7qu2^ab5J<8|}`39tKY&_dOaW@FU8`tqiK#CXiW`cuBZllotG zW@W@0qY5YwpL|`3rCt+iF2gOcCEuB+h8%QFxeTu)p@h5zhX?C25_%M3V*`_`YTD^p zrY~fvKjP&*jk1CrkV)*GgP^w~?FDji6OJ z>NmL#jI58R=vigh6?^(o)?Hk3(6E`yu!UX?kL=Mz7Z=9)qRkCMsV^t%+_f+d*i+ol z-ZeV>SRggW)SujHUW@P7QtP-0s-8Q3k9MeO-hCCwxpBmt@iTWdJ2q)=ZTKyCXA!8Q zf#51$k- literal 0 HcmV?d00001 From a0584e142d0d631298b803115bd079f24fc7f773 Mon Sep 17 00:00:00 2001 From: lj128 <1218018144@qq.com> Date: Tue, 2 Apr 2019 11:21:15 +0800 Subject: [PATCH 55/81] =?UTF-8?q?#989=20=E5=BE=AE=E4=BF=A1=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E5=A2=9E=E5=8A=A0=E6=9F=A5=E8=AF=A2=E7=BA=A2=E5=8C=85?= =?UTF-8?q?=E5=92=8C=E6=8B=89=E5=8F=96=E8=AE=A2=E5=8D=95=E8=AF=84=E8=AE=BA?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E9=87=8D=E8=BD=BD=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wxpay/service/EntPayService.java | 26 ++++++++ .../wxpay/service/WxPayService.java | 62 ++++++++++++------- .../service/impl/BaseWxPayServiceImpl.java | 25 ++++++++ .../wxpay/service/impl/EntPayServiceImpl.java | 44 ++++++------- .../impl/WxPayServiceApacheHttpImpl.java | 7 +++ .../impl/WxPayServiceJoddHttpImpl.java | 9 +++ 6 files changed, 127 insertions(+), 46 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/EntPayService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/EntPayService.java index 43162f79d3..d0be5c4b4f 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/EntPayService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/EntPayService.java @@ -42,6 +42,19 @@ public interface EntPayService { * @throws WxPayException the wx pay exception */ EntPayQueryResult queryEntPay(String partnerTradeNo) throws WxPayException; + /** + *
+   * 查询企业付款API.
+   * 用于商户的企业付款操作进行结果查询,返回付款操作详细结果。
+   * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3
+   * 接口链接:https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo
+   * 
+ * + * @param partnerTradeNo 商户订单号 + * @return the ent pay query result + * @throws WxPayException the wx pay exception + */ + EntPayQueryResult queryEntPay(EntPayQueryRequest request) throws WxPayException; /** *
@@ -92,4 +105,17 @@ public interface EntPayService {
    * @throws WxPayException the wx pay exception
    */
   EntPayBankQueryResult queryPayBank(String partnerTradeNo) throws WxPayException;
+  /**
+   * 企业付款到银行卡查询.
+   * 
+   * 用于对商户企业付款到银行卡操作进行结果查询,返回付款操作详细结果。
+   * 文档详见:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_3
+   * 接口链接:https://api.mch.weixin.qq.com/mmpaysptrans/query_bank
+   * 
+ * + * @param partnerTradeNo 商户订单号 + * @return the ent pay bank query result + * @throws WxPayException the wx pay exception + */ + EntPayBankQueryResult queryPayBank(EntPayBankQueryRequest request) throws WxPayException; } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java index e8bb107962..08b59e2135 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java @@ -14,30 +14,8 @@ import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; import com.github.binarywang.wxpay.bean.notify.WxScanPayNotifyResult; -import com.github.binarywang.wxpay.bean.request.WxPayAuthcode2OpenidRequest; -import com.github.binarywang.wxpay.bean.request.WxPayDownloadBillRequest; -import com.github.binarywang.wxpay.bean.request.WxPayDownloadFundFlowRequest; -import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest; -import com.github.binarywang.wxpay.bean.request.WxPayOrderCloseRequest; -import com.github.binarywang.wxpay.bean.request.WxPayOrderQueryRequest; -import com.github.binarywang.wxpay.bean.request.WxPayOrderReverseRequest; -import com.github.binarywang.wxpay.bean.request.WxPayRefundQueryRequest; -import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest; -import com.github.binarywang.wxpay.bean.request.WxPayReportRequest; -import com.github.binarywang.wxpay.bean.request.WxPaySendRedpackRequest; -import com.github.binarywang.wxpay.bean.request.WxPayShorturlRequest; -import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; -import com.github.binarywang.wxpay.bean.result.WxPayBillResult; -import com.github.binarywang.wxpay.bean.result.WxPayFundFlowResult; -import com.github.binarywang.wxpay.bean.result.WxPayMicropayResult; -import com.github.binarywang.wxpay.bean.result.WxPayOrderCloseResult; -import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult; -import com.github.binarywang.wxpay.bean.result.WxPayOrderReverseResult; -import com.github.binarywang.wxpay.bean.result.WxPayRedpackQueryResult; -import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryResult; -import com.github.binarywang.wxpay.bean.result.WxPayRefundResult; -import com.github.binarywang.wxpay.bean.result.WxPaySendRedpackResult; -import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult; +import com.github.binarywang.wxpay.bean.request.*; +import com.github.binarywang.wxpay.bean.result.*; import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.exception.WxPayException; @@ -326,6 +304,20 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri * @throws WxPayException the wx pay exception */ WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxPayException; + /** + *
+   *   查询红包记录.
+   *   用于商户对已发放的红包进行查询红包的具体信息,可支持普通红包和裂变包。
+   *   请求Url:https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo
+   *   是否需要证书:是(证书及使用说明详见商户证书)
+   *   请求方式:POST
+   * 
+ * + * @param mchBillNo 商户发放红包的商户订单号,比如10000098201411111234567890 + * @return the wx pay redpack query result + * @throws WxPayException the wx pay exception + */ + WxPayRedpackQueryResult queryRedpack(WxPayRedpackQueryRequest request) throws WxPayException; /** *
@@ -685,4 +677,26 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri
    * @throws WxPayException the wx pay exception
    */
   String queryComment(Date beginDate, Date endDate, Integer offset, Integer limit) throws WxPayException;
+
+  /**
+   * 
+   * 拉取订单评价数据.
+   * 商户可以通过该接口拉取用户在微信支付交易记录中针对你的支付记录进行的评价内容。商户可结合商户系统逻辑对该内容数据进行存储、分析、展示、客服回访以及其他使用。如商户业务对评价内容有依赖,可主动引导用户进入微信支付交易记录进行评价。
+   * 注意:
+   * 1. 该内容所有权为提供内容的微信用户,商户在使用内容的过程中应遵从用户意愿
+   * 2. 一次最多拉取200条评价数据,可根据时间区间分批次拉取
+   * 3. 接口只能拉取最近三个月以内的评价数据
+   * 接口链接:https://api.mch.weixin.qq.com/billcommentsp/batchquerycomment
+   * 是否需要证书:需要
+   * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_17&index=10
+   * 
+ * + * @param beginDate 开始时间 + * @param endDate 结束时间 + * @param offset 位移 + * @param limit 条数,建议填null,否则接口会报签名错误 + * @return the string + * @throws WxPayException the wx pay exception + */ + String queryComment(WxPayQueryCommentRequest request) throws WxPayException; } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java index fdd3bcdd9b..39645d6986 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java @@ -251,6 +251,17 @@ public WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxPayExcept result.checkResult(this, request.getSignType(), true); return result; } + @Override + public WxPayRedpackQueryResult queryRedpack(WxPayRedpackQueryRequest request) throws WxPayException { + request.setBillType(BillType.MCHT); + request.checkAndSign(this.getConfig()); + + String url = this.getPayBaseUrl() + "/mmpaymkttransfers/gethbinfo"; + String responseContent = this.post(url, request.toXML(), true); + WxPayRedpackQueryResult result = BaseWxPayResult.fromXML(responseContent, WxPayRedpackQueryResult.class); + result.checkResult(this, request.getSignType(), true); + return result; + } @Override public WxPayOrderQueryResult queryOrder(String transactionId, String outTradeNo) throws WxPayException { @@ -822,4 +833,18 @@ public String queryComment(Date beginDate, Date endDate, Integer offset, Integer return responseContent; } + @Override + public String queryComment(WxPayQueryCommentRequest request) throws WxPayException { + request.checkAndSign(this.getConfig()); + request.setSignType(SignType.HMAC_SHA256); + String url = this.getPayBaseUrl() + "/billcommentsp/batchquerycomment"; + + String responseContent = this.post(url, request.toXML(), true); + if (responseContent.startsWith("<")) { + throw WxPayException.from(BaseWxPayResult.fromXML(responseContent, WxPayCommonResult.class)); + } + + return responseContent; + } + } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/EntPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/EntPayServiceImpl.java index d694f42e78..59db3ee078 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/EntPayServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/EntPayServiceImpl.java @@ -74,6 +74,17 @@ public EntPayQueryResult queryEntPay(String partnerTradeNo) throws WxPayExceptio return result; } + @Override + public EntPayQueryResult queryEntPay(EntPayQueryRequest request) throws WxPayException { + request.checkAndSign(this.payService.getConfig()); + + String url = this.payService.getPayBaseUrl() + "/mmpaymkttransfers/gettransferinfo"; + String responseContent = this.payService.post(url, request.toXML(), true); + EntPayQueryResult result = BaseWxPayResult.fromXML(responseContent, EntPayQueryResult.class); + result.checkResult(this.payService, request.getSignType(), true); + return result; + } + @Override public String getPublicKey() throws WxPayException { WxPayDefaultRequest request = new WxPayDefaultRequest(); @@ -118,6 +129,17 @@ public EntPayBankQueryResult queryPayBank(String partnerTradeNo) throws WxPayExc return result; } + @Override + public EntPayBankQueryResult queryPayBank(EntPayBankQueryRequest request) throws WxPayException { + request.checkAndSign(this.payService.getConfig()); + + String url = this.payService.getPayBaseUrl() + "/mmpaysptrans/query_bank"; + String responseContent = this.payService.post(url, request.toXML(), true); + EntPayBankQueryResult result = BaseWxPayResult.fromXML(responseContent, EntPayBankQueryResult.class); + result.checkResult(this.payService, request.getSignType(), true); + return result; + } + private String encryptRSA(File publicKeyFile, String srcString) throws WxPayException { try { Security.addProvider(new BouncyCastleProvider()); @@ -145,26 +167,4 @@ private File buildPublicKeyFile() throws WxPayException { throw new WxPayException("生成加密公钥文件时发生异常", e); } } - - /** - * The entry point of application. - * - * @param args the input arguments - * @throws WxPayException the wx pay exception - * @throws IOException the io exception - */ - public static void main(String[] args) throws WxPayException, IOException { - String key = "-----BEGIN RSA PUBLIC KEY-----\n" + - "MIIBCgKCAQEAtEeUSop/YGqZ53Y++R9NapFSZmorj+SL/brmJUU7+hyClEnPOeG/\n" + - "v6/ZrX9qo25JAojrBDbqaW9L+HtzI141vusarRYIGPvVqTV30L5db0Yq7AmX7Hs9\n" + - "s+nEtoMAwMWUzQPXLUs2mt6rpu85HwAIK3F4Xb+OFIbXCJTbDvWYtQssn07lr+IY\n" + - "jPA00sON71egmuRrCoQClkhf0vgrhj7eHUCRZRJ2zf4UU31fHv+kO441hVD5TTP8\n" + - "bjJvFm6TW3sgQE8aCDbomtu+syk4Tv/4ONCqxG8d/kF1TlU+idGWEU179uR/KSjP\n" + - "p7kM7BoaY2goFgYAe4DsI8Fh33dCOiKyVwIDAQAB\n" + - "-----END RSA PUBLIC KEY-----"; - Path tmpFile = Files.createTempFile("payToBank", ".pem"); - Files.write(tmpFile, key.getBytes(StandardCharsets.UTF_8)); - System.out.println(new EntPayServiceImpl(null).encryptRSA(tmpFile.toFile(), "111111")); - } - } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java index 5d6f3be4a8..1703c200f5 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceApacheHttpImpl.java @@ -4,6 +4,13 @@ import java.nio.charset.StandardCharsets; import javax.net.ssl.SSLContext; +import com.github.binarywang.wxpay.bean.WxPayApiData; +import com.github.binarywang.wxpay.bean.request.WxPayQueryCommentRequest; +import com.github.binarywang.wxpay.bean.request.WxPayRedpackQueryRequest; +import com.github.binarywang.wxpay.bean.result.WxPayCommonResult; +import com.github.binarywang.wxpay.bean.result.WxPayRedpackQueryResult; +import com.github.binarywang.wxpay.exception.WxPayException; +import jodd.util.Base64; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceJoddHttpImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceJoddHttpImpl.java index 72f2539fb1..81d35614d5 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceJoddHttpImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/WxPayServiceJoddHttpImpl.java @@ -1,5 +1,14 @@ package com.github.binarywang.wxpay.service.impl; +import java.nio.charset.StandardCharsets; +import javax.net.ssl.SSLContext; + +import com.github.binarywang.wxpay.bean.request.WxPayQueryCommentRequest; +import com.github.binarywang.wxpay.bean.request.WxPayRedpackQueryRequest; +import com.github.binarywang.wxpay.bean.result.WxPayCommonResult; +import com.github.binarywang.wxpay.bean.result.WxPayRedpackQueryResult; +import org.apache.commons.lang3.StringUtils; + import com.github.binarywang.wxpay.bean.WxPayApiData; import com.github.binarywang.wxpay.exception.WxPayException; import jodd.http.HttpConnectionProvider; From cea482a762e33fe91490486b30deddeab703ca4e Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Tue, 2 Apr 2019 12:09:24 +0800 Subject: [PATCH 56/81] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=8F=8A=E8=A7=84?= =?UTF-8?q?=E8=8C=83=E9=83=A8=E5=88=86=E6=96=B0=E6=8F=90=E4=BA=A4=E4=BB=A3?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wxpay/service/WxPayService.java | 7 +- .../service/impl/BaseWxPayServiceImpl.java | 96 ++++--------------- 2 files changed, 22 insertions(+), 81 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java index 08b59e2135..51d46512a2 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java @@ -313,7 +313,7 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri * 请求方式:POST *
* - * @param mchBillNo 商户发放红包的商户订单号,比如10000098201411111234567890 + * @param request 红包查询请求 * @return the wx pay redpack query result * @throws WxPayException the wx pay exception */ @@ -691,10 +691,7 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_17&index=10 *
* - * @param beginDate 开始时间 - * @param endDate 结束时间 - * @param offset 位移 - * @param limit 条数,建议填null,否则接口会报签名错误 + * @param request 查询请求 * @return the string * @throws WxPayException the wx pay exception */ diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java index 39645d6986..b202e18086 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java @@ -1,29 +1,8 @@ package com.github.binarywang.wxpay.service.impl; -import java.io.File; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Date; -import java.util.HashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.zip.ZipException; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.github.binarywang.utils.qrcode.QrcodeUtils; import com.github.binarywang.wxpay.bean.WxPayApiData; -import com.github.binarywang.wxpay.bean.coupon.WxPayCouponInfoQueryRequest; -import com.github.binarywang.wxpay.bean.coupon.WxPayCouponInfoQueryResult; -import com.github.binarywang.wxpay.bean.coupon.WxPayCouponSendRequest; -import com.github.binarywang.wxpay.bean.coupon.WxPayCouponSendResult; -import com.github.binarywang.wxpay.bean.coupon.WxPayCouponStockQueryRequest; -import com.github.binarywang.wxpay.bean.coupon.WxPayCouponStockQueryResult; +import com.github.binarywang.wxpay.bean.coupon.*; import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult; import com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResult; import com.github.binarywang.wxpay.bean.notify.WxScanPayNotifyResult; @@ -31,39 +10,8 @@ import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult; import com.github.binarywang.wxpay.bean.order.WxPayMwebOrderResult; import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult; -import com.github.binarywang.wxpay.bean.request.WxPayAuthcode2OpenidRequest; -import com.github.binarywang.wxpay.bean.request.WxPayDefaultRequest; -import com.github.binarywang.wxpay.bean.request.WxPayDownloadBillRequest; -import com.github.binarywang.wxpay.bean.request.WxPayDownloadFundFlowRequest; -import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest; -import com.github.binarywang.wxpay.bean.request.WxPayOrderCloseRequest; -import com.github.binarywang.wxpay.bean.request.WxPayOrderQueryRequest; -import com.github.binarywang.wxpay.bean.request.WxPayOrderReverseRequest; -import com.github.binarywang.wxpay.bean.request.WxPayQueryCommentRequest; -import com.github.binarywang.wxpay.bean.request.WxPayRedpackQueryRequest; -import com.github.binarywang.wxpay.bean.request.WxPayRefundQueryRequest; -import com.github.binarywang.wxpay.bean.request.WxPayRefundRequest; -import com.github.binarywang.wxpay.bean.request.WxPayReportRequest; -import com.github.binarywang.wxpay.bean.request.WxPaySendRedpackRequest; -import com.github.binarywang.wxpay.bean.request.WxPayShorturlRequest; -import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest; -import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; -import com.github.binarywang.wxpay.bean.result.WxPayAuthcode2OpenidResult; -import com.github.binarywang.wxpay.bean.result.WxPayBillResult; -import com.github.binarywang.wxpay.bean.result.WxPayCommonResult; -import com.github.binarywang.wxpay.bean.result.WxPayFundFlowBaseResult; -import com.github.binarywang.wxpay.bean.result.WxPayFundFlowResult; -import com.github.binarywang.wxpay.bean.result.WxPayMicropayResult; -import com.github.binarywang.wxpay.bean.result.WxPayOrderCloseResult; -import com.github.binarywang.wxpay.bean.result.WxPayOrderQueryResult; -import com.github.binarywang.wxpay.bean.result.WxPayOrderReverseResult; -import com.github.binarywang.wxpay.bean.result.WxPayRedpackQueryResult; -import com.github.binarywang.wxpay.bean.result.WxPayRefundQueryResult; -import com.github.binarywang.wxpay.bean.result.WxPayRefundResult; -import com.github.binarywang.wxpay.bean.result.WxPaySandboxSignKeyResult; -import com.github.binarywang.wxpay.bean.result.WxPaySendRedpackResult; -import com.github.binarywang.wxpay.bean.result.WxPayShorturlResult; -import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult; +import com.github.binarywang.wxpay.bean.request.*; +import com.github.binarywang.wxpay.bean.result.*; import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.constant.WxPayConstants.BillType; import com.github.binarywang.wxpay.constant.WxPayConstants.SignType; @@ -75,6 +23,17 @@ import com.google.common.base.Joiner; import com.google.common.collect.Maps; import jodd.io.ZipUtil; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.zip.ZipException; import static com.github.binarywang.wxpay.constant.WxPayConstants.QUERY_COMMENT_DATE_FORMAT; import static com.github.binarywang.wxpay.constant.WxPayConstants.TarType; @@ -142,7 +101,7 @@ public WxPayRefundResult refund(WxPayRefundRequest request) throws WxPayExceptio String url = this.getPayBaseUrl() + "/secapi/pay/refund"; if (this.getConfig().isUseSandboxEnv()) { - url = PAY_BASE_URL + "/sandboxnew/pay/refund"; + url = PAY_BASE_URL + "/sandboxnew/pay/refund"; } String responseContent = this.post(url, request.toXML(), true); @@ -242,15 +201,9 @@ public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) throw public WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxPayException { WxPayRedpackQueryRequest request = new WxPayRedpackQueryRequest(); request.setMchBillNo(mchBillNo); - request.setBillType(BillType.MCHT); - request.checkAndSign(this.getConfig()); - - String url = this.getPayBaseUrl() + "/mmpaymkttransfers/gethbinfo"; - String responseContent = this.post(url, request.toXML(), true); - WxPayRedpackQueryResult result = BaseWxPayResult.fromXML(responseContent, WxPayRedpackQueryResult.class); - result.checkResult(this, request.getSignType(), true); - return result; + return this.queryRedpack(request); } + @Override public WxPayRedpackQueryResult queryRedpack(WxPayRedpackQueryRequest request) throws WxPayException { request.setBillType(BillType.MCHT); @@ -820,25 +773,16 @@ public String queryComment(Date beginDate, Date endDate, Integer offset, Integer request.setEndTime(QUERY_COMMENT_DATE_FORMAT.format(endDate)); request.setOffset(offset); request.setLimit(limit); - request.setSignType(SignType.HMAC_SHA256); - - request.checkAndSign(this.getConfig()); - String url = this.getPayBaseUrl() + "/billcommentsp/batchquerycomment"; - - String responseContent = this.post(url, request.toXML(), true); - if (responseContent.startsWith("<")) { - throw WxPayException.from(BaseWxPayResult.fromXML(responseContent, WxPayCommonResult.class)); - } - - return responseContent; + return this.queryComment(request); } + @Override public String queryComment(WxPayQueryCommentRequest request) throws WxPayException { request.checkAndSign(this.getConfig()); request.setSignType(SignType.HMAC_SHA256); - String url = this.getPayBaseUrl() + "/billcommentsp/batchquerycomment"; + String url = this.getPayBaseUrl() + "/billcommentsp/batchquerycomment"; String responseContent = this.post(url, request.toXML(), true); if (responseContent.startsWith("<")) { throw WxPayException.from(BaseWxPayResult.fromXML(responseContent, WxPayCommonResult.class)); From 9fd7f7d8dcac81d72c50cbf9b5b49b8a2c86e370 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Fri, 12 Apr 2019 17:02:41 +0800 Subject: [PATCH 57/81] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java index 31b88f5f2e..9cbdaf8927 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java @@ -333,6 +333,11 @@ public T executeInternal(RequestExecutor executor, String uri, E da @Override public WxMpConfigStorage getWxMpConfigStorage() { + if (this.configStorageMap.size() == 1) { + // 只有一个公众号,直接返回其配置即可 + return this.configStorageMap.values().iterator().next(); + } + return this.configStorageMap.get(WxMpConfigStorageHolder.get()); } From 9d4847df214ad6af50566046a7992f055876a44a Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 13 Apr 2019 21:33:37 +0800 Subject: [PATCH 58/81] =?UTF-8?q?#999=20=E5=BE=AE=E4=BF=A1=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E5=8F=91=E9=80=81=E7=BA=A2=E5=8C=85=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E4=B8=AD=E5=8A=A0=E5=85=A5=E7=BB=93=E6=9E=9C=E6=98=AF=E5=90=A6?= =?UTF-8?q?=E6=88=90=E5=8A=9F=E7=9A=84=E6=A0=A1=E9=AA=8C=E5=88=A4=E6=96=AD?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java index b202e18086..24677ba908 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java @@ -193,8 +193,9 @@ public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) throw } String responseContent = this.post(url, request.toXML(), true); - //无需校验,因为没有返回签名信息 - return BaseWxPayResult.fromXML(responseContent, WxPaySendRedpackResult.class); + final WxPaySendRedpackResult result = BaseWxPayResult.fromXML(responseContent, WxPaySendRedpackResult.class); + result.checkResult(this, request.getSignType(), true); + return result; } @Override From c2bff929ef7e1961703ede84786a7f8fbae17e10 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 13 Apr 2019 21:50:59 +0800 Subject: [PATCH 59/81] =?UTF-8?q?#997=20=E4=BC=81=E4=B8=9A=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E5=A2=9E=E5=8A=A0=E5=B0=8F=E7=A8=8B=E5=BA=8F=E4=B8=B4?= =?UTF-8?q?=E6=97=B6=E7=99=BB=E5=BD=95=E5=87=AD=E8=AF=81=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/cp/api/WxCpService.java | 9 +++++ .../cp/api/impl/BaseWxCpServiceImpl.java | 14 ++++++++ .../cp/bean/WxCpMaJsCode2SessionResult.java | 33 +++++++++++++++++++ .../cp/api/impl/BaseWxCpServiceImplTest.java | 5 +++ 4 files changed, 61 insertions(+) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMaJsCode2SessionResult.java diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java index 4cff71e620..927b79cbd5 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java @@ -7,6 +7,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.WxCpMessage; import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; import me.chanjar.weixin.cp.config.WxCpConfigStorage; @@ -23,6 +24,7 @@ public interface WxCpService { String BATCH_REPLACE_PARTY = "https://qyapi.weixin.qq.com/cgi-bin/batch/replaceparty"; String BATCH_REPLACE_USER = "https://qyapi.weixin.qq.com/cgi-bin/batch/replaceuser"; String BATCH_GET_RESULT = "https://qyapi.weixin.qq.com/cgi-bin/batch/getresult?jobid="; + String JSCODE_TO_SESSION_URL = "https://qyapi.weixin.qq.com/cgi-bin/miniprogram/jscode2session"; /** *
@@ -124,6 +126,13 @@ public interface WxCpService {
    */
   WxCpMessageSendResult messageSend(WxCpMessage message) throws WxErrorException;
 
+  /**
+   * 小程序登录凭证校验
+   *
+   * @param jsCode 登录时获取的 code
+   */
+  WxCpMaJsCode2SessionResult jsCode2Session(String jsCode) throws WxErrorException;
+
   /**
    * 
    * 获取微信服务器的ip段
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
index e418982e88..f9a146e8f7 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java
@@ -1,5 +1,6 @@
 package me.chanjar.weixin.cp.api.impl;
 
+import com.google.common.base.Joiner;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
@@ -18,6 +19,7 @@
 import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
 import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
 import me.chanjar.weixin.cp.api.*;
+import me.chanjar.weixin.cp.bean.WxCpMaJsCode2SessionResult;
 import me.chanjar.weixin.cp.bean.WxCpMessage;
 import me.chanjar.weixin.cp.bean.WxCpMessageSendResult;
 import me.chanjar.weixin.cp.config.WxCpConfigStorage;
@@ -26,6 +28,8 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * @author chanjarster
@@ -167,6 +171,16 @@ public WxCpMessageSendResult messageSend(WxCpMessage message) throws WxErrorExce
     return WxCpMessageSendResult.fromJson(this.post(WxCpService.MESSAGE_SEND, message.toJson()));
   }
 
+  @Override
+  public WxCpMaJsCode2SessionResult jsCode2Session(String jsCode) throws WxErrorException {
+    Map params = new HashMap<>(2);
+    params.put("js_code", jsCode);
+    params.put("grant_type", "authorization_code");
+
+    String result = this.get(JSCODE_TO_SESSION_URL, Joiner.on("&").withKeyValueSeparator("=").join(params));
+    return WxCpMaJsCode2SessionResult.fromJson(result);
+  }
+
   @Override
   public String[] getCallbackIp() throws WxErrorException {
     String responseContent = get(WxCpService.GET_CALLBACK_IP, null);
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMaJsCode2SessionResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMaJsCode2SessionResult.java
new file mode 100644
index 0000000000..90f1ae840c
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMaJsCode2SessionResult.java
@@ -0,0 +1,33 @@
+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;
+
+/**
+ * 
+ * 小程序登录凭证校验
+ * 文档地址:https://work.weixin.qq.com/api/doc#90000/90136/90289/wx.qy.login
+ * 
+ * @author Binary Wang + */ +@Data +public class WxCpMaJsCode2SessionResult implements Serializable { + private static final long serialVersionUID = 6229609023682814765L; + + @SerializedName("session_key") + private String sessionKey; + + @SerializedName("userid") + private String userId; + + @SerializedName("corpid") + private String corpId; + + public static WxCpMaJsCode2SessionResult fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpMaJsCode2SessionResult.class); + } + +} diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImplTest.java index 7470430a19..69a6aa43d8 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImplTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImplTest.java @@ -28,4 +28,9 @@ public void testGetAgentJsapiTicket() throws WxErrorException { assertThat(this.wxService.getAgentJsapiTicket()).isNotEmpty(); assertThat(this.wxService.getAgentJsapiTicket(true)).isNotEmpty(); } + + @Test + public void testJsCode2Session() throws WxErrorException { + assertThat(this.wxService.jsCode2Session("111")).isNotNull(); + } } From e92e417a1425b7aad47bd316263a38ddef915a4d Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 13 Apr 2019 23:21:06 +0800 Subject: [PATCH 60/81] =?UTF-8?q?=E5=8F=91=E5=B8=833.3.8.B=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- weixin-java-common/pom.xml | 2 +- weixin-java-cp/pom.xml | 2 +- weixin-java-miniapp/pom.xml | 2 +- weixin-java-mp/pom.xml | 2 +- weixin-java-open/pom.xml | 2 +- weixin-java-pay/pom.xml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index aabc6c50c3..19b454b068 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.github.binarywang wx-java - 3.3.7.B + 3.3.8.B pom WxJava - Weixin/Wechat Java SDK 微信开发Java SDK diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 751cde12b4..e88f01c87a 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.7.B + 3.3.8.B weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index d1346f5728..adb0fe93a6 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.7.B + 3.3.8.B weixin-java-cp diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index f56965ad35..c745a3d132 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.7.B + 3.3.8.B weixin-java-miniapp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index d857ad9a28..9a87ab5500 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.7.B + 3.3.8.B weixin-java-mp diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index c8a6dd436a..70459e3fbf 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.7.B + 3.3.8.B weixin-java-open diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index fc9f46af28..c59f50b9f7 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ com.github.binarywang wx-java - 3.3.7.B + 3.3.8.B 4.0.0 From cab663629a547019d53c137a84b0a3945e573d08 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 15 Apr 2019 14:17:42 +0800 Subject: [PATCH 61/81] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/me/chanjar/weixin/mp/api/WxMpService.java | 2 +- .../me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java | 2 +- .../chanjar/weixin/mp/api/impl/BaseWxMpServiceImplTest.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java index 4ccfe30a14..a0452ebad7 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java @@ -347,7 +347,7 @@ public interface WxMpService { * @param mpId 公众号标识 * @return 切换成功,则返回当前对象,方便链式调用,否则抛出异常 */ - WxMpService switchover1(String mpId); + WxMpService switchoverTo(String mpId); /** * 返回客服接口方法实现类,以方便调用其各个接口. diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java index 9cbdaf8927..534ea1390f 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImpl.java @@ -377,7 +377,7 @@ public void removeConfigStorage(String mpId) { } @Override - public WxMpService switchover1(String mpId) { + public WxMpService switchoverTo(String mpId) { if (this.configStorageMap.containsKey(mpId)) { WxMpConfigStorageHolder.set(mpId); return this; diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImplTest.java index 52dfbb9e15..ff0d7537a7 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/BaseWxMpServiceImplTest.java @@ -33,8 +33,8 @@ public void testSwitchover() { } @Test - public void testSwitchover1() throws WxErrorException { - assertThat(this.wxService.switchover1("another").getAccessToken()).isNotEmpty(); + public void testSwitchoverTo() throws WxErrorException { + assertThat(this.wxService.switchoverTo("another").getAccessToken()).isNotEmpty(); assertThat(WxMpConfigStorageHolder.get()).isEqualTo("another"); } } From f46187aed03b08b97236dd5d92039425ba9bb89e Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Wed, 17 Apr 2019 23:40:50 +0800 Subject: [PATCH 62/81] =?UTF-8?q?#1007=20=E5=A2=9E=E5=8A=A0=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E6=94=AF=E4=BB=98=E7=9A=84=20spring=20boot=20starter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 1 + starters/wx-java-pay-starter/pom.xml | 65 +++++++++++++++++++ .../pay/config/WxPayAutoConfiguration.java | 57 ++++++++++++++++ .../pay/properties/WxPayProperties.java | 46 +++++++++++++ .../main/resources/META-INF/spring.factories | 1 + 5 files changed, 170 insertions(+) create mode 100644 starters/wx-java-pay-starter/pom.xml create mode 100644 starters/wx-java-pay-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/config/WxPayAutoConfiguration.java create mode 100644 starters/wx-java-pay-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/properties/WxPayProperties.java create mode 100644 starters/wx-java-pay-starter/src/main/resources/META-INF/spring.factories diff --git a/pom.xml b/pom.xml index 19b454b068..7843d0444a 100644 --- a/pom.xml +++ b/pom.xml @@ -105,6 +105,7 @@ weixin-java-pay weixin-java-miniapp weixin-java-open + starters/wx-java-pay-starter diff --git a/starters/wx-java-pay-starter/pom.xml b/starters/wx-java-pay-starter/pom.xml new file mode 100644 index 0000000000..f61676f3c9 --- /dev/null +++ b/starters/wx-java-pay-starter/pom.xml @@ -0,0 +1,65 @@ + + + + wx-java + com.github.binarywang + 3.3.8.B + + 4.0.0 + + wx-java-pay-starter + + + 2.1.4.RELEASE + + + + + org.springframework.boot + spring-boot-autoconfigure + ${spring.boot.version} + + + org.springframework.boot + spring-boot-configuration-processor + ${spring.boot.version} + true + + + org.projectlombok + lombok + provided + + + com.github.binarywang + weixin-java-pay + ${project.version} + + + + + + + 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/starters/wx-java-pay-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/config/WxPayAutoConfiguration.java b/starters/wx-java-pay-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/config/WxPayAutoConfiguration.java new file mode 100644 index 0000000000..43b2114e6e --- /dev/null +++ b/starters/wx-java-pay-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/config/WxPayAutoConfiguration.java @@ -0,0 +1,57 @@ +package com.binarywang.spring.starter.wxjava.pay.config; + +import com.binarywang.spring.starter.wxjava.pay.properties.WxPayProperties; +import com.github.binarywang.wxpay.config.WxPayConfig; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + *
+ *  微信支付自动配置
+ *  Created by BinaryWang on 2019/4/17.
+ * 
+ * + * @author Binary Wang + */ +@Configuration +@EnableConfigurationProperties(WxPayProperties.class) +@ConditionalOnClass(WxPayService.class) +@ConditionalOnProperty(prefix = "wx.pay", value = "enabled", matchIfMissing = true) +public class WxPayAutoConfiguration { + private WxPayProperties properties; + + @Autowired + public WxPayAutoConfiguration(WxPayProperties properties) { + this.properties = properties; + } + + /** + * 构造微信支付服务对象. + * + * @return 微信支付service + */ + @Bean + @ConditionalOnMissingBean(WxPayService.class) + public WxPayService wxPayService() { + final WxPayServiceImpl wxPayService = new WxPayServiceImpl(); + WxPayConfig payConfig = new WxPayConfig(); + payConfig.setAppId(StringUtils.trimToNull(this.properties.getAppId())); + payConfig.setMchId(StringUtils.trimToNull(this.properties.getMchId())); + payConfig.setMchKey(StringUtils.trimToNull(this.properties.getMchKey())); + payConfig.setSubAppId(StringUtils.trimToNull(this.properties.getSubAppId())); + payConfig.setSubMchId(StringUtils.trimToNull(this.properties.getSubMchId())); + payConfig.setKeyPath(StringUtils.trimToNull(this.properties.getKeyPath())); + + wxPayService.setConfig(payConfig); + return wxPayService; + } + +} diff --git a/starters/wx-java-pay-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/properties/WxPayProperties.java b/starters/wx-java-pay-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/properties/WxPayProperties.java new file mode 100644 index 0000000000..fe8a215650 --- /dev/null +++ b/starters/wx-java-pay-starter/src/main/java/com/binarywang/spring/starter/wxjava/pay/properties/WxPayProperties.java @@ -0,0 +1,46 @@ +package com.binarywang.spring.starter.wxjava.pay.properties; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + *
+ *  微信支付属性配置类
+ * Created by Binary Wang on 2019/4/17.
+ * 
+ * + * @author Binary Wang + */ +@Data +@ConfigurationProperties(prefix = "wx.pay") +public class WxPayProperties { + /** + * 设置微信公众号或者小程序等的appid. + */ + private String appId; + + /** + * 微信支付商户号. + */ + private String mchId; + + /** + * 微信支付商户密钥. + */ + private String mchKey; + + /** + * 服务商模式下的子商户公众账号ID,普通模式请不要配置,请在配置文件中将对应项删除. + */ + private String subAppId; + + /** + * 服务商模式下的子商户号,普通模式请不要配置,最好是请在配置文件中将对应项删除. + */ + private String subMchId; + + /** + * apiclient_cert.p12文件的绝对路径,或者如果放在项目中,请以classpath:开头指定. + */ + private String keyPath; +} diff --git a/starters/wx-java-pay-starter/src/main/resources/META-INF/spring.factories b/starters/wx-java-pay-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..37fe6c20e4 --- /dev/null +++ b/starters/wx-java-pay-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.binarywang.spring.starter.wxjava.pay.config.WxPayAutoConfiguration From e5b6324be811ac7b2e16fa7507d2b2f4253c716e Mon Sep 17 00:00:00 2001 From: niuchang3 <281344730@qq.com> Date: Thu, 18 Apr 2019 09:18:54 +0800 Subject: [PATCH 63/81] =?UTF-8?q?#1003=20=E4=BF=AE=E5=A4=8D=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E6=94=AF=E4=BB=98=E7=BA=A2=E5=8C=85=E6=9F=A5=E8=AF=A2?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=9C=A8=E6=9C=8D=E5=8A=A1=E5=95=86=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E4=B8=8B=E7=9A=84=E7=AD=BE=E5=90=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wxpay/bean/request/WxPayRedpackQueryRequest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java index 4bbee5aaf2..e8ade81d9f 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRedpackQueryRequest.java @@ -24,6 +24,11 @@ @AllArgsConstructor @XStreamAlias("xml") public class WxPayRedpackQueryRequest extends BaseWxPayRequest { + + @Override + protected String[] getIgnoredParamsForSign() { + return new String[]{"sub_appid","sub_mch_id"}; + } /** * 商户订单号 * mch_billno From a16e0f4c88405547c11dfe8847c493aec23f420a Mon Sep 17 00:00:00 2001 From: thomas2050 <37628237+thomas2050@users.noreply.github.com> Date: Sat, 27 Apr 2019 20:39:23 +0800 Subject: [PATCH 64/81] =?UTF-8?q?#1025=20=E4=BC=9A=E5=91=98=E5=8D=A1?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E6=96=B0=E5=A2=9E=E8=B7=B3=E8=BD=AC=E5=9E=8B?= =?UTF-8?q?=E4=BC=9A=E5=91=98=E5=8D=A1=E7=94=A8=E6=88=B7=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E8=B5=84=E6=96=99=E7=9A=84=E4=BF=A1=E6=81=AF=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/mp/api/WxMpMemberCardService.java | 49 +++++++++++--- .../api/impl/WxMpMemberCardServiceImpl.java | 17 +++-- .../WxMpMemberCardActivateTempInfoResult.java | 24 +++++++ .../weixin/mp/util/json/WxMpGsonBuilder.java | 2 + ...CardActivateTempInfoResultGsonAdapter.java | 65 +++++++++++++++++++ .../impl/WxMpMemberCardServiceImplTest.java | 15 ++++- 6 files changed, 154 insertions(+), 18 deletions(-) create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardActivateTempInfoResult.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMemberCardActivateTempInfoResultGsonAdapter.java diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java index b071980480..ba79d78511 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java @@ -6,12 +6,7 @@ import me.chanjar.weixin.mp.bean.card.MemberCardActivateUserFormResult; import me.chanjar.weixin.mp.bean.card.MemberCardUpdateRequest; import me.chanjar.weixin.mp.bean.card.WxMpCardCreateResult; -import me.chanjar.weixin.mp.bean.membercard.ActivatePluginParam; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardActivatedMessage; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardCreateMessage; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUpdateMessage; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUpdateResult; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUserInfoResult; +import me.chanjar.weixin.mp.bean.membercard.*; /** * 会员卡相关接口. @@ -41,19 +36,33 @@ public interface WxMpMemberCardService { */ String MEMBER_CARD_UPDATE = "https://api.weixin.qq.com/card/update"; + /** + * 跳转型会员卡开卡字段,获取用户提交资料(wx_activate=true情况调用),开发者根据activate_ticket获取到用户填写的信息 + */ + String MEMBER_CARD_ACTIVATE_TEMP_INFO = "https://api.weixin.qq.com/card/membercard/activatetempinfo/get"; /** * 得到WxMpService. + * + * @return WxMpService */ WxMpService getWxMpService(); /** * 会员卡创建接口. + * + * @param createJson 会员卡json字符串 + * @return 返回json字符串 + * @throws WxErrorException 接口调用失败抛出的异常 */ WxMpCardCreateResult createMemberCard(String createJson) throws WxErrorException; /** - * 会员卡创建接口. + * 会员卡创建接口 + * + * @param createMessageMessage 会员卡创建对象 + * @return 会员卡信息的结果对象 + * @throws WxErrorException 接口调用失败抛出的异常 */ WxMpCardCreateResult createMemberCard(WxMpMemberCardCreateMessage createMessageMessage) throws WxErrorException; @@ -61,7 +70,7 @@ public interface WxMpMemberCardService { * 会员卡激活接口. * * @param activatedMessage 激活所需参数 - * @return 返回json字符串 + * @return 会员卡激活后的json字符串 * @throws WxErrorException 接口调用失败抛出的异常 */ String activateMemberCard(WxMpMemberCardActivatedMessage activatedMessage) throws WxErrorException; @@ -91,16 +100,40 @@ public interface WxMpMemberCardService { /** * 设置会员卡激活的字段(会员卡设置:wx_activate=true 时需要). + * + * @param userFormRequest 会员卡激活字段对象 + * @return 会员卡激活后结果对象 + * @throws WxErrorException 接口调用失败抛出的异常 */ MemberCardActivateUserFormResult setActivateUserForm(MemberCardActivateUserFormRequest userFormRequest) throws WxErrorException; /** * 获取会员卡开卡插件参数(跳转型开卡组件需要参数). + * + * @param cardId 会员卡的CardId,微信分配 + * @param outStr 会员卡设置商户的渠道 + * @return 会员卡开卡插件参数结果对象 + * @throws WxErrorException 接口调用失败抛出的异常 */ ActivatePluginParam getActivatePluginParam(String cardId, String outStr) throws WxErrorException; /** * 更新会员卡信息. + * + * @param memberCardUpdateRequest 会员卡更新对象 + * @return 会员卡更新后结果对象 + * @throws WxErrorException 接口调用失败抛出的异常 */ CardUpdateResult updateCardInfo(MemberCardUpdateRequest memberCardUpdateRequest) throws WxErrorException; + + /** + * 解析跳转型开卡字段用户提交的资料 + * 开发者在URL上截取ticket后须先进行urldecode + * + * @param activateTicket 用户提交的资料 + * @return 开卡字段的会员信息对象 + * @throws WxErrorException 接口调用失败抛出的异常 + */ + WxMpMemberCardActivateTempInfoResult getActivateTempInfo(String activateTicket) throws WxErrorException; + } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java index d0a1c347bc..6e4143baa7 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java @@ -5,6 +5,7 @@ import java.util.HashMap; import java.util.Map; +import me.chanjar.weixin.mp.bean.membercard.*; import org.apache.commons.lang3.StringUtils; import com.google.gson.Gson; @@ -30,13 +31,6 @@ import me.chanjar.weixin.mp.bean.card.enums.BusinessServiceType; import me.chanjar.weixin.mp.bean.card.enums.CardColor; import me.chanjar.weixin.mp.bean.card.enums.DateInfoType; -import me.chanjar.weixin.mp.bean.membercard.ActivatePluginParam; -import me.chanjar.weixin.mp.bean.membercard.ActivatePluginParamResult; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardActivatedMessage; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardCreateMessage; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUpdateMessage; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUpdateResult; -import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUserInfoResult; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; /** @@ -284,6 +278,15 @@ public CardUpdateResult updateCardInfo(MemberCardUpdateRequest memberCardUpdateR return result; } + @Override + public WxMpMemberCardActivateTempInfoResult getActivateTempInfo(String activateTicket) throws WxErrorException { + JsonObject params = new JsonObject(); + params.addProperty("activate_ticket", activateTicket); + String response = this.wxMpService.post(MEMBER_CARD_ACTIVATE_TEMP_INFO, GSON.toJson(params)); + WxMpMemberCardActivateTempInfoResult result = GSON.fromJson(response, WxMpMemberCardActivateTempInfoResult.class); + return result; + } + private static String truncateUrlPage(String strURL) { String strAllParam = null; String[] arrSplit; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardActivateTempInfoResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardActivateTempInfoResult.java new file mode 100644 index 0000000000..120e326701 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/membercard/WxMpMemberCardActivateTempInfoResult.java @@ -0,0 +1,24 @@ +package me.chanjar.weixin.mp.bean.membercard; + +import lombok.Data; +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + + +/** + * @author thomas + * @date 2019/4/26 + */ +@Data +public class WxMpMemberCardActivateTempInfoResult { + + private String errorCode; + + private String errorMsg; + + private MemberCardUserInfo userInfo; + + public static WxMpMemberCardActivateTempInfoResult fromJson(String json) { + return WxMpGsonBuilder.create().fromJson(json, WxMpMemberCardActivateTempInfoResult.class); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java index e6a60c34b0..b16775b40b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java @@ -8,6 +8,7 @@ import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserCumulate; import me.chanjar.weixin.mp.bean.datacube.WxDataCubeUserSummary; import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; +import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardActivateTempInfoResult; import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUpdateResult; import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardUserInfoResult; import me.chanjar.weixin.mp.bean.material.*; @@ -58,6 +59,7 @@ public class WxMpGsonBuilder { INSTANCE.registerTypeAdapter(WxMpUserBlacklistGetResult.class, new WxUserBlacklistGetResultGsonAdapter()); INSTANCE.registerTypeAdapter(WxMpMemberCardUserInfoResult.class, new WxMpMemberCardUserInfoResultGsonAdapter()); INSTANCE.registerTypeAdapter(WxMpMemberCardUpdateResult.class, new WxMpMemberCardUpdateResultGsonAdapter()); + INSTANCE.registerTypeAdapter(WxMpMemberCardActivateTempInfoResult.class, new WxMpMemberCardActivateTempInfoResultGsonAdapter()); } public static Gson create() { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMemberCardActivateTempInfoResultGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMemberCardActivateTempInfoResultGsonAdapter.java new file mode 100644 index 0000000000..a38a27aa01 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpMemberCardActivateTempInfoResultGsonAdapter.java @@ -0,0 +1,65 @@ +package me.chanjar.weixin.mp.util.json; + +import com.google.gson.*; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.mp.bean.membercard.MemberCardUserInfo; +import me.chanjar.weixin.mp.bean.membercard.NameValues; +import me.chanjar.weixin.mp.bean.membercard.WxMpMemberCardActivateTempInfoResult; + +import java.lang.reflect.Type; + +/** + * Json to WxMpMemberCardActivateTempInfoResultGsonAdapter 的转换适配器 + * + * @author thomas(351402401 @ qq.com) + * @version 2019/4/26 + */ +public class WxMpMemberCardActivateTempInfoResultGsonAdapter implements JsonDeserializer { + + @Override + public WxMpMemberCardActivateTempInfoResult deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException { + WxMpMemberCardActivateTempInfoResult result = new WxMpMemberCardActivateTempInfoResult(); + + JsonObject jsonObject = jsonElement.getAsJsonObject(); + + result.setErrorCode(GsonHelper.getString(jsonObject, "errcode")); + result.setErrorMsg(GsonHelper.getString(jsonObject, "errmsg")); + + JsonObject userInfoJsonObject = jsonObject.getAsJsonObject("info"); + MemberCardUserInfo cardUserInfo = new MemberCardUserInfo(); + + JsonArray commonFieldListObj = userInfoJsonObject.getAsJsonArray("common_field_list"); + NameValues[] commonFieldListValues = new NameValues[commonFieldListObj.size()]; + for (int i = 0; i < commonFieldListObj.size(); i++) { + JsonObject commonField = commonFieldListObj.get(i).getAsJsonObject(); + NameValues commonNameValues = new NameValues(); + commonNameValues.setName(GsonHelper.getString(commonField, "name")); + commonNameValues.setValue(GsonHelper.getString(commonField, "value")); + commonFieldListValues[i] = commonNameValues; + } + cardUserInfo.setCommonFieldList(commonFieldListValues); + + JsonArray customFieldListObj = userInfoJsonObject.getAsJsonArray("custom_field_list"); + NameValues[] customFieldListValues = new NameValues[customFieldListObj.size()]; + for (int i = 0; i < customFieldListObj.size(); i++) { + JsonObject customField = customFieldListObj.get(i).getAsJsonObject(); + NameValues customNameValues = new NameValues(); + customNameValues.setName(GsonHelper.getString(customField, "name")); + customNameValues.setValue(GsonHelper.getString(customField, "value")); + + JsonArray valueListArray = customField.getAsJsonArray("value_list"); + String[] valueList = new String[valueListArray.size()]; + for (int j = 0; j < valueListArray.size(); j++) { + valueList[j] = valueListArray.get(j).getAsString(); + } + customNameValues.setValueList(valueList); + customFieldListValues[i] = customNameValues; + } + cardUserInfo.setCustomFieldList(customFieldListValues); + + result.setUserInfo(cardUserInfo); + + return result; + } + +} diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImplTest.java index fbdb7cea29..96eb671370 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImplTest.java @@ -23,9 +23,9 @@ public class WxMpMemberCardServiceImplTest { @Inject protected WxMpService wxService; - private String cardId = "p2iQk1uwOUYlzHm4s-UYdZnABW88"; - private String code = "435223630779"; - private String openId = "o2iQk1u5X-XIJkatmAK1Q8VVuS90"; + private String cardId = "p4p-v1bKn9tiQHxyO79aKmuTIZlQ"; + private String code = "224765120681"; + private String openId = "o4p-v1TIemEIpBSrSrTprkCaG6Xc"; @Test public void createMemberCard() throws Exception { @@ -150,6 +150,15 @@ public void testGetActivateUrl() throws Exception { WxMpMemberCardService memberCardService = this.wxService.getMemberCardService(); ActivatePluginParam response = memberCardService.getActivatePluginParam(cardId, "test"); System.out.println(response); + } + @Test + public void testGetActivateTempInfo() throws Exception { + String activateTicket = "fDZv9eMQAFfrNr3XBoqhb8eUX67DFb6h8yXDelGSMDLfg2OAIGQcU7mEKecnWZBK%2B%2Bvm%2FtZxZJrbRkdJB%2FUmpVoJkEsbeH%2BOefcntAsYDKA%3D"; + WxMpMemberCardService memberCardService = this.wxService.getMemberCardService(); + WxMpMemberCardActivateTempInfoResult result = memberCardService.getActivateTempInfo(activateTicket); + assertNotNull(result); + System.out.println(result); } + } From 49454655c66887dfb62b70d8430a96bd0b4621ee Mon Sep 17 00:00:00 2001 From: thomas2050 <37628237+thomas2050@users.noreply.github.com> Date: Thu, 9 May 2019 11:55:23 +0800 Subject: [PATCH 65/81] =?UTF-8?q?#1037=20=E4=BF=AE=E5=A4=8D=E9=80=9A?= =?UTF-8?q?=E8=AE=AF=E5=BD=95=E5=8F=98=E6=9B=B4=E4=BA=8B=E4=BB=B6ExtAttr?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E6=8A=A5=E9=94=99=EF=BC=8C=E5=B9=B6=E8=A1=A5?= =?UTF-8?q?=E5=85=85Address=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 新增跳转型会员卡,用户提交资料的信息参数解析 * 修复通讯录变更事件ExtAttr解析报错,并补充Address属性 --- .../weixin/cp/bean/WxCpXmlMessage.java | 15 ++++++++- .../weixin/cp/bean/WxCpXmlMessageTest.java | 32 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java index 90d67b07bc..5a6a05293b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java @@ -8,6 +8,7 @@ import java.util.List; import java.util.Map; +import com.thoughtworks.xstream.annotations.XStreamImplicit; import org.apache.commons.io.IOUtils; import com.thoughtworks.xstream.annotations.XStreamAlias; @@ -247,6 +248,13 @@ public class WxCpXmlMessage implements Serializable { @XStreamConverter(value = XStreamCDataConverter.class) private String telephone; + /** + * 地址. + */ + @XStreamAlias("Address") + @XStreamConverter(value = XStreamCDataConverter.class) + private String address; + /** * 扩展属性. */ @@ -327,17 +335,20 @@ public class WxCpXmlMessage implements Serializable { */ @XStreamAlias("TotalCount") private Integer totalCount; + /** * 过滤. * (过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数,原则上,filterCount = sentCount + errorCount */ @XStreamAlias("FilterCount") private Integer filterCount; + /** * 发送成功的粉丝数. */ @XStreamAlias("SentCount") private Integer sentCount; + /** * 发送失败的粉丝数. */ @@ -411,9 +422,11 @@ public static class ScanCodeInfo { @Data public static class ExtAttr { - @XStreamAlias("Item") + + @XStreamImplicit(itemFieldName = "Item") protected final List items = new ArrayList<>(); + @XStreamAlias("Item") @Data public static class Item { @XStreamAlias("Name") diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java index 68c57c3d89..aaf4032427 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java @@ -117,4 +117,36 @@ public void testSendPicsInfo() { assertEquals(wxMessage.getSendPicsInfo().getPicList().get(0).getPicMd5Sum(), "aef52ae501537e552725c5d7f99c1741"); assertEquals(wxMessage.getSendPicsInfo().getPicList().get(1).getPicMd5Sum(), "c4564632a4fab91378c39bea6aad6f9e"); } + + public void testExtAttr() { + + String xml = "" + + " " + + " " + + " 1557241961" + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + " " + + "
" + + "
"; + WxCpXmlMessage wxMessage = WxCpXmlMessage.fromXml(xml); + assertEquals(wxMessage.getToUserName(), "w56c9fe3d50ad1ea2"); + assertEquals(wxMessage.getFromUserName(), "sys"); + assertEquals(wxMessage.getCreateTime(), new Long(1557241961)); + assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.EVENT); + assertEquals(wxMessage.getEvent(), "change_contact"); + assertEquals(wxMessage.getChangeType(), "update_user"); + assertEquals(wxMessage.getUserId(), "zhangsan"); + assertNotNull(wxMessage.getExtAttrs()); + assertNotNull(wxMessage.getExtAttrs().getItems()); + assertEquals(wxMessage.getExtAttrs().getItems().size(), 3); + assertEquals(wxMessage.getExtAttrs().getItems().get(0).getName(), "爱好"); + + } } From 467e33dc71f5be53e9695f1c52da2d0bc41fc7e6 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 9 May 2019 23:21:58 +0800 Subject: [PATCH 66/81] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=AE=98=E6=96=B9=E6=96=87=E6=A1=A3=E5=9C=B0?= =?UTF-8?q?=E5=9D=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/binarywang/wx/miniapp/api/WxMaMsgService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaMsgService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaMsgService.java index a838417e23..f0dbccd81a 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaMsgService.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaMsgService.java @@ -20,7 +20,7 @@ public interface WxMaMsgService { /** *
    * 发送客服消息
-   * 详情请见: 发送客服消息
+   * 详情请见: 发送客服消息
    * 接口url格式:https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN
    * 
*/ @@ -29,7 +29,7 @@ public interface WxMaMsgService { /** *
    * 发送模板消息
-   * 详情请见: 发送模板消息
+   * 详情请见: 发送模板消息
    * 接口url格式:https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN
    * 
*/ From 2dfcd6acaa3f72d7a6e0136e9ff02888e5c3ab1d Mon Sep 17 00:00:00 2001 From: Mario Luo Date: Fri, 10 May 2019 14:48:22 +0800 Subject: [PATCH 67/81] =?UTF-8?q?#1040=20=E5=A2=9E=E5=8A=A0=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E5=85=AC=E4=BC=97=E5=8F=B7=E6=A8=A1=E5=9D=97=E7=9A=84?= =?UTF-8?q?spring-boot-starter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 1 + starters/wx-java-mp-starter/README.md | 32 +++++++ starters/wx-java-mp-starter/pom.xml | 69 +++++++++++++++ .../starter/wxjava/mp/RedisProperties.java | 42 ++++++++++ .../wxjava/mp/WxMpAutoConfiguration.java | 11 +++ .../starter/wxjava/mp/WxMpProperties.java | 58 +++++++++++++ .../mp/WxMpServiceAutoConfiguration.java | 53 ++++++++++++ .../mp/WxMpStorageAutoConfiguration.java | 84 +++++++++++++++++++ .../main/resources/META-INF/spring.factories | 1 + 9 files changed, 351 insertions(+) create mode 100644 starters/wx-java-mp-starter/README.md create mode 100644 starters/wx-java-mp-starter/pom.xml create mode 100644 starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/RedisProperties.java create mode 100644 starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/WxMpAutoConfiguration.java create mode 100644 starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/WxMpProperties.java create mode 100644 starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/WxMpServiceAutoConfiguration.java create mode 100644 starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/WxMpStorageAutoConfiguration.java create mode 100644 starters/wx-java-mp-starter/src/main/resources/META-INF/spring.factories diff --git a/pom.xml b/pom.xml index 7843d0444a..6432bd3eb4 100644 --- a/pom.xml +++ b/pom.xml @@ -106,6 +106,7 @@ weixin-java-miniapp weixin-java-open starters/wx-java-pay-starter + starters/wx-java-mp-starter diff --git a/starters/wx-java-mp-starter/README.md b/starters/wx-java-mp-starter/README.md new file mode 100644 index 0000000000..d8e1010322 --- /dev/null +++ b/starters/wx-java-mp-starter/README.md @@ -0,0 +1,32 @@ +# wx-java-mp-starter +## 快速开始 +1. 引入依赖 + ```xml + + com.github.binarywang + wx-java-mp-starter + ${version} + + ``` +2. 添加配置(application.properties) + ```properties + # 公众号配置(必填) + wx.mp.appId = @appId + wx.mp.secret = @secret + wx.mp.token = @token + wx.mp.aesKey = @aesKey + # 存储配置redis(可选) + wx.mp.config-storage.type = redis + wx.mp.config-storage.redis.host = 127.0.0.1 + wx.mp.config-storage.redis.port = 6379 + ``` +3. 支持自动注入的类型 + +`WxMpService`以及相关的服务类, 比如: `wxMpService.getXxxService`。 + + + + + + + diff --git a/starters/wx-java-mp-starter/pom.xml b/starters/wx-java-mp-starter/pom.xml new file mode 100644 index 0000000000..d5ce48eda5 --- /dev/null +++ b/starters/wx-java-mp-starter/pom.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + + com.github.binarywang + wx-java + 3.3.8.B + + + wx-java-mp-starter + + + 2.1.4.RELEASE + + + + + org.springframework.boot + spring-boot-autoconfigure + ${spring.boot.version} + + + org.springframework.boot + spring-boot-configuration-processor + ${spring.boot.version} + true + + + com.github.binarywang + weixin-java-mp + ${project.version} + + + redis.clients + jedis + + + org.projectlombok + lombok + provided + + + + + + + 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/starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/RedisProperties.java b/starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/RedisProperties.java new file mode 100644 index 0000000000..d609cc88c1 --- /dev/null +++ b/starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/RedisProperties.java @@ -0,0 +1,42 @@ +package com.binarywang.spring.starter.wxjava.mp; + +import lombok.Data; + +import java.io.Serializable; + +/** + * Redis配置 + */ +@Data +public class RedisProperties implements Serializable { + + /** + * 主机地址 + */ + private String host = "127.0.0.1"; + + /** + * 端口号 + */ + private int port = 6379; + + /** + * 密码 + */ + private String password; + + /** + * 超时 + */ + private int timeout = 2000; + + /** + * 数据库 + */ + private int database = 0; + + private Integer maxActive; + private Integer maxIdle; + private Integer maxWaitMillis; + private Integer minIdle; +} \ No newline at end of file diff --git a/starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/WxMpAutoConfiguration.java b/starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/WxMpAutoConfiguration.java new file mode 100644 index 0000000000..ba85d04482 --- /dev/null +++ b/starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/WxMpAutoConfiguration.java @@ -0,0 +1,11 @@ +package com.binarywang.spring.starter.wxjava.mp; + +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; + +@Configuration +@EnableConfigurationProperties(WxMpProperties.class) +@Import({WxMpStorageAutoConfiguration.class, WxMpServiceAutoConfiguration.class}) +public class WxMpAutoConfiguration { +} diff --git a/starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/WxMpProperties.java b/starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/WxMpProperties.java new file mode 100644 index 0000000000..af74f430ed --- /dev/null +++ b/starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/WxMpProperties.java @@ -0,0 +1,58 @@ +package com.binarywang.spring.starter.wxjava.mp; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +import java.io.Serializable; + +import static com.binarywang.spring.starter.wxjava.mp.WxMpProperties.PREFIX; +import static com.binarywang.spring.starter.wxjava.mp.WxMpProperties.StorageType.memory; + + +/** + * 微信接入相关配置属性 + */ +@Data +@ConfigurationProperties(PREFIX) +public class WxMpProperties { + public static final String PREFIX = "wx.mp"; + + /** + * 设置微信公众号的appid + */ + private String appId; + + /** + * 设置微信公众号的app secret + */ + private String secret; + + /** + * 设置微信公众号的token + */ + private String token; + + /** + * 设置微信公众号的EncodingAESKey + */ + private String aesKey; + + /** + * 存储策略, memory, redis + */ + private ConfigStorage configStorage = new ConfigStorage(); + + + @Data + public static class ConfigStorage implements Serializable { + + private StorageType type = memory; + + private RedisProperties redis = new RedisProperties(); + + } + + public enum StorageType { + memory, redis + } +} diff --git a/starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/WxMpServiceAutoConfiguration.java b/starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/WxMpServiceAutoConfiguration.java new file mode 100644 index 0000000000..7a6cf920c4 --- /dev/null +++ b/starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/WxMpServiceAutoConfiguration.java @@ -0,0 +1,53 @@ +package com.binarywang.spring.starter.wxjava.mp; + +import me.chanjar.weixin.mp.api.WxMpConfigStorage; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * 微信公众号相关服务自动注册 + */ +@Configuration +public class WxMpServiceAutoConfiguration { + @Autowired + private ApplicationContext ctx; + + @Bean + @ConditionalOnMissingBean + public WxMpService wxMpService(WxMpConfigStorage configStorage) { + WxMpService wxMpService = new WxMpServiceImpl(); + wxMpService.setWxMpConfigStorage(configStorage); + registerWxMpSubService(wxMpService); + return wxMpService; + } + + @ConditionalOnBean(WxMpService.class) + public Object registerWxMpSubService(WxMpService wxMpService) { + ConfigurableListableBeanFactory factory = (ConfigurableListableBeanFactory) ctx.getAutowireCapableBeanFactory(); + factory.registerSingleton("wxMpKefuService", wxMpService.getKefuService()); + factory.registerSingleton("wxMpMaterialService", wxMpService.getMaterialService()); + factory.registerSingleton("wxMpMenuService", wxMpService.getMenuService()); + factory.registerSingleton("wxMpUserService", wxMpService.getUserService()); + factory.registerSingleton("wxMpUserTagService", wxMpService.getUserTagService()); + factory.registerSingleton("wxMpQrcodeService", wxMpService.getQrcodeService()); + factory.registerSingleton("wxMpCardService", wxMpService.getCardService()); + factory.registerSingleton("wxMpDataCubeService", wxMpService.getDataCubeService()); + factory.registerSingleton("wxMpUserBlacklistService", wxMpService.getBlackListService()); + factory.registerSingleton("wxMpStoreService", wxMpService.getStoreService()); + factory.registerSingleton("wxMpTemplateMsgService", wxMpService.getTemplateMsgService()); + factory.registerSingleton("wxMpSubscribeMsgService", wxMpService.getSubscribeMsgService()); + factory.registerSingleton("wxMpDeviceService", wxMpService.getDeviceService()); + factory.registerSingleton("wxMpShakeService", wxMpService.getShakeService()); + factory.registerSingleton("wxMpMemberCardService", wxMpService.getMemberCardService()); + factory.registerSingleton("wxMpMassMessageService", wxMpService.getMassMessageService()); + return Boolean.TRUE; + } + +} diff --git a/starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/WxMpStorageAutoConfiguration.java b/starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/WxMpStorageAutoConfiguration.java new file mode 100644 index 0000000000..a0fb7eb3d5 --- /dev/null +++ b/starters/wx-java-mp-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/WxMpStorageAutoConfiguration.java @@ -0,0 +1,84 @@ +package com.binarywang.spring.starter.wxjava.mp; + +import me.chanjar.weixin.mp.api.WxMpConfigStorage; +import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage; +import me.chanjar.weixin.mp.api.WxMpInRedisConfigStorage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import redis.clients.jedis.JedisPool; +import redis.clients.jedis.JedisPoolConfig; + +/** + * 微信公众号存储策略自动配置 + */ +@Configuration +public class WxMpStorageAutoConfiguration { + + @Autowired + private WxMpProperties properties; + + @Autowired(required = false) + private JedisPool jedisPool; + + @Bean + @ConditionalOnMissingBean(WxMpConfigStorage.class) + public WxMpConfigStorage wxMpInMemoryConfigStorage() { + WxMpProperties.ConfigStorage storage = properties.getConfigStorage(); + WxMpProperties.StorageType type = storage.getType(); + + if (type == WxMpProperties.StorageType.redis) { + return getWxMpInRedisConfigStorage(); + } + return getWxMpInMemoryConfigStorage(); + } + + private WxMpInMemoryConfigStorage getWxMpInMemoryConfigStorage() { + WxMpInMemoryConfigStorage config = new WxMpInMemoryConfigStorage(); + setWxMpInfo(config); + return config; + } + + private WxMpInRedisConfigStorage getWxMpInRedisConfigStorage() { + JedisPool poolToUse = jedisPool; + if (poolToUse == null) { + poolToUse = getJedisPool(); + } + WxMpInRedisConfigStorage config = new WxMpInRedisConfigStorage(poolToUse); + setWxMpInfo(config); + return config; + } + + private void setWxMpInfo(WxMpInMemoryConfigStorage config) { + config.setAppId(properties.getAppId()); + config.setSecret(properties.getSecret()); + config.setToken(properties.getToken()); + config.setAesKey(properties.getAesKey()); + } + + private JedisPool getJedisPool() { + WxMpProperties.ConfigStorage storage = properties.getConfigStorage(); + RedisProperties redis = storage.getRedis(); + + JedisPoolConfig config = new JedisPoolConfig(); + if (redis.getMaxActive() != null) { + config.setMaxTotal(redis.getMaxActive()); + } + if (redis.getMaxIdle() != null) { + config.setMaxIdle(redis.getMaxIdle()); + } + if (redis.getMaxWaitMillis() != null) { + config.setMaxWaitMillis(redis.getMaxWaitMillis()); + } + if (redis.getMinIdle() != null) { + config.setMinIdle(redis.getMinIdle()); + } + config.setTestOnBorrow(true); + config.setTestWhileIdle(true); + + JedisPool pool = new JedisPool(config, redis.getHost(), redis.getPort(), + redis.getTimeout(), redis.getPassword(), redis.getDatabase()); + return pool; + } +} diff --git a/starters/wx-java-mp-starter/src/main/resources/META-INF/spring.factories b/starters/wx-java-mp-starter/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..aaa17f7676 --- /dev/null +++ b/starters/wx-java-mp-starter/src/main/resources/META-INF/spring.factories @@ -0,0 +1 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.binarywang.spring.starter.wxjava.mp.WxMpAutoConfiguration \ No newline at end of file From cf78cd52d2879b3bf00cd6ece02c8927cda649ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E5=9B=A0=E6=96=AF=E5=94=90?= Date: Sun, 12 May 2019 12:03:14 +0800 Subject: [PATCH 68/81] =?UTF-8?q?#698=20=E4=BC=81=E4=B8=9A=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E5=A2=9E=E5=8A=A0OA=E6=95=B0=E6=8D=AE=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/cp/api/WxCpChatService.java | 15 ++ .../chanjar/weixin/cp/api/WxCpOAService.java | 66 +++++++ .../me/chanjar/weixin/cp/api/WxCpService.java | 2 + .../cp/api/impl/BaseWxCpServiceImpl.java | 6 + .../cp/api/impl/WxCpChatServiceImpl.java | 26 ++- .../weixin/cp/api/impl/WxCpOAServiceImpl.java | 165 ++++++++++++++++++ .../impl/WxCpServiceApacheHttpClientImpl.java | 1 + .../cp/bean/WxCpApprovalDataResult.java | 69 ++++++++ .../weixin/cp/bean/WxCpCheckinData.java | 51 ++++++ .../weixin/cp/bean/WxCpCheckinOption.java | 151 ++++++++++++++++ .../weixin/cp/bean/WxCpDialRecord.java | 73 ++++++++ .../cp/api/impl/WxCpOAServiceImplTest.java | 67 +++++++ 12 files changed, 686 insertions(+), 6 deletions(-) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAService.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAServiceImpl.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpApprovalDataResult.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpCheckinData.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpCheckinOption.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDialRecord.java create mode 100644 weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAServiceImplTest.java diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java index a9a7cfe7f3..95f747e356 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpChatService.java @@ -28,6 +28,11 @@ public interface WxCpChatService { */ String chatCreate(String name, String owner, List users, String chatId) throws WxErrorException; + /** + * chatCreate 同名方法 + */ + String create(String name, String owner, List users, String chatId) throws WxErrorException; + /** * 修改群聊会话. * @@ -40,6 +45,11 @@ public interface WxCpChatService { */ void chatUpdate(String chatId, String name, String owner, List usersToAdd, List usersToDelete) throws WxErrorException; + /** + * chatUpdate 同名方法 + */ + void update(String chatId, String name, String owner, List usersToAdd, List usersToDelete) throws WxErrorException; + /** * 获取群聊会话. * @@ -49,6 +59,11 @@ public interface WxCpChatService { */ WxCpChat chatGet(String chatId) throws WxErrorException; + /** + * chatGet 同名方法 + */ + WxCpChat get(String chatId) throws WxErrorException; + /** * 应用支持推送文本、图片、视频、文件、图文等类型. * 请求方式: POST(HTTPS) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAService.java new file mode 100644 index 0000000000..e8cf874eb6 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpOAService.java @@ -0,0 +1,66 @@ +package me.chanjar.weixin.cp.api; + +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.bean.WxCpApprovalDataResult; +import me.chanjar.weixin.cp.bean.WxCpCheckinData; +import me.chanjar.weixin.cp.bean.WxCpCheckinOption; +import me.chanjar.weixin.cp.bean.WxCpDialRecord; + +import java.util.Date; +import java.util.List; + +/** + * @author Element + * @Package me.chanjar.weixin.cp.api + * @date 2019-04-06 10:52 + * @Description:
+ *     企业微信OA相关接口
+ *
+ * 
+ */ +public interface WxCpOAService { + + /** + *
+   *     获取打卡数据
+   *     API doc : https://work.weixin.qq.com/api/doc#90000/90135/90262
+   * 
+ * + * @param openCheckinDataType 打卡类型。1:上下班打卡;2:外出打卡;3:全部打卡 + * @param starttime 获取打卡记录的开始时间 + * @param endtime 获取打卡记录的结束时间 + * @param userIdList 需要获取打卡记录的用户列表 + */ + List getCheckinData(Integer openCheckinDataType, Date starttime, Date endtime, List userIdList) throws WxErrorException; + + /** + *
+   *     获取打卡规则
+   *     API doc : https://work.weixin.qq.com/api/doc#90000/90135/90263
+   * 
+ * + * @param datetime 需要获取规则的当天日期 + * @param userIdList 需要获取打卡规则的用户列表 + * @return + * @throws WxErrorException + */ + List getCheckinOption(Date datetime, List userIdList) throws WxErrorException; + + /** + *
+   *     获取审批数据
+   *     通过本接口来获取公司一段时间内的审批记录。一次拉取调用最多拉取10000个审批记录,可以通过多次拉取的方式来满足需求,但调用频率不可超过600次/分。
+   *     API doc : https://work.weixin.qq.com/api/doc#90000/90135/91530
+   * 
+ * + * @param starttime 获取审批记录的开始时间 + * @param endtime 获取审批记录的结束时间 + * @param nextSpnum 第一个拉取的审批单号,不填从该时间段的第一个审批单拉取 + * @return + * @throws WxErrorException + */ + WxCpApprovalDataResult getApprovalData(Date starttime, Date endtime, Long nextSpnum) throws WxErrorException; + + List getDialRecord(Date starttime, Date endtime, Integer offset, Integer limit) throws WxErrorException; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java index 927b79cbd5..732c1449ee 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java @@ -303,6 +303,8 @@ public interface WxCpService { WxCpAgentService getAgentService(); + WxCpOAService getOAService(); + /** * http请求对象 */ diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java index f9a146e8f7..161c747c69 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java @@ -45,6 +45,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH private WxCpOAuth2Service oauth2Service = new WxCpOAuth2ServiceImpl(this); private WxCpTagService tagService = new WxCpTagServiceImpl(this); private WxCpAgentService agentService = new WxCpAgentServiceImpl(this); + private WxCpOAService oaService = new WxCpOAServiceImpl(this); /** * 全局的是否正在刷新access token的锁 @@ -386,6 +387,11 @@ public WxCpChatService getChatService() { return chatService; } + @Override + public WxCpOAService getOAService() { + return oaService; + } + @Override public RequestHttp getRequestHttp() { return this; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java index 96e842adbc..05d298c9ad 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImpl.java @@ -1,11 +1,5 @@ package me.chanjar.weixin.cp.api.impl; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; - import com.google.gson.JsonParser; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.json.WxGsonBuilder; @@ -14,6 +8,11 @@ import me.chanjar.weixin.cp.bean.WxCpAppChatMessage; import me.chanjar.weixin.cp.bean.WxCpChat; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; +import org.apache.commons.lang3.StringUtils; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * 群聊服务实现. @@ -52,6 +51,11 @@ public String chatCreate(String name, String owner, List users, String c return new JsonParser().parse(result).getAsJsonObject().get("chatid").getAsString(); } + @Override + public String create(String name, String owner, List users, String chatId) throws WxErrorException { + return chatCreate(name, owner, users, chatId); + } + @Override public void chatUpdate(String chatId, String name, String owner, List usersToAdd, List usersToDelete) throws WxErrorException { @@ -75,6 +79,11 @@ public void chatUpdate(String chatId, String name, String owner, List us this.cpService.post(APPCHAT_UPDATE, WxGsonBuilder.create().toJson(data)); } + @Override + public void update(String chatId, String name, String owner, List usersToAdd, List usersToDelete) throws WxErrorException { + chatUpdate(chatId, name, owner, usersToAdd, usersToDelete); + } + @Override public WxCpChat chatGet(String chatId) throws WxErrorException { String result = this.cpService.get(APPCHAT_GET_CHATID + chatId, null); @@ -82,6 +91,11 @@ public WxCpChat chatGet(String chatId) throws WxErrorException { .fromJson(JSON_PARSER.parse(result).getAsJsonObject().getAsJsonObject("chat_info").toString(), WxCpChat.class); } + @Override + public WxCpChat get(String chatId) throws WxErrorException { + return chatGet(chatId); + } + @Override public void sendMsg(WxCpAppChatMessage message) throws WxErrorException { this.cpService.post("https://qyapi.weixin.qq.com/cgi-bin/appchat/send", message.toJson()); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAServiceImpl.java new file mode 100644 index 0000000000..2d1ca6ab0b --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOAServiceImpl.java @@ -0,0 +1,165 @@ +package me.chanjar.weixin.cp.api.impl; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.cp.api.WxCpOAService; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.bean.WxCpApprovalDataResult; +import me.chanjar.weixin.cp.bean.WxCpCheckinData; +import me.chanjar.weixin.cp.bean.WxCpCheckinOption; +import me.chanjar.weixin.cp.bean.WxCpDialRecord; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.util.Date; +import java.util.List; + +/** + * @author Element + * @Package me.chanjar.weixin.cp.api.impl + * @date 2019-04-06 11:20 + * @Description: TODO + */ +public class WxCpOAServiceImpl implements WxCpOAService { + + private WxCpService mainService; + + public WxCpOAServiceImpl(WxCpService mainService) { + this.mainService = mainService; + } + + @Override + public List getCheckinData(Integer openCheckinDataType, Date starttime, Date endtime, List userIdList) throws WxErrorException { + + if (starttime == null || endtime == null) { + throw new RuntimeException("starttime and endtime can't be null"); + } + + if (userIdList == null || userIdList.size() > 100) { + throw new RuntimeException("用户列表不能为空,不超过100个,若用户超过100个,请分批获取"); + } + + long endtimestamp = endtime.getTime() / 1000L; + long starttimestamp = starttime.getTime() / 1000L; + + if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= 30 * 24 * 60 * 60) { + throw new RuntimeException("获取记录时间跨度不超过一个月"); + } + + String url = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckindata"; + + JsonObject jsonObject = new JsonObject(); + JsonArray jsonArray = new JsonArray(); + + jsonObject.addProperty("opencheckindatatype", openCheckinDataType); + jsonObject.addProperty("starttime", starttimestamp); + jsonObject.addProperty("endtime", endtimestamp); + + for (String userid : userIdList) { + jsonArray.add(userid); + } + + jsonObject.add("useridlist", jsonArray); + + String responseContent = this.mainService.post(url, jsonObject.toString()); + JsonElement tmpJsonElement = new JsonParser().parse(responseContent); + return WxCpGsonBuilder.create() + .fromJson( + tmpJsonElement.getAsJsonObject().get("checkindata"), + new TypeToken>() { + }.getType() + ); + } + + @Override + public List getCheckinOption(Date datetime, List userIdList) throws WxErrorException { + String url = "https://qyapi.weixin.qq.com/cgi-bin/checkin/getcheckinoption"; + if (datetime == null) { + throw new RuntimeException("datetime can't be null"); + } + + if (userIdList == null || userIdList.size() > 100) { + throw new RuntimeException("用户列表不能为空,不超过100个,若用户超过100个,请分批获取"); + } + + JsonArray jsonArray = new JsonArray(); + for (String userid : userIdList) { + jsonArray.add(userid); + } + + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("datetime", datetime.getTime() / 1000L); + jsonObject.add("useridlist", jsonArray); + + String responseContent = this.mainService.post(url, jsonObject.toString()); + JsonElement tmpJsonElement = new JsonParser().parse(responseContent); + + return WxCpGsonBuilder.create() + .fromJson( + tmpJsonElement.getAsJsonObject().get("info"), + new TypeToken>() { + }.getType() + ); + } + + @Override + public WxCpApprovalDataResult getApprovalData(Date starttime, Date endtime, Long nextSpnum) throws WxErrorException { + + String url = "https://qyapi.weixin.qq.com/cgi-bin/corp/getapprovaldata"; + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("starttime", starttime.getTime() / 1000L); + jsonObject.addProperty("endtime", endtime.getTime() / 1000L); + if (nextSpnum != null) { + jsonObject.addProperty("next_spnum", nextSpnum); + } + + String responseContent = this.mainService.post(url, jsonObject.toString()); + return WxCpGsonBuilder.create().fromJson(responseContent, WxCpApprovalDataResult.class); + } + + @Override + public List getDialRecord(Date starttime, Date endtime, Integer offset, Integer limit) throws WxErrorException { + + String url = "https://qyapi.weixin.qq.com/cgi-bin/dial/get_dial_record"; + JsonObject jsonObject = new JsonObject(); + + if (offset == null) { + offset = 0; + } + + if (limit == null || limit <= 0) { + limit = 100; + } + + jsonObject.addProperty("offset", offset); + jsonObject.addProperty("limit", limit); + + if (starttime != null && endtime != null) { + + long endtimestamp = endtime.getTime() / 1000L; + long starttimestamp = starttime.getTime() / 1000L; + + if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= 30 * 24 * 60 * 60) { + throw new RuntimeException("受限于网络传输,起止时间的最大跨度为30天,如超过30天,则以结束时间为基准向前取30天进行查询"); + } + + jsonObject.addProperty("start_time", starttimestamp); + jsonObject.addProperty("end_time", endtimestamp); + + + } + + String responseContent = this.mainService.post(url, jsonObject.toString()); + JsonElement tmpJsonElement = new JsonParser().parse(responseContent); + + return WxCpGsonBuilder.create() + .fromJson( + tmpJsonElement.getAsJsonObject().get("record"), + new TypeToken>() { + }.getType() + ); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java index eedb0419a3..86e237168d 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceApacheHttpClientImpl.java @@ -8,6 +8,7 @@ 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.cp.api.WxCpOAService; import me.chanjar.weixin.cp.config.WxCpConfigStorage; 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/bean/WxCpApprovalDataResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpApprovalDataResult.java new file mode 100644 index 0000000000..3e1299e92b --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpApprovalDataResult.java @@ -0,0 +1,69 @@ +package me.chanjar.weixin.cp.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.Map; + +/** + * @author Element + * @Package me.chanjar.weixin.cp.bean + * @date 2019-04-06 14:36 + * @Description: 企业微信 OA 审批数据 + */ +@Data +public class WxCpApprovalDataResult implements Serializable { + private static final long serialVersionUID = -1046940445840716590L; + + @SerializedName("errcode") + private Integer errCode; + + @SerializedName("errmsg") + private String errMsg; + + private Integer count; + + private Integer total; + + @SerializedName("next_spnum") + private Long nextSpnum; + + private WxCpApprovalData[] data; + + + @Data + public static class WxCpApprovalData implements Serializable{ + + private static final long serialVersionUID = -3051785319608491640L; + + private String spname; + + @SerializedName("apply_name") + private String applyName; + + @SerializedName("apply_org") + private String applyOrg; + + @SerializedName("approval_name") + private String[] approvalName; + + @SerializedName("notify_name") + private String[] notifyName; + + @SerializedName("sp_status") + private Integer spStatus; + + @SerializedName("sp_num") + private Long spNum; + + @SerializedName("apply_time") + private Long applyTime; + + @SerializedName("apply_user_id") + private String applyUserId; + + @SerializedName("comm") + private Map comm; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpCheckinData.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpCheckinData.java new file mode 100644 index 0000000000..369c771f98 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpCheckinData.java @@ -0,0 +1,51 @@ +package me.chanjar.weixin.cp.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author Element + * @Package me.chanjar.weixin.cp.bean + * @date 2019-04-06 11:01 + * @Description: 企业微信打卡数据 + */ +@Data +public class WxCpCheckinData implements Serializable { + + private static final long serialVersionUID = 1915820330847799605L; + + @SerializedName("userid") + private String userId; + + @SerializedName("groupname") + private String groupName; + + @SerializedName("checkin_type") + private String checkinType; + + @SerializedName("exception_type") + private String exceptionType; + + @SerializedName("checkin_time") + private Long checkinTime; + + @SerializedName("location_title") + private String locationTitle; + + @SerializedName("location_detail") + private String locationDetail; + + @SerializedName("wifiname") + private String wifiName; + + @SerializedName("wifimac") + private String wifiMAC; + + private String notes; + + @SerializedName("mediaids") + private List mediaIds; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpCheckinOption.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpCheckinOption.java new file mode 100644 index 0000000000..9cc3c389c7 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpCheckinOption.java @@ -0,0 +1,151 @@ +package me.chanjar.weixin.cp.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author Element + * @Package me.chanjar.weixin.cp.bean + * @date 2019-04-06 13:22 + * @Description: 企业微信打卡规则 + */ +@Data +public class WxCpCheckinOption implements Serializable { + private static final long serialVersionUID = -1964233697990417482L; + + @SerializedName("userid") + private String userId; + + private Group group; + + + @Data + public static class CheckinDate implements Serializable { + + private static final long serialVersionUID = -5601722383347110974L; + + private List workdays; + + @SerializedName("checkintime") + private CheckinTime[] checkinTime; + + @SerializedName("flex_time") + private Long flexTime; + + @SerializedName("noneed_offwork") + private Boolean noneedOffwork; + + @SerializedName("limit_aheadtime") + private Long limitAheadtime; + } + + @Data + public static class CheckinTime implements Serializable { + + private static final long serialVersionUID = -8579954143265336276L; + + @SerializedName("work_sec") + private Long workSec; + + @SerializedName("off_work_sec") + private Long offWorkSec; + + @SerializedName("remind_work_sec") + private Long remindWorkSec; + + @SerializedName("remind_off_work_sec") + private Long remindOffWorkSec; + } + + @Data + public static class Group implements Serializable { + + private static final long serialVersionUID = -5888406969613403044L; + + @SerializedName("groupid") + private Long id; + + @SerializedName("groupname") + private String name; + + @SerializedName("grouptype") + private Integer type; + + @SerializedName("checkindate") + private List checkinDate; + + @SerializedName("spe_workdays") + private List speWorkdays; + + @SerializedName("spe_offdays") + private List speOffdays; + + @SerializedName("sync_holidays") + private Boolean syncHolidays; + + @SerializedName("need_photo") + private Boolean needPhoto; + + @SerializedName("note_can_use_local_pic") + private Boolean note_can_use_local_pic; + + @SerializedName("allow_checkin_offworkday") + private Boolean allow_checkin_offworkday; + + @SerializedName("allow_apply_offworkday") + private Boolean allow_apply_offworkday; + + @SerializedName("wifimac_infos") + private List wifiMACInfos; + + @SerializedName("loc_infos") + private List locInfos; + + } + + @Data + public static class WifiMACInfo implements Serializable{ + + private static final long serialVersionUID = -4657809185716627368L; + + @SerializedName("wifiname") + private String name; + + @SerializedName("wifimac") + private String mac; + } + + @Data + public static class LocInfo implements Serializable{ + + private static final long serialVersionUID = -618965280668099608L; + + private Long lat; + private Long lng; + + @SerializedName("loc_title") + private String title; + + @SerializedName("loc_detail") + private String detail; + + private Long distance; + } + + @Data + public static class SpeDay implements Serializable{ + + private static final long serialVersionUID = -3538818921359212748L; + + private Long timestamp; + private String notes; + + @SerializedName("checkintime") + private List checkinTime; + + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDialRecord.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDialRecord.java new file mode 100644 index 0000000000..d8e40c79bd --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDialRecord.java @@ -0,0 +1,73 @@ +package me.chanjar.weixin.cp.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author Element + * @Package me.chanjar.weixin.cp.bean + * @date 2019-04-06 15:38 + * @Description: 公费电话拨打记录 + */ +@Data +public class WxCpDialRecord implements Serializable { + + private static final long serialVersionUID = 4178886812949929116L; + @SerializedName("call_time") + private Long callTime; + + /** + * 总通话时长,单位为分钟 + */ + @SerializedName("total_duration") + private Integer totalDuration; + + /** + * 通话类型,1-单人通话 2-多人通话 + */ + @SerializedName("call_type") + private Integer callType; + + private Caller caller; + + private List callee; + + /** + * 主叫信息 + */ + @Data + public static class Caller implements Serializable{ + + private static final long serialVersionUID = 4792200404338145607L; + + @SerializedName("userid") + private String userId; + + private Integer duration; + } + + /** + * 被叫信息 + */ + @Data + public static class Callee implements Serializable{ + + private static final long serialVersionUID = 2390963671336179550L; + + /** + * 被叫用户的userid,当被叫用户为企业内用户时返回 + */ + @SerializedName("userid") + private String userId; + + /** + * 被叫用户的号码,当被叫用户为外部用户时返回 + */ + private String phone; + + private Integer duration; + } +} diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAServiceImplTest.java new file mode 100644 index 0000000000..1dff536686 --- /dev/null +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAServiceImplTest.java @@ -0,0 +1,67 @@ +package me.chanjar.weixin.cp.api.impl; + +import com.google.gson.Gson; +import com.google.inject.Inject; +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.WxCpCheckinData; +import me.chanjar.weixin.cp.bean.WxCpCheckinOption; +import org.apache.commons.lang3.time.DateFormatUtils; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * @author Element + * @Package me.chanjar.weixin.cp.api.impl + * @date 2019-04-20 13:46 + * @Description: TODO + */ + +@Guice(modules = ApiTestModule.class) +public class WxCpOAServiceImplTest { + + @Inject + protected WxCpService wxService; + + @Inject + protected Gson gson; + + @Test + public void testGetCheckinData() throws ParseException, WxErrorException { + Date starttime,endtime; + List userLists = new ArrayList<>(); + + starttime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-01-01"); + endtime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-01-20"); + + userLists.add("1"); + userLists.add("2"); + userLists.add("3"); + + List results = wxService.getOAService().getCheckinData(1, starttime,endtime,userLists); + + System.out.println("results "); + System.out.println(gson.toJson(results)); + + } + + @Test + public void testGetCheckinOption() throws WxErrorException{ + + Date now = new Date(); + List userLists = new ArrayList<>(); + + userLists.add("user@aliyun.com"); + + List results = wxService.getOAService().getCheckinOption(now,userLists); + + System.out.println("results "); + System.out.println(gson.toJson(results)); + } +} From 0287fb565b53dec95bbd80cfa610c4f0940a1e87 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 12 May 2019 12:25:50 +0800 Subject: [PATCH 69/81] =?UTF-8?q?#698=20=E4=BC=81=E4=B8=9A=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1OA=E6=95=B0=E6=8D=AE=E6=8E=A5=E5=8F=A3=E5=8D=95?= =?UTF-8?q?=E5=85=83=E6=B5=8B=E8=AF=95=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cp/api/impl/WxCpOAServiceImplTest.java | 42 ++++++------------- 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAServiceImplTest.java index 1dff536686..9497a5626b 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAServiceImplTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpOAServiceImplTest.java @@ -1,5 +1,6 @@ package me.chanjar.weixin.cp.api.impl; +import com.google.common.collect.Lists; import com.google.gson.Gson; import com.google.inject.Inject; import me.chanjar.weixin.common.error.WxErrorException; @@ -16,52 +17,33 @@ import java.util.Date; import java.util.List; +import static org.assertj.core.api.Assertions.assertThat; + /** * @author Element - * @Package me.chanjar.weixin.cp.api.impl * @date 2019-04-20 13:46 - * @Description: TODO */ - @Guice(modules = ApiTestModule.class) public class WxCpOAServiceImplTest { - @Inject protected WxCpService wxService; - @Inject - protected Gson gson; - @Test public void testGetCheckinData() throws ParseException, WxErrorException { - Date starttime,endtime; - List userLists = new ArrayList<>(); - - starttime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-01-01"); - endtime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-01-20"); + Date startTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-04-11"); + Date endTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-05-10"); - userLists.add("1"); - userLists.add("2"); - userLists.add("3"); - - List results = wxService.getOAService().getCheckinData(1, starttime,endtime,userLists); - - System.out.println("results "); - System.out.println(gson.toJson(results)); + List results = wxService.getOAService() + .getCheckinData(1, startTime, endTime, Lists.newArrayList("binary")); + assertThat(results).isNotNull(); } @Test - public void testGetCheckinOption() throws WxErrorException{ - + public void testGetCheckinOption() throws WxErrorException { Date now = new Date(); - List userLists = new ArrayList<>(); - - userLists.add("user@aliyun.com"); - - List results = wxService.getOAService().getCheckinOption(now,userLists); - - System.out.println("results "); - System.out.println(gson.toJson(results)); + List results = wxService.getOAService() + .getCheckinOption(now, Lists.newArrayList("binary")); + assertThat(results).isNotNull(); } } From 03a88aab8e57ebb601d2669a8feab9e7292ed219 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 12 May 2019 13:48:33 +0800 Subject: [PATCH 70/81] =?UTF-8?q?#1035=20=E5=B0=8F=E7=A8=8B=E5=BA=8F?= =?UTF-8?q?=E5=8F=91=E9=80=81=E6=A8=A1=E6=9D=BF=E6=8E=A5=E5=8F=A3=E5=8E=BB?= =?UTF-8?q?=E6=8E=89=E6=89=80=E6=9C=89=E9=A2=9C=E8=89=B2=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E7=9A=84color=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../binarywang/wx/miniapp/bean/WxMaTemplateData.java | 3 ++- .../wx/miniapp/bean/WxMaTemplateMessage.java | 12 +----------- .../util/json/WxMaTemplateMessageGsonAdapter.java | 7 ------- .../util/json/WxMaUniformMessageGsonAdapter.java | 3 --- .../wx/miniapp/api/impl/WxMaMsgServiceImplTest.java | 8 ++++---- 5 files changed, 7 insertions(+), 26 deletions(-) diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateData.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateData.java index 5eae34b115..040edda4d0 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateData.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateData.java @@ -5,7 +5,7 @@ /** *
- *
+ * 参考文档 https://developers.weixin.qq.com/miniprogram/dev/api-backend/templateMessage.send.html
  * Created by Binary Wang on 2018/9/23.
  * 
* @@ -29,4 +29,5 @@ public WxMaTemplateData(String name, String value, String color) { this.color = color; } + } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java index 5a67439478..00c7e52f46 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java @@ -13,7 +13,7 @@ /** * 模板消息. - * 参考 https://mp.weixin.qq.com/debug/wxadoc/dev/api/notice.html#接口说明 模板消息部分 + * 参考 https://developers.weixin.qq.com/miniprogram/dev/api-backend/templateMessage.send.html * * @author Binary Wang */ @@ -75,16 +75,6 @@ public class WxMaTemplateMessage implements Serializable { */ private List data; - /** - * 模板内容字体的颜色,不填默认黑色. - *
-   * 参数:color
-   * 是否必填: 否
-   * 描述: 模板内容字体的颜色,不填默认黑色
-   * 
- */ - private String color; - /** * 模板需要放大的关键词,不填则默认无放大. *
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaTemplateMessageGsonAdapter.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaTemplateMessageGsonAdapter.java
index 800a7e5a8e..15eff1ff4d 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaTemplateMessageGsonAdapter.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaTemplateMessageGsonAdapter.java
@@ -27,10 +27,6 @@ public JsonElement serialize(WxMaTemplateMessage message, Type typeOfSrc, JsonSe
       messageJson.addProperty("form_id", message.getFormId());
     }
 
-    if (message.getColor() != null) {
-      messageJson.addProperty("color", message.getColor());
-    }
-
     if (message.getEmphasisKeyword() != null) {
       messageJson.addProperty("emphasis_keyword", message.getEmphasisKeyword());
     }
@@ -45,9 +41,6 @@ public JsonElement serialize(WxMaTemplateMessage message, Type typeOfSrc, JsonSe
     for (WxMaTemplateData datum : message.getData()) {
       JsonObject dataJson = new JsonObject();
       dataJson.addProperty("value", datum.getValue());
-      if (datum.getColor() != null) {
-        dataJson.addProperty("color", datum.getColor());
-      }
       data.add(datum.getName(), dataJson);
     }
 
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapter.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapter.java
index c847bf375b..aecafa5573 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapter.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapter.java
@@ -79,9 +79,6 @@ public JsonElement serialize(WxMaUniformMessage message, Type typeOfSrc, JsonSer
       for (WxMaTemplateData templateData : message.getData()) {
         JsonObject dataJson = new JsonObject();
         dataJson.addProperty("value", templateData.getValue());
-        if (templateData.getColor() != null) {
-          dataJson.addProperty("color", templateData.getColor());
-        }
         data.add(templateData.getName(), dataJson);
       }
     }
diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java
index eb671cda61..298a9c9346 100644
--- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java
+++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java
@@ -48,10 +48,10 @@ public void testSendTemplateMsg() throws WxErrorException {
       .formId("FORMID")
       .page("index")
       .data(Lists.newArrayList(
-        new WxMaTemplateData("keyword1", "339208499", "#173177"),
-        new WxMaTemplateData("keyword2", dateFormat.format(new Date()), "#173177"),
-        new WxMaTemplateData("keyword3", "粤海喜来登酒店", "#173177"),
-        new WxMaTemplateData("keyword4", "广州市天河区天河路208号", "#173177")))
+        new WxMaTemplateData("keyword1", "339208499"),
+        new WxMaTemplateData("keyword2", dateFormat.format(new Date())),
+        new WxMaTemplateData("keyword3", "粤海喜来登酒店"),
+        new WxMaTemplateData("keyword4", "广州市天河区天河路208号")))
       .templateId(config.getTemplateId())
       .emphasisKeyword("keyword1.DATA")
       .build();

From 0345d62d0a467ab7d66579d833ca5bf179220c2c Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sun, 12 May 2019 20:47:39 +0800
Subject: [PATCH 71/81] =?UTF-8?q?#1036=20=E5=BE=AE=E4=BF=A1=E6=94=AF?=
 =?UTF-8?q?=E4=BB=98=E7=BB=9F=E4=B8=80=E4=B8=8B=E5=8D=95=E6=8E=A5=E5=8F=A3?=
 =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=B0=8F=E7=A8=8B=E5=BA=8F=E6=94=AF=E4=BB=98?=
 =?UTF-8?q?=E6=89=80=E9=9C=80=E7=9A=84receipt=E7=94=B5=E5=AD=90=E5=8F=91?=
 =?UTF-8?q?=E7=A5=A8=E5=85=A5=E5=8F=A3=E5=BC=80=E6=94=BE=E6=A0=87=E8=AF=86?=
 =?UTF-8?q?=E5=AD=97=E6=AE=B5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../bean/request/WxPayUnifiedOrderRequest.java      | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java
index 4ef7ab446a..78bb789d25 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayUnifiedOrderRequest.java
@@ -302,6 +302,19 @@ public class WxPayUnifiedOrderRequest extends BaseWxPayRequest {
   @XStreamAlias("sub_openid")
   private String subOpenid;
 
+  /**
+   * 
+   * 字段名:电子发票入口开放标识.
+   * 变量名:	receipt
+   * 是否必填:否
+   * 类型:String(8)
+   * 示例值:Y
+   * 描述:	Y,传入Y时,支付成功消息和支付详情页将出现开票入口。需要在微信支付商户平台或微信公众平台开通电子发票功能,传此字段才可生效
+   * 
+ */ + @XStreamAlias("receipt") + private String receipt; + /** *
    * 字段名:场景信息.

From 3f386d0a56ee95d32ffd3ba7e189906408e61ddd Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sun, 12 May 2019 20:59:30 +0800
Subject: [PATCH 72/81] =?UTF-8?q?#1011=20=E5=BC=80=E6=94=BE=E5=B9=B3?=
 =?UTF-8?q?=E5=8F=B0=E5=B0=8F=E7=A8=8B=E5=BA=8F=E5=AE=A1=E6=A0=B8=E7=BB=93?=
 =?UTF-8?q?=E6=9E=9C=E5=A2=9E=E5=8A=A0=E6=88=AA=E5=9B=BE=E7=A4=BA=E4=BE=8B?=
 =?UTF-8?q?=E7=9A=84=E5=AD=97=E6=AE=B5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../wx/miniapp/api/WxMaCodeService.java       | 40 ++++++------
 .../bean/code/WxMaCodeAuditStatus.java        | 12 +++-
 .../weixin/open/api/WxOpenMaService.java      | 63 ++-----------------
 .../bean/result/WxOpenMaQueryAuditResult.java |  5 ++
 4 files changed, 37 insertions(+), 83 deletions(-)

diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaCodeService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaCodeService.java
index fbe0818493..ad102805da 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaCodeService.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaCodeService.java
@@ -1,14 +1,10 @@
 package cn.binarywang.wx.miniapp.api;
 
-import java.util.List;
-
-import cn.binarywang.wx.miniapp.bean.code.WxMaCategory;
-import cn.binarywang.wx.miniapp.bean.code.WxMaCodeAuditStatus;
-import cn.binarywang.wx.miniapp.bean.code.WxMaCodeCommitRequest;
-import cn.binarywang.wx.miniapp.bean.code.WxMaCodeSubmitAuditRequest;
-import cn.binarywang.wx.miniapp.bean.code.WxMaCodeVersionDistribution;
+import cn.binarywang.wx.miniapp.bean.code.*;
 import me.chanjar.weixin.common.error.WxErrorException;
 
+import java.util.List;
+
 /**
  * 小程序代码管理相关 API(大部分只能是第三方平台调用)
  * 文档:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1489140610_Uavc4&token=&lang=zh_CN
@@ -18,7 +14,7 @@
  */
 public interface WxMaCodeService {
   /**
-   * 为授权的小程序帐号上传小程序代码
+   * 为授权的小程序帐号上传小程序代码.
    */
   String COMMIT_URL = "https://api.weixin.qq.com/wxa/commit";
   String GET_QRCODE_URL = "https://api.weixin.qq.com/wxa/get_qrcode";
@@ -35,7 +31,7 @@ public interface WxMaCodeService {
   String UNDO_CODE_AUDIT_URL = "https://api.weixin.qq.com/wxa/undocodeaudit";
 
   /**
-   * 为授权的小程序帐号上传小程序代码(仅仅支持第三方开放平台)
+   * 为授权的小程序帐号上传小程序代码(仅仅支持第三方开放平台).
    *
    * @param commitRequest 参数
    * @throws WxErrorException 上传失败时抛出,具体错误码请看类注释文档
@@ -43,19 +39,19 @@ public interface WxMaCodeService {
   void commit(WxMaCodeCommitRequest commitRequest) throws WxErrorException;
 
   /**
-   * 获取体验小程序的体验二维码
+   * 获取体验小程序的体验二维码.
    * 文档地址:
    * https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1489140610_Uavc4&token=&lang=zh_CN
    *
    * @param path 指定体验版二维码跳转到某个具体页面(如果不需要的话,则不需要填path参数,可在路径后以“?参数”方式传入参数)
-   * 具体的路径加参数需要urlencode(方法内部处理),比如page/index?action=1编码后得到page%2Findex%3Faction%3D1
+   *             具体的路径加参数需要urlencode(方法内部处理),比如page/index?action=1编码后得到page%2Findex%3Faction%3D1
    * @return 二维码 bytes
    * @throws WxErrorException 上传失败时抛出,具体错误码请看类注释文档
    */
   byte[] getQrCode(String path) throws WxErrorException;
 
   /**
-   * 获取授权小程序帐号的可选类目
+   * 获取授权小程序帐号的可选类目.
    *
    * @return List
    * @throws WxErrorException 获取失败时返回,具体错误码请看此接口的注释文档
@@ -63,7 +59,7 @@ public interface WxMaCodeService {
   List getCategory() throws WxErrorException;
 
   /**
-   * 获取小程序的第三方提交代码的页面配置(仅供第三方开发者代小程序调用)
+   * 获取小程序的第三方提交代码的页面配置(仅供第三方开发者代小程序调用).
    *
    * @return page_list 页面配置列表
    * @throws WxErrorException 获取失败时返回,具体错误码请看此接口的注释文档
@@ -71,7 +67,7 @@ public interface WxMaCodeService {
   List getPage() throws WxErrorException;
 
   /**
-   * 将第三方提交的代码包提交审核(仅供第三方开发者代小程序调用)
+   * 将第三方提交的代码包提交审核(仅供第三方开发者代小程序调用).
    *
    * @param auditRequest 提交审核参数
    * @return 审核编号
@@ -80,7 +76,7 @@ public interface WxMaCodeService {
   long submitAudit(WxMaCodeSubmitAuditRequest auditRequest) throws WxErrorException;
 
   /**
-   * 查询某个指定版本的审核状态(仅供第三方代小程序调用)
+   * 查询某个指定版本的审核状态(仅供第三方代小程序调用).
    *
    * @param auditId 提交审核时获得的审核id
    * @return 审核状态
@@ -89,7 +85,7 @@ public interface WxMaCodeService {
   WxMaCodeAuditStatus getAuditStatus(long auditId) throws WxErrorException;
 
   /**
-   * 查询最新一次提交的审核状态(仅供第三方代小程序调用)
+   * 查询最新一次提交的审核状态(仅供第三方代小程序调用).
    *
    * @return 审核状态
    * @throws WxErrorException 查询失败时返回,具体错误码请看此接口的注释文档
@@ -97,14 +93,14 @@ public interface WxMaCodeService {
   WxMaCodeAuditStatus getLatestAuditStatus() throws WxErrorException;
 
   /**
-   * 发布已通过审核的小程序(仅供第三方代小程序调用)
+   * 发布已通过审核的小程序(仅供第三方代小程序调用).
    *
    * @throws WxErrorException 发布失败时抛出,具体错误码请看此接口的注释文档
    */
   void release() throws WxErrorException;
 
   /**
-   * 修改小程序线上代码的可见状态(仅供第三方代小程序调用)
+   * 修改小程序线上代码的可见状态(仅供第三方代小程序调用).
    *
    * @param action 设置可访问状态,发布后默认可访问,close为不可见,open为可见
    * @throws WxErrorException 发布失败时抛出,具体错误码请看此接口的注释文档
@@ -112,14 +108,14 @@ public interface WxMaCodeService {
   void changeVisitStatus(String action) throws WxErrorException;
 
   /**
-   * 小程序版本回退(仅供第三方代小程序调用)
+   * 小程序版本回退(仅供第三方代小程序调用).
    *
    * @throws WxErrorException 失败时抛出,具体错误码请看此接口的注释文档
    */
   void revertCodeRelease() throws WxErrorException;
 
   /**
-   * 查询当前设置的最低基础库版本及各版本用户占比 (仅供第三方代小程序调用)
+   * 查询当前设置的最低基础库版本及各版本用户占比 (仅供第三方代小程序调用).
    *
    * @return 小程序版本分布信息
    * @throws WxErrorException 失败时抛出,具体错误码请看此接口的注释文档
@@ -127,7 +123,7 @@ public interface WxMaCodeService {
   WxMaCodeVersionDistribution getSupportVersion() throws WxErrorException;
 
   /**
-   * 设置最低基础库版本(仅供第三方代小程序调用)
+   * 设置最低基础库版本(仅供第三方代小程序调用).
    *
    * @param version 版本
    * @throws WxErrorException 失败时抛出,具体错误码请看此接口的注释文档
@@ -135,7 +131,7 @@ public interface WxMaCodeService {
   void setSupportVersion(String version) throws WxErrorException;
 
   /**
-   * 小程序审核撤回
+   * 小程序审核撤回.
    * 单个帐号每天审核撤回次数最多不超过1次,一个月不超过10次
    *
    * @throws WxErrorException 失败时抛出,具体错误码请看此接口的注释文档
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeAuditStatus.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeAuditStatus.java
index 36c33eaf1a..6487485060 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeAuditStatus.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/code/WxMaCodeAuditStatus.java
@@ -18,18 +18,24 @@
 public class WxMaCodeAuditStatus implements Serializable {
   private static final long serialVersionUID = 4655119308692217268L;
   /**
-   * 审核 ID
+   * 审核 ID.
    */
   @SerializedName(value = "auditId", alternate = {"auditid"})
   private Long auditId;
   /**
-   * 审核状态,其中0为审核成功,1为审核失败,2为审核中
+   * 审核状态.
+   * 其中0为审核成功,1为审核失败,2为审核中
    */
   private Integer status;
   /**
-   * 当status=1,审核被拒绝时,返回的拒绝原因
+   * 当status=1,审核被拒绝时,返回的拒绝原因.
    */
   private String reason;
+  /**
+   * 当status=1,审核被拒绝时,会返回审核失败的小程序截图示例。 xxx丨yyy丨zzz是media_id可通过获取永久素材接口 拉取截图内容).
+   */
+  @SerializedName(value = "screenshot")
+  private String screenShot;
 
   public static WxMaCodeAuditStatus fromJson(String json) {
     return WxMaGsonBuilder.create().fromJson(json, WxMaCodeAuditStatus.class);
diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaService.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaService.java
index 7d688d31c8..8dfd7a85f9 100644
--- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaService.java
+++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/WxOpenMaService.java
@@ -22,7 +22,7 @@
 public interface WxOpenMaService extends WxMaService {
 
   /**
-   * 设置小程序服务器域名
+   * 设置小程序服务器域名.
    *
    * 
    *     授权给第三方的小程序,其服务器域名只可以为第三方的服务器,当小程序通过第三方发布代码上线后,小程序原先自己配置的服务器域名将被删除,
@@ -170,21 +170,13 @@ public interface WxOpenMaService extends WxMaService {
 
   /**
    * 获得小程序的域名配置信息
-   *
-   * @return
    */
   WxOpenMaDomainResult getDomain() throws WxErrorException;
 
   /**
    * 修改域名
    *
-   * @param action              delete删除, set覆盖, get获取
-   * @param requestdomainList
-   * @param wsrequestdomainList
-   * @param uploaddomainList
-   * @param downloaddomainList
-   * @return
-   * @throws WxErrorException
+   * @param action delete删除, set覆盖, get获取
    */
   WxOpenMaDomainResult modifyDomain(String action, List requestdomainList, List wsrequestdomainList, List uploaddomainList, List downloaddomainList) throws WxErrorException;
 
@@ -198,17 +190,13 @@ public interface WxOpenMaService extends WxMaService {
   /**
    * 设置小程序的业务域名
    *
-   * @param action     add添加, delete删除, set覆盖
-   * @param domainList
+   * @param action add添加, delete删除, set覆盖
    * @return 直接返回字符串
    */
   String setWebViewDomain(String action, List domainList) throws WxErrorException;
 
   /**
    * 获取小程序的信息
-   *
-   * @return
-   * @throws WxErrorException
    */
   String getAccountBasicInfo() throws WxErrorException;
 
@@ -225,16 +213,11 @@ public interface WxOpenMaService extends WxMaService {
    * 解除绑定小程序体验者
    *
    * @param wechatid 体验者微信号(不是openid)
-   * @return
-   * @throws WxErrorException
    */
   WxOpenResult unbindTester(String wechatid) throws WxErrorException;
 
   /**
    * 获得体验者列表
-   *
-   * @return
-   * @throws WxErrorException
    */
   WxOpenMaTesterListResult getTesterList() throws WxErrorException;
 
@@ -245,17 +228,11 @@ public interface WxOpenMaService extends WxMaService {
    * @param userVersion 用户定义版本
    * @param userDesc    用户定义版本描述
    * @param extInfo     第三方自定义的配置
-   * @return
-   * @throws WxErrorException
    */
   WxOpenResult codeCommit(Long templateId, String userVersion, String userDesc, WxMaOpenCommitExtInfo extInfo) throws WxErrorException;
 
   /**
    * 获取体验小程序的体验二维码
-   *
-   * @param pagePath
-   * @param params
-   * @return
    */
   File getTestQrcode(String pagePath, Map params) throws WxErrorException;
 
@@ -264,9 +241,6 @@ public interface WxOpenMaService extends WxMaService {
    * 

* 注意:该接口可获取已设置的二级类目及用于代码审核的可选三级类目。 *

- * - * @return WxOpenMaCategoryListResult - * @throws WxErrorException */ WxOpenMaCategoryListResult getCategoryList() throws WxErrorException; @@ -280,69 +254,42 @@ public interface WxOpenMaService extends WxMaService { /** * 将第三方提交的代码包提交审核(仅供第三方开发者代小程序调用) - * - * @param submitAuditMessage - * @return - * @throws WxErrorException */ WxOpenMaSubmitAuditResult submitAudit(WxOpenMaSubmitAuditMessage submitAuditMessage) throws WxErrorException; /** * 查询某个指定版本的审核状态(仅供第三方代小程序调用) - * - * @param auditid - * @return - * @throws WxErrorException */ WxOpenMaQueryAuditResult getAuditStatus(Long auditid) throws WxErrorException; /** - * 查询最新一次提交的审核状态(仅供第三方代小程序调用) - * - * @return - * @throws WxErrorException + * 查询最新一次提交的审核状态(仅供第三方代小程序调用). */ WxOpenMaQueryAuditResult getLatestAuditStatus() throws WxErrorException; /** - * 发布已通过审核的小程序(仅供第三方代小程序调用) - * - * @return - * @throws WxErrorException + * 发布已通过审核的小程序(仅供第三方代小程序调用). */ WxOpenResult releaesAudited() throws WxErrorException; /** * 11. 小程序版本回退(仅供第三方代小程序调用) - * - * @return - * @throws WxErrorException */ WxOpenResult revertCodeReleaes() throws WxErrorException; /** * 15. 小程序审核撤回 - *

* 单个帐号每天审核撤回次数最多不超过1次,一个月不超过10次。 - *

- * - * @return - * @throws WxErrorException */ WxOpenResult undoCodeAudit() throws WxErrorException; /** * 查询当前设置的最低基础库版本及各版本用户占比 (仅供第三方代小程序调用) - * @return - * @throws WxErrorException */ String getSupportVersion() throws WxErrorException; /** * 设置最低基础库版本(仅供第三方代小程序调用) - * @param version - * @return - * @throws WxErrorException */ String setSupportVersion(String version) throws WxErrorException; diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaQueryAuditResult.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaQueryAuditResult.java index 41a761d647..8f0739f9a6 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaQueryAuditResult.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/result/WxOpenMaQueryAuditResult.java @@ -29,4 +29,9 @@ public class WxOpenMaQueryAuditResult extends WxOpenResult { * 审核失败原因. */ String reason; + /** + * 当status=1,审核被拒绝时,会返回审核失败的小程序截图示例。 xxx丨yyy丨zzz是media_id可通过获取永久素材接口 拉取截图内容). + */ + @SerializedName(value = "screenshot") + private String screenShot; } From 4247eb41cb693980df0bd20baf813a54d40369c4 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 12 May 2019 21:06:40 +0800 Subject: [PATCH 73/81] =?UTF-8?q?#1021=20=E5=BE=AE=E4=BF=A1=E5=B0=8F?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=8F=91=E9=80=81=E7=BB=9F=E4=B8=80=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E6=8E=A5=E5=8F=A3=E6=97=B6=E5=A2=9E=E5=8A=A0=E7=89=B9?= =?UTF-8?q?=E6=AE=8A=E6=96=B9=E6=B3=95=E7=94=A8=E4=BA=8E=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E5=8F=98=E6=80=81=E5=AD=97=E6=AE=B5=E5=90=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/binarywang/wx/miniapp/bean/WxMaUniformMessage.java | 6 ++++++ .../wx/miniapp/util/json/WxMaUniformMessageGsonAdapter.java | 2 ++ 2 files changed, 8 insertions(+) diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUniformMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUniformMessage.java index e58ad58a98..7515bdbe25 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUniformMessage.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUniformMessage.java @@ -104,5 +104,11 @@ public static class MiniProgram implements Serializable { * 加入此字段是基于微信官方接口变化多端的考虑 */ private boolean usePath = false; + + /** + * 是否使用pagePath,否则使用pagepath. + * 加入此字段是基于微信官方接口变化多端的考虑 + */ + private boolean usePagePath = false; } } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapter.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapter.java index aecafa5573..75ccd68aaa 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapter.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapter.java @@ -36,6 +36,8 @@ public JsonElement serialize(WxMaUniformMessage message, Type typeOfSrc, JsonSer miniProgramJson.addProperty("appid", miniProgram.getAppid()); if (miniProgram.isUsePath()) { miniProgramJson.addProperty("path", miniProgram.getPagePath()); + } else if (miniProgram.isUsePagePath()) { + miniProgramJson.addProperty("pagePath", miniProgram.getPagePath()); } else { miniProgramJson.addProperty("pagepath", miniProgram.getPagePath()); } From b842cf538c7613e63b1db00b8fcb094d992379c9 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 12 May 2019 21:38:27 +0800 Subject: [PATCH 74/81] =?UTF-8?q?=E5=8F=91=E5=B8=833.3.9.B=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- starters/wx-java-mp-starter/pom.xml | 119 ++++++++++++++------------- starters/wx-java-pay-starter/pom.xml | 3 +- weixin-java-common/pom.xml | 5 +- weixin-java-cp/pom.xml | 2 +- weixin-java-miniapp/pom.xml | 2 +- weixin-java-mp/pom.xml | 2 +- weixin-java-open/pom.xml | 2 +- weixin-java-pay/pom.xml | 2 +- 9 files changed, 70 insertions(+), 69 deletions(-) diff --git a/pom.xml b/pom.xml index 6432bd3eb4..b4ae3a66cf 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.github.binarywang wx-java - 3.3.8.B + 3.3.9.B pom WxJava - Weixin/Wechat Java SDK 微信开发Java SDK diff --git a/starters/wx-java-mp-starter/pom.xml b/starters/wx-java-mp-starter/pom.xml index d5ce48eda5..6d581b84a5 100644 --- a/starters/wx-java-mp-starter/pom.xml +++ b/starters/wx-java-mp-starter/pom.xml @@ -2,68 +2,69 @@ - 4.0.0 - - com.github.binarywang - wx-java - 3.3.8.B - + 4.0.0 + + com.github.binarywang + wx-java + 3.3.9.B + ../../ + - wx-java-mp-starter + wx-java-mp-starter - - 2.1.4.RELEASE - + + 2.1.4.RELEASE + - - - org.springframework.boot - spring-boot-autoconfigure - ${spring.boot.version} - - - org.springframework.boot - spring-boot-configuration-processor - ${spring.boot.version} - true - - - com.github.binarywang - weixin-java-mp - ${project.version} - - - redis.clients - jedis - - - org.projectlombok - lombok - provided - - + + + org.springframework.boot + spring-boot-autoconfigure + ${spring.boot.version} + + + org.springframework.boot + spring-boot-configuration-processor + ${spring.boot.version} + true + + + com.github.binarywang + weixin-java-mp + ${project.version} + + + redis.clients + jedis + + + org.projectlombok + lombok + provided + + - - - - 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 - - - - - - + + + + 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/starters/wx-java-pay-starter/pom.xml b/starters/wx-java-pay-starter/pom.xml index f61676f3c9..ee4e80a7c0 100644 --- a/starters/wx-java-pay-starter/pom.xml +++ b/starters/wx-java-pay-starter/pom.xml @@ -5,7 +5,8 @@ wx-java com.github.binarywang - 3.3.8.B + 3.3.9.B + ../../ 4.0.0 diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index e88f01c87a..1edffa2dab 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -1,13 +1,12 @@ - 4.0.0 com.github.binarywang wx-java - 3.3.8.B + 3.3.9.B weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index adb0fe93a6..7dcaec9aa3 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.8.B + 3.3.9.B weixin-java-cp diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index c745a3d132..b2709059c0 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.8.B + 3.3.9.B weixin-java-miniapp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 9a87ab5500..a518d575b8 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.8.B + 3.3.9.B weixin-java-mp diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index 70459e3fbf..de959f16f3 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.8.B + 3.3.9.B weixin-java-open diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index c59f50b9f7..fbb1b9d1fe 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ com.github.binarywang wx-java - 3.3.8.B + 3.3.9.B 4.0.0 From 70a7781ed3b387556ffaafd54bf5ea757ec9c239 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 12 May 2019 22:12:14 +0800 Subject: [PATCH 75/81] fix test --- .../util/json/WxMaUniformMessageGsonAdapterTest.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapterTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapterTest.java index 1541879c33..c28711ab81 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapterTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/util/json/WxMaUniformMessageGsonAdapterTest.java @@ -1,10 +1,9 @@ package cn.binarywang.wx.miniapp.util.json; -import org.testng.annotations.*; - import cn.binarywang.wx.miniapp.bean.WxMaTemplateData; import cn.binarywang.wx.miniapp.bean.WxMaUniformMessage; import com.google.gson.JsonParser; +import org.testng.annotations.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -26,7 +25,7 @@ public void testSerialize_mp() { .appid("APPID") .templateId("TEMPLATE_ID") .url("http://weixin.qq.com/download") - .miniProgram(new WxMaUniformMessage.MiniProgram("xiaochengxuappid12345", "index?foo=bar", false)) + .miniProgram(new WxMaUniformMessage.MiniProgram("xiaochengxuappid12345", "index?foo=bar", false, false)) .build(); message.addData(new WxMaTemplateData("first", "恭喜你购买成功!", "#173177")) .addData(new WxMaTemplateData("keyword1", "巧克力", "#173177")) @@ -72,7 +71,7 @@ public void testSerialize_mp() { @Test public void testSerialize_ma() { - WxMaUniformMessage message = WxMaUniformMessage.builder() + WxMaUniformMessage message = WxMaUniformMessage.builder() .isMpTemplateMsg(false) .toUser("OPENID") .page("page/page/index") From e9e7f6e46bd5a70309a6b592421a6cf461c21d02 Mon Sep 17 00:00:00 2001 From: Jeff Date: Fri, 17 May 2019 11:21:57 +0800 Subject: [PATCH 76/81] =?UTF-8?q?#1046=20=E4=BC=81=E4=B8=9A=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E5=A2=9E=E5=8A=A0=E6=94=AF=E6=8C=81=E6=9C=80=E6=96=B0?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=9A=84=E4=BB=BB=E5=8A=A1=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chanjar/weixin/common/api/WxConsts.java | 5 ++ .../java/me/chanjar/weixin/cp/WxCpConsts.java | 5 ++ .../me/chanjar/weixin/cp/api/WxCpService.java | 7 ++ .../weixin/cp/api/WxCpTaskCardService.java | 30 ++++++++ .../cp/api/impl/BaseWxCpServiceImpl.java | 6 ++ .../cp/api/impl/WxCpTaskCardServiceImpl.java | 39 ++++++++++ .../chanjar/weixin/cp/bean/WxCpMessage.java | 72 +++++++++++++++---- .../cp/bean/WxCpTaskCardUpdateResult.java | 42 +++++++++++ .../weixin/cp/bean/WxCpXmlMessage.java | 25 ++++--- .../bean/messagebuilder/TaskCardBuilder.java | 68 ++++++++++++++++++ .../cp/bean/taskcard/TaskCardButton.java | 23 ++++++ .../api/impl/WxCpTaskCardServiceImplTest.java | 65 +++++++++++++++++ .../weixin/cp/bean/WxCpMessageTest.java | 36 ++++++++-- .../weixin/cp/bean/WxCpXmlMessageTest.java | 28 +++++++- .../weixin/mp/bean/kefu/WxMpKefuMessage.java | 1 + 15 files changed, 420 insertions(+), 32 deletions(-) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTaskCardService.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImpl.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTaskCardUpdateResult.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TaskCardBuilder.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/taskcard/TaskCardButton.java create mode 100644 weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImplTest.java diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java index 557d1fc10e..9af7811c82 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java @@ -88,6 +88,11 @@ public static class KefuMsgType { * 小程序卡片(要求小程序与公众号已关联) */ public static final String MINIPROGRAMPAGE = "miniprogrampage"; + + /** + * 任务卡片消息 + */ + public static final String TASKCARD = "taskcard"; } /** diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/WxCpConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/WxCpConsts.java index 168bcf7492..87892eccdd 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/WxCpConsts.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/WxCpConsts.java @@ -84,6 +84,11 @@ public static class EventType { */ public static final String LOCATION_SELECT = "location_select"; + /** + * 任务卡片事件推送. + */ + public static final String TASKCARD_CLICK = "taskcard_click"; + } /** diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java index 732c1449ee..364723db87 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java @@ -301,6 +301,13 @@ public interface WxCpService { */ WxCpChatService getChatService(); + /** + * 获取任务卡片服务 + * + * @return 任务卡片服务 + */ + WxCpTaskCardService getTaskCardService(); + WxCpAgentService getAgentService(); WxCpOAService getOAService(); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTaskCardService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTaskCardService.java new file mode 100644 index 0000000000..038c2dd3bf --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpTaskCardService.java @@ -0,0 +1,30 @@ +package me.chanjar.weixin.cp.api; + +import me.chanjar.weixin.common.error.WxErrorException; + +import java.util.List; + +/** + *
+ *  任务卡片管理接口.
+ *  Created by Jeff on 2019-05-16.
+ * 
+ * + * @author Jeff + * @date 2019-05-16 + */ +public interface WxCpTaskCardService { + /** + *
+   * 更新任务卡片消息状态
+   * 详情请见: https://work.weixin.qq.com/api/doc#90000/90135/91579
+   *
+   * 注意: 这个方法使用WxCpConfigStorage里的agentId
+   * 
+ * + * @param userIds 企业的成员ID列表 + * @param taskId 任务卡片ID + * @param clickedKey 已点击按钮的Key + */ + void update(List userIds, String taskId, String clickedKey) throws WxErrorException; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java index 161c747c69..3eb99b79d2 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java @@ -46,6 +46,7 @@ public abstract class BaseWxCpServiceImpl implements WxCpService, RequestH private WxCpTagService tagService = new WxCpTagServiceImpl(this); private WxCpAgentService agentService = new WxCpAgentServiceImpl(this); private WxCpOAService oaService = new WxCpOAServiceImpl(this); + private WxCpTaskCardService taskCardService = new WxCpTaskCardServiceImpl(this); /** * 全局的是否正在刷新access token的锁 @@ -392,6 +393,11 @@ public WxCpOAService getOAService() { return oaService; } + @Override + public WxCpTaskCardService getTaskCardService() { + return taskCardService; + } + @Override public RequestHttp getRequestHttp() { return this; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImpl.java new file mode 100644 index 0000000000..3011320d50 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImpl.java @@ -0,0 +1,39 @@ +package me.chanjar.weixin.cp.api.impl; + +import lombok.RequiredArgsConstructor; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; +import me.chanjar.weixin.cp.api.WxCpService; +import me.chanjar.weixin.cp.api.WxCpTaskCardService; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + *
+ *  任务卡片管理接口.
+ *  Created by Jeff on 2019-05-16.
+ * 
+ * + * @author Jeff + * @date 2019-05-16 + */ +@RequiredArgsConstructor +public class WxCpTaskCardServiceImpl implements WxCpTaskCardService { + private final WxCpService mainService; + + @Override + public void update(List userIds, String taskId, String clickedKey) throws WxErrorException { + Integer agentId = this.mainService.getWxCpConfigStorage().getAgentId(); + + Map data = new HashMap<>(4); + data.put("userids", userIds); + data.put("agentid", agentId); + data.put("task_id", taskId); + data.put("clicked_key", clickedKey); + + String url = "https://qyapi.weixin.qq.com/cgi-bin/message/update_taskcard"; + this.mainService.post(url, WxGsonBuilder.create().toJson(data)); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java index df90775b5e..a22efd0e45 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java @@ -1,26 +1,18 @@ package me.chanjar.weixin.cp.bean; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.lang3.StringUtils; - import com.google.gson.JsonArray; import com.google.gson.JsonObject; import lombok.Data; import me.chanjar.weixin.common.api.WxConsts.KefuMsgType; import me.chanjar.weixin.cp.bean.article.MpnewsArticle; import me.chanjar.weixin.cp.bean.article.NewArticle; -import me.chanjar.weixin.cp.bean.messagebuilder.FileBuilder; -import me.chanjar.weixin.cp.bean.messagebuilder.ImageBuilder; -import me.chanjar.weixin.cp.bean.messagebuilder.MarkdownMsgBuilder; -import me.chanjar.weixin.cp.bean.messagebuilder.MpnewsBuilder; -import me.chanjar.weixin.cp.bean.messagebuilder.NewsBuilder; -import me.chanjar.weixin.cp.bean.messagebuilder.TextBuilder; -import me.chanjar.weixin.cp.bean.messagebuilder.TextCardBuilder; -import me.chanjar.weixin.cp.bean.messagebuilder.VideoBuilder; -import me.chanjar.weixin.cp.bean.messagebuilder.VoiceBuilder; +import me.chanjar.weixin.cp.bean.messagebuilder.*; +import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton; +import org.apache.commons.lang3.StringUtils; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; /** * 消息. @@ -49,6 +41,12 @@ public class WxCpMessage implements Serializable { private List articles = new ArrayList<>(); private List mpnewsArticles = new ArrayList<>(); + /** + * 任务卡片特有的属性 + */ + private String taskId; + private List taskButtons = new ArrayList<>(); + /** * 获得文本消息builder. */ @@ -112,6 +110,13 @@ public static FileBuilder FILE() { return new FileBuilder(); } + /** + * 获得任务卡片消息builder. + */ + public static TaskCardBuilder TASKCARD() { + return new TaskCardBuilder(); + } + /** *
@@ -124,6 +129,7 @@ public static FileBuilder FILE() {
    * {@link KefuMsgType#NEWS}
    * {@link KefuMsgType#MPNEWS}
    * {@link KefuMsgType#MARKDOWN}
+   * {@link KefuMsgType#TASKCARD}
    * 
* * @param msgType 消息类型 @@ -249,6 +255,42 @@ private void handleMsgType(JsonObject messageJson) { messageJson.add("mpnews", newsJsonObject); break; } + case KefuMsgType.TASKCARD: { + JsonObject text = new JsonObject(); + text.addProperty("title", this.getTitle()); + text.addProperty("description", this.getDescription()); + + if (StringUtils.isNotBlank(this.getUrl())) { + text.addProperty("url", this.getUrl()); + } + + text.addProperty("task_id", this.getTaskId()); + + JsonArray buttonJsonArray = new JsonArray(); + for (TaskCardButton button : this.getTaskButtons()) { + JsonObject buttonJson = new JsonObject(); + buttonJson.addProperty("key", button.getKey()); + buttonJson.addProperty("name", button.getName()); + + if (StringUtils.isNotBlank(button.getReplaceName())) { + buttonJson.addProperty("replace_name", button.getReplaceName()); + } + + if (StringUtils.isNotBlank(button.getColor())) { + buttonJson.addProperty("color", button.getColor()); + } + + if (button.getBold() != null) { + buttonJson.addProperty("is_bold", button.getBold()); + } + + buttonJsonArray.add(buttonJson); + } + text.add("btn", buttonJsonArray); + + messageJson.add("taskcard", text); + break; + } default: { // do nothing } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTaskCardUpdateResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTaskCardUpdateResult.java new file mode 100644 index 0000000000..c86b255b44 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTaskCardUpdateResult.java @@ -0,0 +1,42 @@ +package me.chanjar.weixin.cp.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ *  更新任务卡片消息状态的返回类
+ *  参考文档:https://work.weixin.qq.com/api/doc#90000/90135/91579
+ *  Created by Jeff on 2019-05-16.
+ * 
+ * + * @author Jeff + * @date 2019-05-16 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class WxCpTaskCardUpdateResult implements Serializable { + + @SerializedName("errcode") + private Integer errcode; + + @SerializedName("errmsg") + private String errmsg; + + /** + * 用户列表 + */ + @SerializedName("invaliduser") + private List invalidUsers; + + public static WxCpTaskCardUpdateResult fromJson(String json) { + return WxCpGsonBuilder.create().fromJson(json, WxCpTaskCardUpdateResult.class); + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java index 5a6a05293b..e6b2be197a 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java @@ -1,18 +1,8 @@ package me.chanjar.weixin.cp.bean; -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import com.thoughtworks.xstream.annotations.XStreamImplicit; -import org.apache.commons.io.IOUtils; - import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamConverter; +import com.thoughtworks.xstream.annotations.XStreamImplicit; import lombok.Data; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.api.WxConsts; @@ -22,6 +12,15 @@ import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; import me.chanjar.weixin.cp.util.xml.XStreamTransformer; +import org.apache.commons.io.IOUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; /** *
@@ -157,6 +156,10 @@ public class WxCpXmlMessage implements Serializable {
   @XStreamConverter(value = XStreamCDataConverter.class)
   private String recognition;
 
+  @XStreamAlias("TaskId")
+  @XStreamConverter(value = XStreamCDataConverter.class)
+  private String taskId;
+
   /**
    * 通讯录变更事件.
    * 请参考常量 me.chanjar.weixin.cp.WxCpConsts.ContactChangeType
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TaskCardBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TaskCardBuilder.java
new file mode 100644
index 0000000000..3c2d77924d
--- /dev/null
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TaskCardBuilder.java
@@ -0,0 +1,68 @@
+package me.chanjar.weixin.cp.bean.messagebuilder;
+
+import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton;
+
+import java.util.List;
+
+/**
+ * 
+ * 任务卡片消息Builder
+ * 用法: WxCustomMessage m = WxCustomMessage.TASKCARD().title(...)....toUser(...).build();
+ * 
+ * + * @author Jeff + * @date 2019-05-16 + */ +public class TaskCardBuilder extends BaseBuilder { + private String title; + private String description; + private String url; + private String taskId; + /** + * 按钮个数为1~2个 + */ + private List buttons; + + public TaskCardBuilder() { + this.msgType = WxConsts.KefuMsgType.TASKCARD; + } + + public TaskCardBuilder title(String title) { + this.title = title; + return this; + } + + public TaskCardBuilder description(String description) { + this.description = description; + return this; + } + + public TaskCardBuilder url(String url) { + this.url = url; + return this; + } + + public TaskCardBuilder taskId(String taskId) { + this.taskId = taskId; + return this; + } + + public TaskCardBuilder buttons(List buttons) { + this.buttons = buttons; + return this; + } + + @Override + public WxCpMessage build() { + WxCpMessage m = super.build(); + m.setSafe(null); + m.setTitle(this.title); + m.setDescription(this.description); + m.setUrl(this.url); + m.setTaskId(this.taskId); + m.setTaskButtons(this.buttons); + return m; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/taskcard/TaskCardButton.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/taskcard/TaskCardButton.java new file mode 100644 index 0000000000..0ffe49ce58 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/taskcard/TaskCardButton.java @@ -0,0 +1,23 @@ +package me.chanjar.weixin.cp.bean.taskcard; + +import lombok.Builder; +import lombok.Data; + +/** + *
+ *  任务卡片按钮
+ *  Created by Jeff on 2019-05-16.
+ * 
+ * + * @author Jeff + * @date 2019-05-16 + */ +@Data +@Builder +public class TaskCardButton { + private String key; + private String name; + private String replaceName; + private String color; + private Boolean bold; +} diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImplTest.java new file mode 100644 index 0000000000..be387548b9 --- /dev/null +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImplTest.java @@ -0,0 +1,65 @@ +package me.chanjar.weixin.cp.api.impl; + +import com.google.inject.Inject; +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.WxCpMessage; +import me.chanjar.weixin.cp.bean.WxCpMessageSendResult; +import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import java.util.Arrays; + +import static org.testng.Assert.assertNotNull; + +/** + * 测试任务卡片服务 + * + * @author Jeff + * @date 2019-05-16 + */ +@Guice(modules = ApiTestModule.class) +public class WxCpTaskCardServiceImplTest { + + @Inject + private WxCpService wxCpService; + + @Test + public void testSendTaskCard() throws WxErrorException { + TaskCardButton btn1 = TaskCardButton.builder() + .key("key1") + .name("同意") + .replaceName("已同意") + .bold(true) + .build(); + TaskCardButton btn2 = TaskCardButton.builder() + .key("key2") + .name("拒绝") + .replaceName("已拒绝") + .color("red") + .build(); + WxCpMessage message = WxCpMessage.TASKCARD() + .toUser("jeff|mr.t") + .title("有一个待审批的请求") + .description("申请:购买图书\n金额:100 元") + .taskId("task_1") + .url("http://www.qq.com") + .buttons(Arrays.asList(btn1, btn2)) + .build(); + + WxCpMessageSendResult messageSendResult = this.wxCpService.messageSend(message); + assertNotNull(messageSendResult); + System.out.println(messageSendResult); + System.out.println(messageSendResult.getInvalidPartyList()); + System.out.println(messageSendResult.getInvalidUserList()); + System.out.println(messageSendResult.getInvalidTagList()); + } + + @Test + public void testUpdate() throws Exception { + wxCpService.getTaskCardService().update(Arrays.asList("jeff", "mr.t"), "task_1", "key1"); + } + +} diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java index 344d1e8251..c54211758b 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java @@ -1,9 +1,11 @@ package me.chanjar.weixin.cp.bean; -import org.testng.annotations.*; - import me.chanjar.weixin.cp.bean.article.MpnewsArticle; import me.chanjar.weixin.cp.bean.article.NewArticle; +import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton; +import org.testng.annotations.Test; + +import java.util.Arrays; import static org.assertj.core.api.Assertions.assertThat; @@ -67,7 +69,7 @@ public void testNewsBuild() { WxCpMessage reply = WxCpMessage.NEWS().toUser("OPENID").addArticle(article1).addArticle(article2).build(); assertThat(reply.toJson()) - .isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":" + + .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{\"articles\":" + "[{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}," + "{\"title\":\"Happy Day\",\"description\":\"Is Really A Happy Day\",\"url\":\"URL\",\"picurl\":\"PIC_URL\"}]}," + "\"safe\":\"0\"}"); @@ -97,7 +99,7 @@ public void testMpnewsBuild_with_articles() { WxCpMessage reply = WxCpMessage.MPNEWS().toUser("OPENID").addArticle(article1, article2).build(); assertThat(reply.toJson()) - .isEqualTo( "{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"mpnews\":{\"articles\":" + + .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"mpnews\":{\"articles\":" + "[{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\"," + "\"content_source_url\":\"nice url\",\"content\":\"hahaha\",\"digest\":\"digest\",\"show_cover_pic\":\"heihei\"}" + ",{\"title\":\"Happy Day\",\"thumb_media_id\":\"thumb\",\"author\":\"aaaaaa\"," + @@ -112,4 +114,30 @@ public void testMpnewsBuild_with_media_id() { .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"mpnews\",\"mpnews\":{\"media_id\":\"mmm\"},\"safe\":\"0\"}"); } + public void testTaskCardBuilder() { + TaskCardButton button1 = TaskCardButton.builder() + .key("yes") + .name("批准") + .replaceName("已批准") + .color("blue") + .bold(true) + .build(); + TaskCardButton button2 = TaskCardButton.builder() + .key("yes") + .name("拒绝") + .replaceName("已拒绝") + .color("red") + .bold(false) + .build(); + WxCpMessage reply = WxCpMessage.TASKCARD().toUser("OPENID") + .title("任务卡片") + .description("有一条待处理任务") + .url("http://www.qq.com") + .taskId("task_123") + .buttons(Arrays.asList(button1, button2)) + .build(); + assertThat(reply.toJson()) + .isEqualTo("{\"touser\":\"OPENID\",\"msgtype\":\"taskcard\",\"taskcard\":{\"title\":\"任务卡片\",\"description\":\"有一条待处理任务\",\"url\":\"http://www.qq.com\",\"task_id\":\"task_123\",\"btn\":[{\"key\":\"yes\",\"name\":\"批准\",\"replace_name\":\"已批准\",\"color\":\"blue\",\"is_bold\":true},{\"key\":\"yes\",\"name\":\"拒绝\",\"replace_name\":\"已拒绝\",\"color\":\"red\",\"is_bold\":false}]}}"); + } + } diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java index aaf4032427..89c0396e08 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java @@ -1,9 +1,11 @@ package me.chanjar.weixin.cp.bean; import me.chanjar.weixin.common.api.WxConsts; -import org.testng.annotations.*; +import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static me.chanjar.weixin.cp.WxCpConsts.EventType.TASKCARD_CLICK; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; @Test public class WxCpXmlMessageTest { @@ -149,4 +151,26 @@ public void testExtAttr() { assertEquals(wxMessage.getExtAttrs().getItems().get(0).getName(), "爱好"); } + + public void testTaskCardEvent() { + String xml = "" + + "" + + "" + + "123456789" + + "" + + "" + + "" + + "" + + "1" + + ""; + WxCpXmlMessage wxMessage = WxCpXmlMessage.fromXml(xml); + assertEquals(wxMessage.getToUserName(), "toUser"); + assertEquals(wxMessage.getFromUserName(), "FromUser"); + assertEquals(wxMessage.getCreateTime(), Long.valueOf(123456789L)); + assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.EVENT); + assertEquals(wxMessage.getAgentId(), Integer.valueOf(1)); + assertEquals(wxMessage.getEvent(), TASKCARD_CLICK); + assertEquals(wxMessage.getEventKey(), "key111"); + assertEquals(wxMessage.getTaskId(), "taskid111"); + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java index 92c298a647..560add6042 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/kefu/WxMpKefuMessage.java @@ -109,6 +109,7 @@ public static MiniProgramPageBuilder MINIPROGRAMPAGE() { * {@link WxConsts.KefuMsgType#MPNEWS} * {@link WxConsts.KefuMsgType#WXCARD} * {@link WxConsts.KefuMsgType#MINIPROGRAMPAGE} + * {@link WxConsts.KefuMsgType#TASKCARD} *
* */ From ca346abad6c9c60eefcf283382274a3457ec9d1b Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 18 May 2019 15:21:07 +0800 Subject: [PATCH 77/81] =?UTF-8?q?=E8=A7=84=E8=8C=83=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/me/chanjar/weixin/mp/bean/card/CashCard.java | 3 ++- .../java/me/chanjar/weixin/mp/bean/card/DiscountCard.java | 3 ++- .../weixin/mp/bean/card/DiscountCardCreateRequest.java | 4 ++++ .../main/java/me/chanjar/weixin/mp/bean/card/GeneralCard.java | 3 ++- .../chanjar/weixin/mp/bean/card/GeneralCardCreateRequest.java | 4 ++++ .../chanjar/weixin/mp/bean/card/GrouponCardCreateRequest.java | 4 ++++ 6 files changed, 18 insertions(+), 3 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CashCard.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CashCard.java index 3d4de40c0b..df5290b218 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CashCard.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/CashCard.java @@ -2,6 +2,7 @@ import com.google.gson.annotations.SerializedName; import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; @@ -12,8 +13,8 @@ * @Date 2018/12/29 */ @Data +@EqualsAndHashCode(callSuper = true) public final class CashCard extends Card implements Serializable { - private static final long serialVersionUID = 6965491956462769745L; /** diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DiscountCard.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DiscountCard.java index b2c3a13ffc..b1becbd642 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DiscountCard.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DiscountCard.java @@ -2,6 +2,7 @@ import com.google.gson.annotations.SerializedName; import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; @@ -12,8 +13,8 @@ * @Date 2018/12/29 */ @Data +@EqualsAndHashCode(callSuper = true) public final class DiscountCard extends Card implements Serializable { - private static final long serialVersionUID = 1704610082472315077L; /** diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DiscountCardCreateRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DiscountCardCreateRequest.java index 869c487c92..b527ec12fc 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DiscountCardCreateRequest.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/DiscountCardCreateRequest.java @@ -2,6 +2,7 @@ import com.google.gson.annotations.SerializedName; import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; @@ -12,7 +13,10 @@ * @Date 2018/12/29 */ @Data +@EqualsAndHashCode(callSuper = true) public class DiscountCardCreateRequest extends CardCreateRequest implements Serializable { + private static final long serialVersionUID = 1190518086576489692L; + @SerializedName("card_type") private String cardType = "DISCOUNT"; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GeneralCard.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GeneralCard.java index dcfba74da7..2264d8ec0a 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GeneralCard.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GeneralCard.java @@ -2,6 +2,7 @@ import com.google.gson.annotations.SerializedName; import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; @@ -12,8 +13,8 @@ * @Date 2018/12/29 */ @Data +@EqualsAndHashCode(callSuper = true) public final class GeneralCard extends Card implements Serializable { - private static final long serialVersionUID = -1577656733441132585L; /** diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GeneralCardCreateRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GeneralCardCreateRequest.java index 8a9c3d1801..f1ac56987b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GeneralCardCreateRequest.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GeneralCardCreateRequest.java @@ -2,6 +2,7 @@ import com.google.gson.annotations.SerializedName; import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; @@ -12,7 +13,10 @@ * @Date 2018/12/29 */ @Data +@EqualsAndHashCode(callSuper = true) public class GeneralCardCreateRequest extends CardCreateRequest implements Serializable { + private static final long serialVersionUID = 1771355872211267723L; + @SerializedName("card_type") private String cardType = "GENERAL_COUPON"; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GrouponCardCreateRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GrouponCardCreateRequest.java index 48b1e3e7da..aeab1fd3e8 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GrouponCardCreateRequest.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/GrouponCardCreateRequest.java @@ -2,6 +2,7 @@ import com.google.gson.annotations.SerializedName; import lombok.Data; +import lombok.EqualsAndHashCode; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import java.io.Serializable; @@ -12,7 +13,10 @@ * @Date 2018/12/29 */ @Data +@EqualsAndHashCode(callSuper = true) public class GrouponCardCreateRequest extends CardCreateRequest implements Serializable { + private static final long serialVersionUID = 7551441058859934512L; + @SerializedName("card_type") private String cardType = "GROUPON"; From 3410692f2d960e8ea757265cf1806afc77452c32 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 18 May 2019 15:22:36 +0800 Subject: [PATCH 78/81] =?UTF-8?q?#1047=E4=BC=81=E4=B8=9A=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E9=82=80=E8=AF=B7=E6=88=90=E5=91=98=E6=8E=A5=E5=8F=A3=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=E4=B8=ADinvaliduser=E5=AD=97=E6=AE=B5=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chanjar/weixin/cp/bean/WxCpInviteResult.java | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpInviteResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpInviteResult.java index 871e48394e..ccf6fc94db 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpInviteResult.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpInviteResult.java @@ -37,7 +37,7 @@ public static WxCpInviteResult fromJson(String json) { private String errMsg; @SerializedName("invaliduser") - private String invalidUsers; + private String[] invalidUsers; @SerializedName("invalidparty") private String[] invalidParties; @@ -45,16 +45,4 @@ public static WxCpInviteResult fromJson(String json) { @SerializedName("invalidtag") private String[] invalidTags; - public List getInvalidUserList() { - return this.content2List(this.invalidUsers); - } - - private List content2List(String content) { - if (StringUtils.isBlank(content)) { - return Collections.emptyList(); - } - - return Splitter.on("|").splitToList(content); - } - } From fcc01030d2cde7ebb921d76000a7b4feb248eb76 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 18 May 2019 15:38:14 +0800 Subject: [PATCH 79/81] =?UTF-8?q?#1031=20=E5=BE=AE=E4=BF=A1=E4=BC=9A?= =?UTF-8?q?=E5=91=98=E5=8D=A1=E5=AF=B9=E8=B1=A1=E5=A2=9E=E5=8A=A0=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E4=B8=80=E9=94=AE=E8=B7=B3=E8=BD=AC=E6=BF=80=E6=B4=BB?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=89=80=E9=9C=80=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cp/config/WxCpJedisConfigStorage.java | 11 ++------- .../weixin/mp/api/WxMpMemberCardService.java | 9 +++---- .../api/impl/WxMpMemberCardServiceImpl.java | 4 ++-- .../weixin/mp/bean/card/MemberCard.java | 24 ++++++++++++++----- .../mp/bean/card/MemberCardCreateRequest.java | 11 +++++++-- .../mp/bean/card/MemberCardUpdateRequest.java | 7 ++++++ 6 files changed, 43 insertions(+), 23 deletions(-) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpJedisConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpJedisConfigStorage.java index 7f9fcf654b..7c72de0e1b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpJedisConfigStorage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpJedisConfigStorage.java @@ -9,28 +9,21 @@ import java.io.File; /** - * Jedis client implementor for wechat config storage. *
- *    使用说明:本实现仅供参考,并不完整,
+ *    使用说明:本实现仅供参考,并不完整.
  *    比如为减少项目依赖,未加入redis分布式锁的实现,如有需要请自行实现。
  * 
* * @author gaigeshen */ public class WxCpJedisConfigStorage implements WxCpConfigStorage { - - /** - * Redis keys here - */ private static final String ACCESS_TOKEN_KEY = "WX_CP_ACCESS_TOKEN"; private static final String ACCESS_TOKEN_EXPIRES_TIME_KEY = "WX_CP_ACCESS_TOKEN_EXPIRES_TIME"; private static final String JS_API_TICKET_KEY = "WX_CP_JS_API_TICKET"; private static final String JS_API_TICKET_EXPIRES_TIME_KEY = "WX_CP_JS_API_TICKET_EXPIRES_TIME"; private static final String AGENT_JSAPI_TICKET_KEY = "WX_CP_AGENT_%s_JSAPI_TICKET"; private static final String AGENT_JSAPI_TICKET_EXPIRES_TIME_KEY = "WX_CP_AGENT_%s_JSAPI_TICKET_EXPIRES_TIME"; - /** - * Redis clients pool - */ + private final JedisPool jedisPool; private volatile String corpId; private volatile String corpSecret; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java index ba79d78511..37785365c1 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMemberCardService.java @@ -17,14 +17,14 @@ * @date 2018-08-30 */ public interface WxMpMemberCardService { - String MEMBER_CARD_CREAET = "https://api.weixin.qq.com/card/create"; + String MEMBER_CARD_CREATE = "https://api.weixin.qq.com/card/create"; String MEMBER_CARD_ACTIVATE = "https://api.weixin.qq.com/card/membercard/activate"; String MEMBER_CARD_USER_INFO_GET = "https://api.weixin.qq.com/card/membercard/userinfo/get"; String MEMBER_CARD_UPDATE_USER = "https://api.weixin.qq.com/card/membercard/updateuser"; /** * 会员卡激活之微信开卡接口(wx_activate=true情况调用). */ - String MEMBER_CARD_ACTIVATEUSERFORM = "https://api.weixin.qq.com/card/membercard/activateuserform/set"; + String MEMBER_CARD_ACTIVATE_USER_FORM = "https://api.weixin.qq.com/card/membercard/activateuserform/set"; /** * 获取会员卡开卡插件参数. @@ -37,7 +37,8 @@ public interface WxMpMemberCardService { String MEMBER_CARD_UPDATE = "https://api.weixin.qq.com/card/update"; /** - * 跳转型会员卡开卡字段,获取用户提交资料(wx_activate=true情况调用),开发者根据activate_ticket获取到用户填写的信息 + * 跳转型会员卡开卡字段. + * 获取用户提交资料(wx_activate=true情况调用),开发者根据activate_ticket获取到用户填写的信息 */ String MEMBER_CARD_ACTIVATE_TEMP_INFO = "https://api.weixin.qq.com/card/membercard/activatetempinfo/get"; @@ -127,7 +128,7 @@ public interface WxMpMemberCardService { CardUpdateResult updateCardInfo(MemberCardUpdateRequest memberCardUpdateRequest) throws WxErrorException; /** - * 解析跳转型开卡字段用户提交的资料 + * 解析跳转型开卡字段用户提交的资料. * 开发者在URL上截取ticket后须先进行urldecode * * @param activateTicket 用户提交的资料 diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java index 6e4143baa7..3eaf61417c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMemberCardServiceImpl.java @@ -70,7 +70,7 @@ public WxMpCardCreateResult createMemberCard(WxMpMemberCardCreateMessage createM return validResult; } - String response = this.wxMpService.post(MEMBER_CARD_CREAET, GSON.toJson(createMessageMessage)); + String response = this.wxMpService.post(MEMBER_CARD_CREATE, GSON.toJson(createMessageMessage)); return WxMpCardCreateResult.fromJson(response); } @@ -243,7 +243,7 @@ public WxMpMemberCardUpdateResult updateUserMemberCard(WxMpMemberCardUpdateMessa @Override public MemberCardActivateUserFormResult setActivateUserForm(MemberCardActivateUserFormRequest userFormRequest) throws WxErrorException { - String responseContent = this.getWxMpService().post(MEMBER_CARD_ACTIVATEUSERFORM, GSON.toJson(userFormRequest)); + String responseContent = this.getWxMpService().post(MEMBER_CARD_ACTIVATE_USER_FORM, GSON.toJson(userFormRequest)); return MemberCardActivateUserFormResult.fromJson(responseContent); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCard.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCard.java index b8b81399d2..a6caf1bbd4 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCard.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCard.java @@ -38,12 +38,6 @@ public final class MemberCard implements Serializable { @SerializedName("auto_activate") private boolean autoActivate; - /** - * 是否一键开卡. - */ - @SerializedName("wx_activate") - private boolean wxActivate; - /** * 显示积分. */ @@ -145,6 +139,24 @@ public final class MemberCard implements Serializable { @SerializedName("advanced_info") private AdvancedInfo advancedInfo; + /** + * 是否支持一键激活 ,填true或false. + */ + @SerializedName("wx_activate") + private boolean wxActivate; + + /** + * 是否支持跳转型一键激活,填true或false. + */ + @SerializedName("wx_activate_after_submit") + private boolean wxActivateAfterSubmit; + + /** + * 跳转型一键激活跳转的地址链接,请填写http:// 或者https://开头的链接. + */ + @SerializedName("wx_activate_after_submit_url") + private String wxActivateAfterSubmitUrl; + @Override public String toString() { return WxMpGsonBuilder.create().toJson(this); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardCreateRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardCreateRequest.java index b15cf22546..5abdf73310 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardCreateRequest.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardCreateRequest.java @@ -1,13 +1,20 @@ package me.chanjar.weixin.mp.bean.card; -import java.io.Serializable; - import com.google.gson.annotations.SerializedName; import lombok.Data; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; +import java.io.Serializable; + +/** + * 创建会员卡请求对象. + * + * @author yuanqixun + */ @Data public class MemberCardCreateRequest implements Serializable { + private static final long serialVersionUID = -1044836608401698097L; + @SerializedName("card_type") private String cardType = "MEMBER_CARD"; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardUpdateRequest.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardUpdateRequest.java index 37807a068f..8c1f85351e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardUpdateRequest.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/MemberCardUpdateRequest.java @@ -6,8 +6,15 @@ import java.io.Serializable; +/** + * 更新会员卡请求对象. + * + * @author yuanqixun + */ @Data public class MemberCardUpdateRequest implements Serializable { + private static final long serialVersionUID = -1025759626161614466L; + @SerializedName("card_id") private String cardId; From e3c0cada2e7df39c49450bf34198c90fd3261172 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 18 May 2019 15:46:45 +0800 Subject: [PATCH 80/81] add readme for pay starter --- starters/wx-java-pay-starter/README.md | 27 ++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 starters/wx-java-pay-starter/README.md diff --git a/starters/wx-java-pay-starter/README.md b/starters/wx-java-pay-starter/README.md new file mode 100644 index 0000000000..c987216147 --- /dev/null +++ b/starters/wx-java-pay-starter/README.md @@ -0,0 +1,27 @@ +# 使用说明 +1. 在自己的Spring Boot项目里,引入maven依赖 +```xml + + com.github.binarywang + wx-java-pay-starter + ${version} + + ``` +2. 添加配置(application.yml) +```yml +wx: + pay: + appId: wx5b69c56ac01ed858 + mchId: 1462547202 + mchKey: OGL9fvig9y2HrXrQ86tM4jTwyv4ja6G5 + subAppId: + subMchId: + keyPath: +``` + + + + + + + From a503171a5b76bf8689b7665cde97143a8f80db84 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 18 May 2019 17:04:45 +0800 Subject: [PATCH 81/81] =?UTF-8?q?=E5=8F=91=E5=B8=833.4.0=E6=AD=A3=E5=BC=8F?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- starters/wx-java-mp-starter/pom.xml | 4 +++- starters/wx-java-pay-starter/pom.xml | 4 +++- weixin-java-common/pom.xml | 2 +- weixin-java-cp/pom.xml | 2 +- weixin-java-miniapp/pom.xml | 2 +- weixin-java-mp/pom.xml | 2 +- weixin-java-open/pom.xml | 2 +- weixin-java-pay/pom.xml | 2 +- 9 files changed, 13 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index b4ae3a66cf..0ad56a1bf1 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.github.binarywang wx-java - 3.3.9.B + 3.4.0 pom WxJava - Weixin/Wechat Java SDK 微信开发Java SDK diff --git a/starters/wx-java-mp-starter/pom.xml b/starters/wx-java-mp-starter/pom.xml index 6d581b84a5..639662b8fe 100644 --- a/starters/wx-java-mp-starter/pom.xml +++ b/starters/wx-java-mp-starter/pom.xml @@ -6,11 +6,13 @@ com.github.binarywang wx-java - 3.3.9.B + 3.4.0 ../../ wx-java-mp-starter + WxJava - Spring Boot Starter for MP + 微信公众号开发的Spring Boot Starter 2.1.4.RELEASE diff --git a/starters/wx-java-pay-starter/pom.xml b/starters/wx-java-pay-starter/pom.xml index ee4e80a7c0..eba398b454 100644 --- a/starters/wx-java-pay-starter/pom.xml +++ b/starters/wx-java-pay-starter/pom.xml @@ -5,12 +5,14 @@ wx-java com.github.binarywang - 3.3.9.B + 3.4.0 ../../ 4.0.0 wx-java-pay-starter + WxJava - Spring Boot Starter for WxPay + 微信支付开发的Spring Boot Starter 2.1.4.RELEASE diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 1edffa2dab..7e5f54fefc 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 3.3.9.B + 3.4.0 weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 7dcaec9aa3..09208eb329 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.9.B + 3.4.0 weixin-java-cp diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index b2709059c0..de3c9f50df 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.9.B + 3.4.0 weixin-java-miniapp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index a518d575b8..ed8c7e75de 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.9.B + 3.4.0 weixin-java-mp diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index de959f16f3..a624a38c7f 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.3.9.B + 3.4.0 weixin-java-open diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index fbb1b9d1fe..a6130d13ee 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ com.github.binarywang wx-java - 3.3.9.B + 3.4.0 4.0.0