From 6fd1e8b312a15f962928f8dc1d6aa736810b01e8 Mon Sep 17 00:00:00 2001 From: lsw <598145607@qq.com> Date: Mon, 25 Nov 2019 10:04:39 +0800 Subject: [PATCH 0001/1706] =?UTF-8?q?#1297=20=E4=BC=81=E4=B8=9A=E5=A4=96?= =?UTF-8?q?=E9=83=A8=E8=81=94=E7=B3=BB=E4=BA=BA=E5=AE=A2=E6=88=B7=E5=8F=98?= =?UTF-8?q?=E6=9B=B4=E4=BA=8B=E4=BB=B6=E6=96=B0=E5=A2=9E=20ChangeType=20?= =?UTF-8?q?=E5=B8=B8=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/me/chanjar/weixin/cp/constant/WxCpConsts.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java index aa4eded451..48bfc3ceb9 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java @@ -109,6 +109,15 @@ public static class ExternalContactChangeType { * 删除外部联系人 */ public static final String DEL_EXTERNAL_CONTACT = "del_external_contact"; + + /** + * 外部联系人免验证添加成员事件 + */ + public static final String ADD_HALF_EXTERNAL_CONTACT = "add_half_external_contact"; + /** + * 删除跟进成员事件 + */ + public static final String DEL_FOLLOW_USER = "del_follow_user"; } /** From 010464e3996eff7379f0a4c855d88c530815b4b1 Mon Sep 17 00:00:00 2001 From: JohnsGain <1047994907@qq.com> Date: Wed, 27 Nov 2019 10:10:21 +0800 Subject: [PATCH 0002/1706] =?UTF-8?q?:art:=20=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=EF=BC=8C=E6=8A=8A=E7=AD=BE=E5=90=8D=E5=B7=A5=E5=85=B7?= =?UTF-8?q?=E7=B1=BB=E9=87=8C=E9=9D=A2=E7=9A=84=E5=B8=B8=E9=87=8F=E6=8F=90?= =?UTF-8?q?=E5=8F=96=E5=87=BA=E6=9D=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../binarywang/wxpay/util/SignUtils.java | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java index 4712987249..5591b016b4 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java @@ -1,18 +1,5 @@ package com.github.binarywang.wxpay.util; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; - -import org.apache.commons.codec.digest.DigestUtils; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.StringUtils; - import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest; import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; import com.github.binarywang.wxpay.constant.WxPayConstants.SignType; @@ -20,6 +7,13 @@ import com.google.common.collect.Maps; import com.thoughtworks.xstream.annotations.XStreamAlias; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.*; /** *
@@ -31,6 +25,12 @@
  */
 @Slf4j
 public class SignUtils {
+
+  /**
+   * 签名的时候不携带的参数
+   */
+  private static List NO_SIGN_PARAMS = Lists.newArrayList("sign", "key", "xmlString", "xmlDoc", "couponList");
+
   /**
    * 请参考并使用 {@link #createSign(Object, String, String, String[])}.
    *
@@ -85,7 +85,7 @@ public static String createSign(Map params, String signType, Str
       String value = params.get(key);
       boolean shouldSign = false;
       if (StringUtils.isNotEmpty(value) && !ArrayUtils.contains(ignoredParams, key)
-        && !Lists.newArrayList("sign", "key", "xmlString", "xmlDoc", "couponList").contains(key)) {
+        && !NO_SIGN_PARAMS.contains(key)) {
         shouldSign = true;
       }
 

From 80f885fbfb913f1ab4356cba1c1451135e5530d7 Mon Sep 17 00:00:00 2001
From: mrxiao <39647988+mr-xiaoyu@users.noreply.github.com>
Date: Thu, 28 Nov 2019 10:22:41 +0800
Subject: [PATCH 0003/1706] =?UTF-8?q?:sparkles:=09#1009=20=E5=AE=9E?=
 =?UTF-8?q?=E7=8E=B0=E5=BE=AE=E4=BF=A1=E5=B0=8F=E7=A8=8B=E5=BA=8F=E7=89=A9?=
 =?UTF-8?q?=E6=B5=81=E5=8A=A9=E6=89=8B=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

* 快递公司

* 绑定、解绑物流账号

* 配置面单打印员

* 获取打印员

* 增加微信文档地址说明

* 快递下单

* 快递下单和订单操作

* 补充文档地址
---
 .../wx/miniapp/api/WxMaExpressService.java    | 203 +++++++++++++++
 .../wx/miniapp/api/WxMaService.java           |   6 +-
 .../api/impl/WxMaExpressServiceImpl.java      |  98 ++++++++
 .../wx/miniapp/api/impl/WxMaServiceImpl.java  |   4 +
 .../bean/express/WxMaExpressAccount.java      | 103 ++++++++
 .../bean/express/WxMaExpressDelivery.java     |  83 +++++++
 .../miniapp/bean/express/WxMaExpressPath.java |  75 ++++++
 .../bean/express/WxMaExpressPrinter.java      |  44 ++++
 .../request/WxMaExpressAddOrderRequest.java   | 169 +++++++++++++
 .../WxMaExpressBindAccountRequest.java        |  73 ++++++
 .../request/WxMaExpressGetOrderRequest.java   |  63 +++++
 .../request/WxMaExpressOrderCargo.java        |  74 ++++++
 .../request/WxMaExpressOrderCargoDetail.java  |  33 +++
 .../request/WxMaExpressOrderInsured.java      |  43 ++++
 .../request/WxMaExpressOrderPerson.java       | 110 +++++++++
 .../express/request/WxMaExpressOrderShop.java |  55 +++++
 .../WxMaExpressPrinterUpdateRequest.java      |  54 ++++
 .../WxMaExpressTestUpdateOrderRequest.java    |  94 +++++++
 .../result/WxMaExpressOrderInfoResult.java    |  70 ++++++
 .../wx/miniapp/constant/WxMaConstants.java    |  52 ++++
 .../api/impl/WxMaExpressServiceImplTest.java  | 231 ++++++++++++++++++
 21 files changed, 1736 insertions(+), 1 deletion(-)
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaExpressService.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaExpressServiceImpl.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/WxMaExpressAccount.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/WxMaExpressDelivery.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/WxMaExpressPath.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/WxMaExpressPrinter.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressAddOrderRequest.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressBindAccountRequest.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressGetOrderRequest.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderCargo.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderCargoDetail.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderInsured.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderPerson.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderShop.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressPrinterUpdateRequest.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressTestUpdateOrderRequest.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/result/WxMaExpressOrderInfoResult.java
 create mode 100644 weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaExpressServiceImplTest.java

diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaExpressService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaExpressService.java
new file mode 100644
index 0000000000..b6f5e2d683
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaExpressService.java
@@ -0,0 +1,203 @@
+package cn.binarywang.wx.miniapp.api;
+
+import cn.binarywang.wx.miniapp.bean.express.WxMaExpressAccount;
+import cn.binarywang.wx.miniapp.bean.express.WxMaExpressDelivery;
+import cn.binarywang.wx.miniapp.bean.express.WxMaExpressPath;
+import cn.binarywang.wx.miniapp.bean.express.WxMaExpressPrinter;
+import cn.binarywang.wx.miniapp.bean.express.request.*;
+import cn.binarywang.wx.miniapp.bean.express.result.WxMaExpressOrderInfoResult;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+import java.util.List;
+
+/**
+ * 小程序物流助手
+ * @author xiaoyu
+ * @since 2019-11-26
+ */
+public interface WxMaExpressService {
+  /**
+   * 获取支持的快递公司列表
+   */
+  String ALL_DELIVERY_URL = "https://api.weixin.qq.com/cgi-bin/express/business/delivery/getall";
+
+  /**
+   * 获取所有绑定的物流账号
+   */
+  String ALL_ACCOUNT_URL = "https://api.weixin.qq.com/cgi-bin/express/business/account/getall";
+
+  /**
+   * 绑定、解绑物流账号
+   */
+  String BIND_ACCOUNT_URL = "https://api.weixin.qq.com/cgi-bin/express/business/account/bind";
+
+  /**
+   * 获取电子面单余额
+   */
+  String GET_QUOTA_URL = "https://api.weixin.qq.com/cgi-bin/express/business/quota/get";
+
+  /**
+   * 配置面单打印员
+   */
+  String UPDATE_PRINTER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/printer/update";
+
+  /**
+   * 获取打印员
+   */
+  String GET_PRINTER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/printer/getall";
+
+  /**
+   * 生成运单
+   */
+  String ADD_ORDER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/order/add";
+
+  /**
+   * 批量获取运单数据
+   */
+  String BATCH_GET_ORDER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/order/batchget";
+
+  /**
+   * 取消运单
+   */
+  String CANCEL_ORDER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/order/cancel";
+
+  /**
+   * 获取运单数据
+   */
+  String GET_ORDER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/order/get";
+
+  /**
+   * 查询运单轨迹
+   */
+  String GET_PATH_URL = "https://api.weixin.qq.com/cgi-bin/express/business/path/get";
+
+  /**
+   * 模拟快递公司更新订单状态
+   */
+  String TEST_UPDATE_ORDER_URL = "https://api.weixin.qq.com/cgi-bin/express/business/test_update_order";
+
+  /**
+   * 获取支持的快递公司列表
+   * @return  快递公司列表
+   * @throws WxErrorException 获取失败时返回
+   * 
+   *   查看文档
+   * 
+ */ + List getAllDelivery() throws WxErrorException; + + /** + * 获取所有绑定的物流账号 + * @return 物流账号list + * @throws WxErrorException 获取失败时返回 + *
+   *   查看文档
+   * 
+ */ + List getAllAccount() throws WxErrorException; + + /** + * 绑定、解绑物流账号 + * @param wxMaExpressBindAccountRequest 物流账号对象 + * @throws WxErrorException 请求失败时返回 + *
+   *   查看文档
+   * 
+ */ + void bindAccount(WxMaExpressBindAccountRequest wxMaExpressBindAccountRequest) throws WxErrorException; + + /** + * 获取电子面单余额。仅在使用加盟类快递公司时,才可以调用。 + * @param wxMaExpressBindAccountRequest 物流账号对象 + * @return 电子面单余额 + * @throws WxErrorException 获取失败时返回 + *
+   *   查看文档
+   * 
+ */ + Integer getQuota(WxMaExpressBindAccountRequest wxMaExpressBindAccountRequest) throws WxErrorException; + + /** + * 配置面单打印员,可以设置多个,若需要使用微信打单 PC 软件,才需要调用。 + * @param wxMaExpressPrinterUpdateRequest 面单打印员对象 + * @throws WxErrorException 请求失败时返回 + *
+   *   查看文档
+   * 
+ */ + void updatePrinter(WxMaExpressPrinterUpdateRequest wxMaExpressPrinterUpdateRequest) throws WxErrorException; + + /** + * 获取打印员。若需要使用微信打单 PC 软件,才需要调用 + * @return 打印员 + * @throws WxErrorException 获取失败时返回 + *
+   *   查看文档
+   * 
+ */ + WxMaExpressPrinter getPrinter() throws WxErrorException; + + /** + * 生成运单 + * @param wxMaExpressAddOrderRequest 生成运单请求对象 + * @return 生成运单结果 + * @throws WxErrorException 请求失败时返回 + *
+   *   查看文档
+   * 
+ */ + WxMaExpressOrderInfoResult addOrder(WxMaExpressAddOrderRequest wxMaExpressAddOrderRequest) throws WxErrorException; + + /** + * 批量获取运单数据 + * @param requests 获取运单请求对象集合,最多不能超过1000个 + * @return 运单信息集合 + * @throws WxErrorException 获取失败时返回 + *
+   *   查看文档
+   * 
+ */ + List batchGetOrder(List requests) throws WxErrorException; + + /** + * 取消运单 + * @param wxMaExpressGetOrderRequest 运单信息请求对象 + * @throws WxErrorException 取消失败时返回 + *
+   *   查看文档
+   * 
+ */ + void cancelOrder(WxMaExpressGetOrderRequest wxMaExpressGetOrderRequest) throws WxErrorException; + + /** + * 获取运单数据 + * @param wxMaExpressGetOrderRequest 运单信息请求对象 + * @return 运单信息 + * @throws WxErrorException 获取失败时返回 + *
+   *   查看文档
+   * 
+ */ + WxMaExpressOrderInfoResult getOrder(WxMaExpressGetOrderRequest wxMaExpressGetOrderRequest) throws WxErrorException; + + /** + * 查询运单轨迹 + * @param wxMaExpressGetOrderRequest 运单信息请求对象 + * @return 运单轨迹对象 + * @throws WxErrorException 查询失败时返回 + *
+   *   查看文档
+   * 
+ */ + WxMaExpressPath getPath(WxMaExpressGetOrderRequest wxMaExpressGetOrderRequest) throws WxErrorException; + + /** + * 模拟快递公司更新订单状态, 该接口只能用户测试 + * @param wxMaExpressTestUpdateOrderRequest 模拟快递公司更新订单状态请求对象 + * @throws WxErrorException 模拟更新订单状态失败时返回 + *
+   *   查看文档
+   * 
+ */ + void testUpdateOrder(WxMaExpressTestUpdateOrderRequest wxMaExpressTestUpdateOrderRequest) throws WxErrorException; +} 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 52988f36e2..695590a6b2 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 @@ -224,5 +224,9 @@ public interface WxMaService { */ RequestHttp getRequestHttp(); - + /** + * 获取物流助手接口服务对象 + * @return + */ + WxMaExpressService getExpressService(); } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaExpressServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaExpressServiceImpl.java new file mode 100644 index 0000000000..21d0bfe0b0 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaExpressServiceImpl.java @@ -0,0 +1,98 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaExpressService; +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.express.WxMaExpressAccount; +import cn.binarywang.wx.miniapp.bean.express.WxMaExpressDelivery; +import cn.binarywang.wx.miniapp.bean.express.WxMaExpressPath; +import cn.binarywang.wx.miniapp.bean.express.WxMaExpressPrinter; +import cn.binarywang.wx.miniapp.bean.express.request.*; +import cn.binarywang.wx.miniapp.bean.express.result.WxMaExpressOrderInfoResult; +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import lombok.AllArgsConstructor; +import me.chanjar.weixin.common.error.WxErrorException; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @author xiaoyu + * @since 2019-11-26 + */ +@AllArgsConstructor +public class WxMaExpressServiceImpl implements WxMaExpressService { + + private WxMaService wxMaService; + + @Override + public List getAllDelivery() throws WxErrorException { + String responseContent = this.wxMaService.get(ALL_DELIVERY_URL, null); + return WxMaExpressDelivery.fromJson(responseContent); + } + + @Override + public List getAllAccount() throws WxErrorException { + String responseContent = this.wxMaService.get(ALL_ACCOUNT_URL, null); + return WxMaExpressAccount.fromJsonList(responseContent); + } + + @Override + public void bindAccount(WxMaExpressBindAccountRequest wxMaExpressBindAccountRequest) throws WxErrorException { + this.wxMaService.post(BIND_ACCOUNT_URL,wxMaExpressBindAccountRequest.toJson()); + } + + @Override + public Integer getQuota(WxMaExpressBindAccountRequest wxMaExpressBindAccountRequest) throws WxErrorException { + String responseContent = this.wxMaService.post(GET_QUOTA_URL,wxMaExpressBindAccountRequest.toJson()); + WxMaExpressAccount account = WxMaExpressAccount.fromJson(responseContent); + return account.getQuotaNum(); + } + + @Override + public void updatePrinter(WxMaExpressPrinterUpdateRequest wxMaExpressPrinterUpdateRequest) throws WxErrorException { + this.wxMaService.post(UPDATE_PRINTER_URL,wxMaExpressPrinterUpdateRequest.toJson()); + } + + @Override + public WxMaExpressPrinter getPrinter() throws WxErrorException { + String responseContent = this.wxMaService.get(GET_PRINTER_URL, null); + return WxMaExpressPrinter.fromJson(responseContent); + } + + @Override + public WxMaExpressOrderInfoResult addOrder(WxMaExpressAddOrderRequest wxMaExpressAddOrderRequest) throws WxErrorException { + String responseContent = this.wxMaService.post(ADD_ORDER_URL,wxMaExpressAddOrderRequest.toJson()); + return WxMaExpressOrderInfoResult.fromJson(responseContent); + } + + @Override + public List batchGetOrder(List requests) throws WxErrorException { + Map param = new HashMap<>(1); + param.put("order_list", requests); + String responseContent = this.wxMaService.post(BATCH_GET_ORDER_URL, WxMaGsonBuilder.create().toJson(param)); + return WxMaExpressOrderInfoResult.toList(responseContent); + } + + @Override + public void cancelOrder(WxMaExpressGetOrderRequest wxMaExpressGetOrderRequest) throws WxErrorException { + this.wxMaService.post(CANCEL_ORDER_URL,wxMaExpressGetOrderRequest.toJson()); + } + + @Override + public WxMaExpressOrderInfoResult getOrder(WxMaExpressGetOrderRequest wxMaExpressGetOrderRequest) throws WxErrorException { + String responseContent = this.wxMaService.post(GET_ORDER_URL,wxMaExpressGetOrderRequest.toJson()); + return WxMaExpressOrderInfoResult.fromJson(responseContent); + } + + @Override + public WxMaExpressPath getPath(WxMaExpressGetOrderRequest wxMaExpressGetOrderRequest) throws WxErrorException { + String responseContent = this.wxMaService.post(GET_PATH_URL,wxMaExpressGetOrderRequest.toJson()); + return WxMaExpressPath.fromJson(responseContent); + } + + @Override + public void testUpdateOrder(WxMaExpressTestUpdateOrderRequest wxMaExpressTestUpdateOrderRequest) throws WxErrorException { + this.wxMaService.post(TEST_UPDATE_ORDER_URL,wxMaExpressTestUpdateOrderRequest.toJson()); + } +} 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 44ba6258d7..0a6da86143 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 @@ -54,6 +54,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp + * 物流账号对象 + *
+ * @author xiaoyu + * @since 2019-11-26 + */ +@Data +public class WxMaExpressAccount implements Serializable { + + private static final JsonParser JSON_PARSER = new JsonParser(); + private static final long serialVersionUID = -4991983596742569736L; + + /** + * 快递公司客户编码 + */ + @SerializedName("biz_id") + private String bizId; + + /** + * 快递公司ID + */ + @SerializedName("delivery_id") + private String deliveryId; + + /** + * 账号绑定时间 + */ + @SerializedName("create_time") + private Long createTime; + + /** + * 账号更新时间 + */ + @SerializedName("update_time") + private Long updateTime; + + /** + * 绑定状态 + * status_code 的合法值 : 0-绑定成功;1-审核中;2-绑定失败 + */ + @SerializedName("status_code") + private Integer statusCode; + + /** + * 账号别名 + */ + @SerializedName("alias") + private String alias; + + /** + * 账号绑定失败的错误信息(EMS审核结果) + */ + @SerializedName("remark_wrong_msg") + private String remarkWrongMsg; + + /** + * 账号绑定时的备注内容(提交EMS审核需要) + */ + @SerializedName("remark_content") + private String remarkContent; + + /** + * 电子面单余额 + */ + @SerializedName("quota_num") + private Integer quotaNum; + + /** + * 电子面单余额更新时间 + */ + @SerializedName("quota_update_time") + private Integer quotaUpdateTime; + + /** + * 支持的服务类型 + */ + @SerializedName("service_type") + private List serviceType; + + public static List fromJsonList(String json) { + JsonObject jsonObject = JSON_PARSER.parse(json).getAsJsonObject(); + return WxMaGsonBuilder.create().fromJson(jsonObject.get("list").toString(), + new TypeToken>() { + }.getType()); + } + + public static WxMaExpressAccount fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaExpressAccount.class); + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/WxMaExpressDelivery.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/WxMaExpressDelivery.java new file mode 100644 index 0000000000..1127479b4c --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/WxMaExpressDelivery.java @@ -0,0 +1,83 @@ +package cn.binarywang.wx.miniapp.bean.express; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ * 快递公司对象
+ * 
+ * @author xiaoyu + * @since 2019-11-26 + */ +@Data +public class WxMaExpressDelivery implements Serializable { + private static final JsonParser JSON_PARSER = new JsonParser(); + private static final long serialVersionUID = -8394544895730223810L; + + /** + * 快递公司 ID + */ + @SerializedName("delivery_id") + private String deliveryId; + + /** + * 快递公司名称 + */ + @SerializedName("delivery_name") + private String deliveryName; + + /** + * 是否支持散单, 1表示支持 + */ + @SerializedName("can_use_cash") + private Integer canUseCash; + + /** + * 是否支持查询面单余额, 1表示支持 + */ + @SerializedName("can_get_quota") + private Integer canGetQuota; + + /** + * 散单对应的bizid,当can_use_cash=1时有效 + */ + @SerializedName("cash_biz_id") + private String cashBizId; + + /** + * 支持的服务类型 + */ + @SerializedName("service_type") + private List serviceType; + + public static List fromJson(String json) { + JsonObject jsonObject = JSON_PARSER.parse(json).getAsJsonObject(); + return WxMaGsonBuilder.create().fromJson(jsonObject.get("data").toString(), + new TypeToken>() { + }.getType()); + } + + @Data + public static class ServiceType{ + + /** + * 服务类型ID + */ + @SerializedName("service_type") + private Integer serviceType; + + /** + * 服务类型名称 + */ + @SerializedName("service_name") + private String serviceName; + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/WxMaExpressPath.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/WxMaExpressPath.java new file mode 100644 index 0000000000..ba5a903f4d --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/WxMaExpressPath.java @@ -0,0 +1,75 @@ +package cn.binarywang.wx.miniapp.bean.express; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 运单轨迹对象 + * @author xiaoyu + * @since 2019-11-26 + */ +@Data +public class WxMaExpressPath implements Serializable { + + private static final long serialVersionUID = 5643624677715536605L; + + /** + * 用户openid + */ + private String openid; + + /** + * 快递公司 ID + */ + @SerializedName("delivery_id") + private String deliveryId; + + /** + * 运单 ID + */ + @SerializedName("waybill_id") + private String waybillId; + + /** + * 轨迹节点数量 + */ + @SerializedName("path_item_num") + private Integer pathItemNum; + + /** + * 轨迹节点列表 + */ + @SerializedName("path_item_list") + private List pathItemList; + + public static WxMaExpressPath fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaExpressPath.class); + } + + @Data + private static class PathItem{ + + /** + * 轨迹节点 Unix 时间戳 + */ + @SerializedName("action_time") + private Long actionTime; + + /** + * 轨迹节点类型 + */ + @SerializedName("action_type") + private Integer actionType; + + /** + * 轨迹节点详情 + */ + @SerializedName("action_msg") + private String actionMsg; + + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/WxMaExpressPrinter.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/WxMaExpressPrinter.java new file mode 100644 index 0000000000..832fa2e376 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/WxMaExpressPrinter.java @@ -0,0 +1,44 @@ +package cn.binarywang.wx.miniapp.bean.express; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.JsonParser; +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ * 面单打印员对象
+ * 
+ * @author xiaoyu + * @since 2019-11-26 + */ +@Data +public class WxMaExpressPrinter implements Serializable { + + private static final JsonParser JSON_PARSER = new JsonParser(); + private static final long serialVersionUID = 7164449984700322531L; + + /** + * 数量 + */ + private Integer count; + + /** + * 打印员openid + */ + private List openid; + + /** + * 打印员面单打印权限 + */ + @SerializedName("tagid_list") + private List tagidList; + + + public static WxMaExpressPrinter fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaExpressPrinter.class); + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressAddOrderRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressAddOrderRequest.java new file mode 100644 index 0000000000..4b404e332b --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressAddOrderRequest.java @@ -0,0 +1,169 @@ +package cn.binarywang.wx.miniapp.bean.express.request; + + +import cn.binarywang.wx.miniapp.bean.express.*; +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + *
+ * 生成运单请求对象
+ * 
+ * @author xiaoyu + * @since 2019-11-26 + */ +@Data +@Builder +public class WxMaExpressAddOrderRequest implements Serializable { + + private static final long serialVersionUID = -7538739003766268386L; + + + /** + * 订单来源 + *
+   * 是否必填: 是
+   * 描述: 0为小程序订单,2为App或H5订单,填2则不发送物流服务通知
+   * 
+ */ + @SerializedName("add_source") + private Integer addSource; + + /** + * App或H5的appid + *
+   * 是否必填: 否
+   * 描述: add_source=2时必填,需和开通了物流助手的小程序绑定同一open帐号
+   * 
+ */ + @SerializedName("wx_appid") + private String wxAppid; + + /** + * 订单ID + *
+   * 是否必填: 是
+   * 描述: 须保证全局唯一,不超过512字节
+   * 
+ */ + @SerializedName("order_id") + private String orderId; + + /** + * 用户openid + *
+   * 是否必填: 否
+   * 描述: 当add_source=2时无需填写(不发送物流服务通知)
+   * 
+ */ + @SerializedName("openid") + private String openid; + + /** + * 快递公司ID + *
+   * 是否必填: 是
+   * 描述: 可通过getAllDelivery查询
+   * 
+ */ + @SerializedName("delivery_id") + private String deliveryId; + + /** + * 快递客户编码或者现付编码 + *
+   * 是否必填: 是
+   * 
+ */ + @SerializedName("biz_id") + private String bizId; + + /** + * 快递备注信息 + *
+   * 是否必填: 否
+   * 描述: 比如"易碎物品",不超过1024字节
+   * 
+ */ + @SerializedName("custom_remark") + private String customRemark; + + /** + * 订单标签id + *
+   * 是否必填: 否
+   * 描述: 用于平台型小程序区分平台上的入驻方,tagid须与入驻方账号一一对应,非平台型小程序无需填写该字段
+   * 
+ */ + @SerializedName("tagid") + private Integer tagid; + + /** + * 预期的上门揽件时间 + *
+   * 是否必填: 否
+   * 描述: 顺丰必须传,0表示已事先约定取件时间;否则请传预期揽件时间戳,需大于当前时间,收件员会在预期时间附近上门。例如expect_time为“1557989929”,表示希望收件员将在2019年05月16日14:58:49-15:58:49内上门取货。说明:若选择 了预期揽件时间,请不要自己打单,由上门揽件的时候打印。
+   * 
+ */ + @SerializedName("expect_time") + private Long expectTime; + + /** + * 发件人信息 + *
+   * 是否必填: 是
+   * 
+ */ + private WxMaExpressOrderPerson sender; + + /** + * 收件人信息 + *
+   * 是否必填: 是
+   * 
+ */ + private WxMaExpressOrderPerson receiver; + + /** + * 包裹信息 + *
+   * 是否必填: 是
+   * 描述: 将传递给快递公司
+   * 
+ */ + private WxMaExpressOrderCargo cargo; + + /** + * 商品信息 + *
+   * 是否必填: 否
+   * 描述: 会展示到物流服务通知和电子面单中
+   * 
+ */ + private WxMaExpressOrderShop shop; + + /** + * 保价信息 + *
+   * 是否必填: 是
+   * 
+ */ + private WxMaExpressOrderInsured insured; + + /** + * 服务类型 + *
+   * 是否必填: 是
+   * 
+ */ + private WxMaExpressDelivery.ServiceType service; + + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressBindAccountRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressBindAccountRequest.java new file mode 100644 index 0000000000..fe6877fa9f --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressBindAccountRequest.java @@ -0,0 +1,73 @@ +package cn.binarywang.wx.miniapp.bean.express.request; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + *
+ * 绑定、解绑物流账号请求对象
+ * 
+ * @author xiaoyu + * @since 2019-11-26 + */ +@Data +@Builder +public class WxMaExpressBindAccountRequest implements Serializable { + + private static final long serialVersionUID = 3868003945297939946L; + + /** + * 类型 + *
+   * 是否必填: 是
+   * 描述: bind表示绑定,unbind表示解除绑定
+   * 
+ */ + @SerializedName("type") + private String type; + + /** + * 快递公司客户编码 + *
+   * 是否必填: 是
+   * 
+ */ + @SerializedName("biz_id") + private String bizId; + + /** + * 快递公司ID + *
+   * 是否必填: 是
+   * 
+ */ + @SerializedName("delivery_id") + private String deliveryId; + + /** + * 快递公司客户密码 + *
+   * 是否必填: 是
+   * 
+ */ + @SerializedName("password") + private String password; + + /** + * 备注内容(提交EMS审核需要) + *
+   * 是否必填: 是
+   * 
+ */ + @SerializedName("remark_content") + private String remarkContent; + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressGetOrderRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressGetOrderRequest.java new file mode 100644 index 0000000000..b21de172e9 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressGetOrderRequest.java @@ -0,0 +1,63 @@ +package cn.binarywang.wx.miniapp.bean.express.request; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + *
+ * 获取运单请求对象
+ * 
+ * @author xiaoyu + * @since 2019-11-26 + */ +@Data +@Builder +public class WxMaExpressGetOrderRequest implements Serializable { + + private static final long serialVersionUID = 8239315305577639778L; + + /** + * 订单ID + *
+   * 是否必填: 是
+   * 
+ */ + @SerializedName("order_id") + private String orderId; + + /** + * 用户openid + *
+   * 是否必填: 否
+   * 描述: 当add_source=2时无需填写(不发送物流服务通知)
+   * 
+ */ + private String openid; + + /** + * 快递公司ID + *
+   * 是否必填: 是
+   * 
+ */ + @SerializedName("delivery_id") + private String deliveryId; + + /** + * 运单ID + *
+   * 是否必填: 是
+   * 
+ */ + @SerializedName("waybill_id") + private String waybillId; + + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderCargo.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderCargo.java new file mode 100644 index 0000000000..ec2c39709d --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderCargo.java @@ -0,0 +1,74 @@ +package cn.binarywang.wx.miniapp.bean.express.request; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 包裹信息对象 + * @author xiaoyu + * @since 2019-11-26 + */ +@Data +public class WxMaExpressOrderCargo implements Serializable { + + private static final long serialVersionUID = 6642536671375396150L; + + /** + * 包裹数量 + *
+   * 是否必填: 是
+   * 描述: 需要和detail_list size保持一致
+   * 
+ */ + private Integer count; + /** + * 包裹总重量 + *
+   * 是否必填: 是
+   * 描述: 单位是千克(kg)
+   * 
+ */ + private Integer weight; + + /** + * 包裹长度 + *
+   * 是否必填: 是
+   * 描述: 单位是厘米(cm)
+   * 
+ */ + @SerializedName("space_x") + private Integer spaceLength; + + /** + * 包裹宽度 + *
+   * 是否必填: 是
+   * 描述: 单位是厘米(cm)
+   * 
+ */ + @SerializedName("space_y") + private Integer spaceWidth; + + /** + * 包裹高度 + *
+   * 是否必填: 是
+   * 描述: 单位是厘米(cm)
+   * 
+ */ + @SerializedName("space_z") + private Integer spaceHeight; + + /** + * 包裹中商品详情列表 + *
+   * 是否必填: 是
+   * 
+ */ + @SerializedName("detail_list") + private List detailList; +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderCargoDetail.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderCargoDetail.java new file mode 100644 index 0000000000..1e61bba897 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderCargoDetail.java @@ -0,0 +1,33 @@ +package cn.binarywang.wx.miniapp.bean.express.request; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 包裹商品详情对象 + * @author xiaoyu + * @since 2019-11-26 + */ +@Data +public class WxMaExpressOrderCargoDetail implements Serializable { + + private static final long serialVersionUID = 5988620921216969796L; + + /** + * 商品名 + *
+   * 是否必填: 是
+   * 描述: 不超过128字节
+   * 
+ */ + private String name; + + /** + * 商品数量 + *
+   * 是否必填: 是
+   * 
+ */ + private Integer count; +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderInsured.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderInsured.java new file mode 100644 index 0000000000..7a30dacadc --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderInsured.java @@ -0,0 +1,43 @@ +package cn.binarywang.wx.miniapp.bean.express.request; + + +import cn.binarywang.wx.miniapp.constant.WxMaConstants; +import com.google.gson.annotations.SerializedName; +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + * 保价信息对象 + * @author xiaoyu + * @since 2019-11-26 + */ +@Data +@Builder +public class WxMaExpressOrderInsured implements Serializable { + + private static final long serialVersionUID = -8636857630937445422L; + + /** + * 是否保价 + *
+   * 是否必填: 是
+   * 描述: 0 表示不保价,1 表示保价
+   * 
+ */ + @SerializedName("use_insured") + private final Integer useInsured = WxMaConstants.OrderAddInsured.INSURED_PROGRAM; + + /** + * 保价金额 + *
+   * 是否必填: 是
+   * 描述: 单位是分,比如: 10000 表示 100 元
+   * 
+ */ + @SerializedName("insured_value") + @Builder.Default + private final Integer insuredValue = WxMaConstants.OrderAddInsured.DEFAULT_INSURED_VALUE; + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderPerson.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderPerson.java new file mode 100644 index 0000000000..989380fb49 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderPerson.java @@ -0,0 +1,110 @@ +package cn.binarywang.wx.miniapp.bean.express.request; + + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 发件人/收件人信息对象 + * @author xiaoyu + * @since 2019-11-26 + */ +@Data +public class WxMaExpressOrderPerson implements Serializable { + + private static final long serialVersionUID = -7816060207882761506L; + + /** + * 发件人/收件人姓名 + *
+   * 是否必填: 是
+   * 描述: 不超过64字节
+   * 
+ */ + private String name; + + /** + * 发件人/收件人座机号码 + *
+   * 是否必填: 否
+   * 描述: 若不填写则必须填写 mobile,不超过32字节
+   * 
+ */ + private String tel; + + /** + * 发件人/收件人手机号码 + *
+   * 是否必填: 否
+   * 描述: 若不填写则必须填写 tel,不超过32字节
+   * 
+ */ + private String mobile; + + /** + * 发件人/收件人公司名 + *
+   * 是否必填: 否
+   * 描述: 不超过64字节
+   * 
+ */ + private String company; + + /** + * 发件人/收件人邮编 + *
+   * 是否必填: 否
+   * 描述: 不超过10字节
+   * 
+ */ + @SerializedName("post_code") + private String postCode; + + /** + * 发件人/收件人所在国家 + *
+   * 是否必填: 否
+   * 描述: 不超过64字节
+   * 
+ */ + private String country; + + /** + * 发件人/收件人省份 + *
+   * 是否必填: 是
+   * 描述: 比如:"广东省",不超过64字节
+   * 
+ */ + private String province; + + /** + * 发件人/收件人地区或市 + *
+   * 是否必填: 是
+   * 描述: 比如:"广州市",不超过64字节
+   * 
+ */ + private String city; + + /** + * 发件人/收件人区或县 + *
+   * 是否必填: 是
+   * 描述: 比如:"天河区",不超过64字节
+   * 
+ */ + private String area; + + /** + * 发件人/收件人详细地址 + *
+   * 是否必填: 是
+   * 描述: 比如:"XX路XX号XX大厦XX",不超过512字节
+   * 
+ */ + private String address; + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderShop.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderShop.java new file mode 100644 index 0000000000..9b1e3d884c --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressOrderShop.java @@ -0,0 +1,55 @@ +package cn.binarywang.wx.miniapp.bean.express.request; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 商品信息对象 + * @author xiaoyu + * @since 2019-11-26 + */ +@Data +public class WxMaExpressOrderShop implements Serializable { + + private static final long serialVersionUID = 7256509453502211830L; + + /** + * 商家小程序的路径 + *
+   * 是否必填: 是
+   * 描述: 建议为订单页面
+   * 
+ */ + @SerializedName("wxa_path") + private String wxaPath; + + /** + * 商品缩略图url + *
+   * 是否必填: 是
+   * 
+ */ + @SerializedName("img_url") + private String imgUrl; + + /** + * 商品名称 + *
+   * 是否必填: 是
+   * 
+ */ + @SerializedName("goods_name") + private String goodsName; + + /** + * 商品数量 + *
+   * 是否必填: 是
+   * 
+ */ + @SerializedName("goods_count") + private Integer goodsCount; + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressPrinterUpdateRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressPrinterUpdateRequest.java new file mode 100644 index 0000000000..a5f9f50dbf --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressPrinterUpdateRequest.java @@ -0,0 +1,54 @@ +package cn.binarywang.wx.miniapp.bean.express.request; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + *
+ * 配置面单打印员请求对象
+ * 
+ * @author xiaoyu + * @since 2019-11-26 + */ +@Data +@Builder +public class WxMaExpressPrinterUpdateRequest implements Serializable { + + private static final long serialVersionUID = 9119040050963924127L; + + /** + * 打印员 openid + *
+   * 是否必填: 是
+   * 
+ */ + private String openid; + + /** + * 更新类型 + *
+   * 是否必填: 是
+   * 描述: bind表示绑定,unbind表示解除绑定
+   * 
+ */ + @SerializedName("update_type") + private String updateType; + + /** + * 打印员面单打印权限 + *
+   * 是否必填: 否
+   * 描述: 用于平台型小程序设置入驻方的打印员面单打印权限,同一打印员最多支持10个tagid,使用逗号分隔,如填写123,456,表示该打印员可以拉取到tagid为123和456的下的单,非平台型小程序无需填写该字段
+   * 
+ */ + @SerializedName("tagid_list") + private String tagidList; + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressTestUpdateOrderRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressTestUpdateOrderRequest.java new file mode 100644 index 0000000000..e5d4cb448b --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/request/WxMaExpressTestUpdateOrderRequest.java @@ -0,0 +1,94 @@ +package cn.binarywang.wx.miniapp.bean.express.request; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.annotations.SerializedName; +import lombok.Builder; +import lombok.Data; + +import java.io.Serializable; + +/** + *
+ * 模拟快递公司更新订单状态请求对象
+ * 
+ * @author xiaoyu + * @since 2019-11-26 + */ +@Data +@Builder +public class WxMaExpressTestUpdateOrderRequest implements Serializable { + + private static final long serialVersionUID = -3701602332580704140L; + + /** + * 商户id + *
+   * 是否必填: 是
+   * 描述: 需填test_biz_id,默认值已设置
+   * 
+ */ + @SerializedName("biz_id") + @Builder.Default + private final String bizId = "test_biz_id"; + + /** + * 快递公司id + *
+   * 是否必填: 是
+   * 描述: 需填TEST,默认值已设置
+   * 
+ */ + @SerializedName("delivery_id") + @Builder.Default + private final String deliveryId = "TEST"; + + /** + * 订单号 + *
+   * 是否必填: 是
+   * 
+ */ + @SerializedName("order_id") + private String orderId; + + /** + * 运单号 + *
+   * 是否必填: 是
+   * 
+ */ + @SerializedName("waybill_id") + private String waybillId; + + /** + * 轨迹变化 Unix 时间戳 + *
+   * 是否必填: 是
+   * 
+ */ + @SerializedName("action_time") + private Long actionTime; + + /** + * 轨迹变化类型 + *
+   * 是否必填: 是
+   * 
+ */ + @SerializedName("action_type") + private Integer actionType; + + /** + * 轨迹变化具体信息说明,使用UTF-8编码 + *
+   * 是否必填: 是
+   * 
+ */ + @SerializedName("action_msg") + private String actionMsg; + + public String toJson() { + return WxMaGsonBuilder.create().toJson(this); + } + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/result/WxMaExpressOrderInfoResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/result/WxMaExpressOrderInfoResult.java new file mode 100644 index 0000000000..01f274fb9c --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/express/result/WxMaExpressOrderInfoResult.java @@ -0,0 +1,70 @@ +package cn.binarywang.wx.miniapp.bean.express.result; + +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.annotations.SerializedName; +import com.google.gson.reflect.TypeToken; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + *
+ * 运单信息返回结果对象
+ * 
+ * @author xiaoyu + * @since 2019-11-26 + */ +@Data +public class WxMaExpressOrderInfoResult implements Serializable { + private static final JsonParser JSON_PARSER = new JsonParser(); + private static final long serialVersionUID = -9166603059965942285L; + + /** + * 错误码 + */ + private Integer errcode; + + /** + * 错误信息 + */ + private String errmsg; + /** + * 订单ID + */ + @SerializedName("order_id") + private String orderId; + + /** + * 运单ID + */ + @SerializedName("waybill_id") + private String waybillId; + + /** + * 运单 html 的 BASE64 结果 + */ + @SerializedName("print_html") + private String printHtml; + + /** + * 运单信息 + */ + @SerializedName("waybill_data") + private List> waybillData; + + + public static WxMaExpressOrderInfoResult fromJson(String json) { + return WxMaGsonBuilder.create().fromJson(json, WxMaExpressOrderInfoResult.class); + } + + public static List toList(String json) { + JsonObject jsonObject = JSON_PARSER.parse(json).getAsJsonObject(); + return WxMaGsonBuilder.create().fromJson(jsonObject.get("order_list").toString(), + new TypeToken>() { + }.getType()); + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java index efd2b22916..2c89b8a02e 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java @@ -85,4 +85,56 @@ public static final class SecCheckMediaType { */ public static final int IMAGE = 2; } + + /** + * 快递账号绑定类型 + */ + public static final class BindAccountType{ + + /** + * 绑定 + */ + public static final String BIND = "bind"; + + /** + * 解绑 + */ + public static final String UNBIND = "unbind"; + } + + /** + * 快递下单订单来源 + */ + public static final class OrderAddSource{ + + /** + * 小程序 + */ + public static final int MINI_PROGRAM = 0; + + /** + * APP或H5 + */ + public static final int APP_OR_H5 = 2; + } + + /** + * 快递下单保价 + */ + public static final class OrderAddInsured{ + /** + * 不保价 + */ + public static final int INSURED_PROGRAM = 0; + + /** + * 保价 + */ + public static final int USE_INSURED = 1; + + /** + * 默认保价金额 + */ + public static final int DEFAULT_INSURED_VALUE = 0; + } } diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaExpressServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaExpressServiceImplTest.java new file mode 100644 index 0000000000..6991ad9c25 --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaExpressServiceImplTest.java @@ -0,0 +1,231 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaExpressService; +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.express.*; +import cn.binarywang.wx.miniapp.bean.express.request.*; +import cn.binarywang.wx.miniapp.bean.express.result.WxMaExpressOrderInfoResult; +import cn.binarywang.wx.miniapp.constant.WxMaConstants; +import cn.binarywang.wx.miniapp.test.ApiTestModule; +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; +import com.google.inject.Inject; +import me.chanjar.weixin.common.error.WxErrorException; +import org.apache.commons.lang3.StringUtils; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.List; + + +@Guice(modules = ApiTestModule.class) +public class WxMaExpressServiceImplTest { + + @Inject + private WxMaService wxMaService; + + @Test + public void testGetAllDelivery() throws WxErrorException { + final WxMaExpressService service = wxMaService.getExpressService(); + List list = service.getAllDelivery(); + System.out.println(WxMaGsonBuilder.create().toJson(list)); + } + + @Test + public void testGetAllAccount() throws WxErrorException { + final WxMaExpressService service = wxMaService.getExpressService(); + List list = service.getAllAccount(); + System.out.println(WxMaGsonBuilder.create().toJson(list)); + } + + @Test + public void testBindAccount() throws WxErrorException { + final WxMaExpressService service = wxMaService.getExpressService(); + WxMaExpressBindAccountRequest request = WxMaExpressBindAccountRequest.builder() + .deliveryId("YUNDA") + .bizId("******") + .password("*********") + .remarkContent("####") + .type(WxMaConstants.BindAccountType.BIND) + .build(); + service.bindAccount(request); + } + + @Test + public void testGetQuota() throws WxErrorException { + final WxMaExpressService service = wxMaService.getExpressService(); + WxMaExpressBindAccountRequest request = WxMaExpressBindAccountRequest.builder() + .deliveryId("YUNDA") + .bizId("******") + .build(); + Integer quotaNum = service.getQuota(request); + System.out.println(quotaNum); + } + + + + @Test + public void testUpdatePrinter() throws WxErrorException { + final WxMaExpressService service = wxMaService.getExpressService(); + WxMaExpressPrinterUpdateRequest request = WxMaExpressPrinterUpdateRequest.builder() + .openid("*************") + .updateType(WxMaConstants.BindAccountType.UNBIND) + .build(); + service.updatePrinter(request); + } + + @Test + public void testGetPrinter() throws WxErrorException { + final WxMaExpressService service = wxMaService.getExpressService(); + WxMaExpressPrinter printer = service.getPrinter(); + System.out.println(WxMaGsonBuilder.create().toJson(printer)); + } + + @Test + public void testAddOrder() throws WxErrorException { + final WxMaExpressService service = wxMaService.getExpressService(); + + WxMaExpressOrderPerson sender = new WxMaExpressOrderPerson(); + sender.setName("张三"); + sender.setMobile("177****9809"); + sender.setProvince("北京市"); + sender.setCity("朝阳区"); + sender.setArea("朝阳区"); + sender.setAddress("西坝河****C-102"); + + WxMaExpressOrderPerson receiver = new WxMaExpressOrderPerson(); + receiver.setName("李四"); + receiver.setMobile("180****8772"); + receiver.setProvince("北京市"); + receiver.setCity("朝阳区"); + receiver.setArea("朝阳区"); + receiver.setAddress("西坝河北里****101"); + + + WxMaExpressOrderCargo cargo = new WxMaExpressOrderCargo(); + List detailList = new ArrayList<>(); + List shopNames = new ArrayList<>(); + Integer goodsCount = 0; + for (int i = 0; i < 4; i++) { + WxMaExpressOrderCargoDetail detail = new WxMaExpressOrderCargoDetail(); + String shopName = "商品_"+i; + detail.setName(shopName); + detail.setCount(1); + detailList.add(detail); + shopNames.add(shopName); + goodsCount ++; + } + cargo.setCount(detailList.size()); + cargo.setWeight(5); + cargo.setSpaceHeight(10); + cargo.setSpaceLength(10); + cargo.setSpaceWidth(10); + cargo.setDetailList(detailList); + + + WxMaExpressOrderShop shop = new WxMaExpressOrderShop(); + shop.setWxaPath("/index/index?from=waybill&id=01234567890123456789"); + shop.setGoodsName(StringUtils.join(shopNames,"&")); + shop.setGoodsCount(goodsCount); + shop.setImgUrl("https://mmbiz.qpic.cn/mmbiz_png/OiaFLUqewuIDNQnTiaCInIG8ibdosYHhQHPbXJUrqYSNIcBL60vo4LIjlcoNG1QPkeH5GWWEB41Ny895CokeAah8A/640"); + + WxMaExpressDelivery.ServiceType serviceType = new WxMaExpressDelivery.ServiceType(); + serviceType.setServiceName("test_service_name"); + serviceType.setServiceType(1); + + WxMaExpressAddOrderRequest request = WxMaExpressAddOrderRequest.builder() + .addSource(WxMaConstants.OrderAddSource.MINI_PROGRAM) + .orderId("test201911271429004") + .openid("oAg_-0PDUPuLbQw9V9kXE9OkU-Vo") + .deliveryId("TEST") + .bizId("test_biz_id") + .customRemark("") + .expectTime(0L) + .sender(sender) + .receiver(receiver) + .cargo(cargo) + .shop(shop) + .insured(WxMaExpressOrderInsured.builder().build()) + .service(serviceType) + .build(); + + WxMaExpressOrderInfoResult result = service.addOrder(request); + System.out.println(WxMaGsonBuilder.create().toJson(result)); + } + + @Test + public void testBatchGetOrder() throws WxErrorException { + final WxMaExpressService service = wxMaService.getExpressService(); + List requests = new ArrayList<>(); + + List orderIds = new ArrayList<>(); + orderIds.add("test201911271429000"); + + List waybillIds = new ArrayList<>(); + waybillIds.add("test201911271429000_1574836404_waybill_id"); + for (int i = 0; i < orderIds.size(); i++) { + WxMaExpressGetOrderRequest request = WxMaExpressGetOrderRequest.builder() + .orderId(orderIds.get(i)) + .deliveryId("TEST") + .waybillId(waybillIds.get(i)) + .build(); + requests.add(request); + } + + List results = service.batchGetOrder(requests); + System.out.println(WxMaGsonBuilder.create().toJson(results)); + } + + @Test + public void testCancelOrder() throws WxErrorException { + final WxMaExpressService service = wxMaService.getExpressService(); + WxMaExpressGetOrderRequest request = WxMaExpressGetOrderRequest.builder() + .orderId("test201911271429000") + .deliveryId("TEST") + .waybillId("test201911271429000_1574836404_waybill_id") + .openid("oAg_-0PDUPuLbQw9V9kXE9OkU-Vo") + .build(); + service.cancelOrder(request); + } + + + @Test + public void testGetOrder() throws WxErrorException { + final WxMaExpressService service = wxMaService.getExpressService(); + WxMaExpressGetOrderRequest request = WxMaExpressGetOrderRequest.builder() + .orderId("test201911271429000") + .deliveryId("TEST") + .waybillId("test201911271429000_1574836404_waybill_id") + .openid("oAg_-0PDUPuLbQw9V9kXE9OkU-Vo") + .build(); + WxMaExpressOrderInfoResult result = service.getOrder(request); + System.out.println(WxMaGsonBuilder.create().toJson(result)); + } + + + @Test + public void testGetPath() throws WxErrorException { + final WxMaExpressService service = wxMaService.getExpressService(); + WxMaExpressGetOrderRequest request = WxMaExpressGetOrderRequest.builder() + .orderId("test201911271429000") + .deliveryId("TEST") + .waybillId("test201911271429000_1574836404_waybill_id") + .openid("oAg_-0PDUPuLbQw9V9kXE9OkU-Vo") + .build(); + WxMaExpressPath path = service.getPath(request); + System.out.println(WxMaGsonBuilder.create().toJson(path)); + } + + @Test + public void testTestUpdateOrder() throws WxErrorException { + final WxMaExpressService service = wxMaService.getExpressService(); + WxMaExpressTestUpdateOrderRequest request = WxMaExpressTestUpdateOrderRequest.builder() + .orderId("test201911271429000") + .waybillId("test201911271429000_1574836404_waybill_id") + .actionTime(1574850455L) + .actionType(300002) + .actionMsg("开始派送") + .build(); + service.testUpdateOrder(request); + } +} From 46e9a39c2fb82fea24ba3103f478cd61d8f20f8f Mon Sep 17 00:00:00 2001 From: 007gzs <007gzs@gmail.com> Date: Thu, 28 Nov 2019 10:27:23 +0800 Subject: [PATCH 0004/1706] =?UTF-8?q?:art:=20#1303=20=E5=BC=80=E6=94=BE?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0WxOpenInnerConfigStorage=E4=B8=AD=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=88=B7=E6=96=B0token=E9=85=8D=E7=BD=AE=E6=B2=BF?= =?UTF-8?q?=E7=94=A8WxOpenConfigStorage=E4=B8=AD=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/open/api/impl/WxOpenInMemoryConfigStorage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 c981147033..e67cb29e6d 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 @@ -546,7 +546,7 @@ public ApacheHttpClientBuilder getApacheHttpClientBuilder() { @Override public boolean autoRefreshToken() { - return true; + return wxOpenConfigStorage.autoRefreshToken(); } @Override From e8a9d00a362e06c3030bac5577e0efe8f9741254 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 28 Nov 2019 13:57:44 +0800 Subject: [PATCH 0005/1706] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/common/util/http/SimplePostRequestExecutor.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimplePostRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimplePostRequestExecutor.java index 692387f9f2..1209790b65 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimplePostRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimplePostRequestExecutor.java @@ -1,15 +1,14 @@ package me.chanjar.weixin.common.util.http; -import java.io.IOException; - import me.chanjar.weixin.common.WxType; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.util.http.apache.ApacheSimplePostRequestExecutor; import me.chanjar.weixin.common.util.http.jodd.JoddHttpSimplePostRequestExecutor; import me.chanjar.weixin.common.util.http.okhttp.OkHttpSimplePostRequestExecutor; +import java.io.IOException; + /** - * 用装饰模式实现 * 简单的POST请求执行器,请求的参数是String, 返回的结果也是String * * @author Daniel Qian From 9317366def54524262427ec2bd68efe425789bdb Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 1 Dec 2019 16:55:55 +0800 Subject: [PATCH 0006/1706] =?UTF-8?q?:sparkles:=20#1033=20=E5=BE=AE?= =?UTF-8?q?=E4=BF=A1=E6=94=AF=E4=BB=98=E5=A2=9E=E5=8A=A0=E5=8F=91=E9=80=81?= =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E7=BA=A2=E5=8C=85=E7=9A=84=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WxPaySendMiniProgramRedpackRequest.java | 112 ++++++++++++++++++ .../WxPaySendMiniProgramRedpackResult.java | 56 +++++++++ .../wxpay/service/WxPayService.java | 28 +++-- .../service/impl/BaseWxPayServiceImpl.java | 14 ++- .../impl/BaseWxPayServiceImplTest.java | 78 ++++++------ 5 files changed, 239 insertions(+), 49 deletions(-) create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendMiniProgramRedpackRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendMiniProgramRedpackResult.java diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendMiniProgramRedpackRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendMiniProgramRedpackRequest.java new file mode 100644 index 0000000000..4215399d4a --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendMiniProgramRedpackRequest.java @@ -0,0 +1,112 @@ +package com.github.binarywang.wxpay.bean.request; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.*; +import lombok.experimental.Accessors; + +/** + * 发送小程序红包请求参数对象. + * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@AllArgsConstructor +@Builder +@XStreamAlias("xml") +@Accessors(chain = true) +public class WxPaySendMiniProgramRedpackRequest extends BaseWxPayRequest { + private static final long serialVersionUID = -2035425086824987567L; + + @Override + protected String[] getIgnoredParamsForSign() { + return new String[]{"sign_type", "sub_appid"}; + } + + /** + * mch_billno. + * 商户订单号(每个订单号必须唯一) + * 组成:mch_id+yyyymmdd+10位一天内不能重复的数字。 接口根据商户订单号支持重入,如出现超时可再调用。 + */ + @XStreamAlias("mch_billno") + private String mchBillNo; + + /** + * send_name. + * 商户名称 + * 红包发送者名称 + */ + @XStreamAlias("send_name") + private String sendName; + + /** + * re_openid. + * 接受红包的用户 用户在wxappid下的openid + */ + @XStreamAlias("re_openid") + private String reOpenid; + + /** + * total_amount. + * 红包总额 + */ + @XStreamAlias("total_amount") + private Integer totalAmount; + + /** + * total_num + * 红包发放总人数 + */ + @XStreamAlias("total_num") + private Integer totalNum; + + /** + * wishing. + * 红包祝福语 + */ + @XStreamAlias("wishing") + private String wishing; + + /** + * act_name. + * 活动名称 + */ + @XStreamAlias("act_name") + private String actName; + + /** + * remark. + * 备注 + */ + @XStreamAlias("remark") + private String remark; + + /** + * 通知用户形式 . + * 通过JSAPI方式领取红包,小程序红包固定传MINI_PROGRAM_JSAPI + */ + @XStreamAlias("notify_way") + private String notifyWay = "MINI_PROGRAM_JSAPI"; + + /** + *
+   * 发放红包使用场景,红包金额大于200时必传
+   * PRODUCT_1:商品促销
+   * PRODUCT_2:抽奖
+   * PRODUCT_3:虚拟物品兑奖
+   * PRODUCT_4:企业内部福利
+   * PRODUCT_5:渠道分润
+   * PRODUCT_6:保险回馈
+   * PRODUCT_7:彩票派奖
+   * PRODUCT_8:税务刮奖
+   * 
+ */ + @XStreamAlias("scene_id") + private String sceneId; + + @Override + protected void checkConstraints() { + + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendMiniProgramRedpackResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendMiniProgramRedpackResult.java new file mode 100644 index 0000000000..bb9bfee8a1 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendMiniProgramRedpackResult.java @@ -0,0 +1,56 @@ +package com.github.binarywang.wxpay.bean.result; + +import com.thoughtworks.xstream.annotations.XStreamAlias; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 发送小程序红包的返回结果 + * + * @author Binary Wang + */ +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +@XStreamAlias("xml") +public class WxPaySendMiniProgramRedpackResult extends BaseWxPayResult implements Serializable { + /** + * 商户订单号. + */ + @XStreamAlias("mch_billno") + private String mchBillNo; + + /** + * 公众账号appid. + */ + @XStreamAlias("wxappid") + private String wxAppid; + + /** + * 用户openid. + */ + @XStreamAlias("re_openid") + private String reOpenid; + + /** + * 付款金额. + */ + @XStreamAlias("total_amount") + private int totalAmount; + + /** + * 返回jaspi的入参package的值. + */ + @XStreamAlias("package") + private String packageName; + + /** + * 微信单号. + */ + @XStreamAlias("send_listid") + private String sendListId; + +} 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 d3fc4be7ff..0534058138 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 @@ -1,16 +1,7 @@ package com.github.binarywang.wxpay.service; -import java.io.File; -import java.util.Date; -import java.util.Map; - 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; @@ -19,6 +10,10 @@ import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.exception.WxPayException; +import java.io.File; +import java.util.Date; +import java.util.Map; + /** *
  * 微信支付相关接口.
@@ -281,6 +276,19 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri
    */
   WxScanPayNotifyResult parseScanPayNotifyResult(String xmlData) throws WxPayException;
 
+  /**
+   * 
+   * 发送小程序红包.
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/api/tools/miniprogram_hb.php?chapter=13_9&index=2
+   *  接口地址:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendminiprogramhb
+   * 
+ * + * @param request 请求对象 + * @return the result + * @throws WxPayException the exception + */ + WxPaySendMiniProgramRedpackResult sendMiniProgramRedpack(WxPaySendMiniProgramRedpackRequest 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 4c3465f8df..093997e06b 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
@@ -182,7 +182,19 @@ public WxScanPayNotifyResult parseScanPayNotifyResult(String xmlData) throws WxP
 
   }
 
-  @Override
+    @Override
+    public WxPaySendMiniProgramRedpackResult sendMiniProgramRedpack(WxPaySendMiniProgramRedpackRequest request)
+      throws WxPayException {
+      request.checkAndSign(this.getConfig());
+      String url = this.getPayBaseUrl() + "/mmpaymkttransfers/sendminiprogramhb";
+      String responseContent = this.post(url, request.toXML(), true);
+
+      WxPaySendMiniProgramRedpackResult result = BaseWxPayResult.fromXML(responseContent, WxPaySendMiniProgramRedpackResult.class);
+      result.checkResult(this, request.getSignType(), true);
+      return result;
+    }
+
+    @Override
   public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) throws WxPayException {
     request.checkAndSign(this.getConfig());
 
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java
index 13a507d9e5..551b00ee52 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java
@@ -1,43 +1,14 @@
 package com.github.binarywang.wxpay.service.impl;
 
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Calendar;
-import java.util.Date;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.*;
-
 import com.github.binarywang.utils.qrcode.QrcodeUtils;
-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.WxPayOrderNotifyResultTest;
 import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult;
 import com.github.binarywang.wxpay.bean.order.WxPayMpOrderResult;
 import com.github.binarywang.wxpay.bean.order.WxPayNativeOrderResult;
-import com.github.binarywang.wxpay.bean.request.WxPayAuthcode2OpenidRequest;
-import com.github.binarywang.wxpay.bean.request.WxPayMicropayRequest;
-import com.github.binarywang.wxpay.bean.request.WxPayOrderReverseRequest;
-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.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.constant.WxPayConstants.AccountType;
 import com.github.binarywang.wxpay.constant.WxPayConstants.BillType;
 import com.github.binarywang.wxpay.constant.WxPayConstants.SignType;
@@ -47,6 +18,16 @@
 import com.github.binarywang.wxpay.testbase.ApiTestModule;
 import com.github.binarywang.wxpay.testbase.XmlWxPayConfig;
 import com.google.inject.Inject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Calendar;
+import java.util.Date;
 
 import static com.github.binarywang.wxpay.constant.WxPayConstants.TarType;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -461,8 +442,7 @@ public void testSetConfig() throws Exception {
   @Test
   public void testReverseOrder() throws Exception {
     WxPayOrderReverseResult result = this.payService.reverseOrder(
-      WxPayOrderReverseRequest
-        .newBuilder()
+      WxPayOrderReverseRequest.newBuilder()
         .outTradeNo("1111")
         .build());
     assertNotNull(result);
@@ -541,8 +521,7 @@ public void testSendCoupon() throws Exception {
   @Test
   public void testQueryCouponStock() throws Exception {
     WxPayCouponStockQueryResult result = this.payService.queryCouponStock(
-      WxPayCouponStockQueryRequest
-        .newBuilder()
+      WxPayCouponStockQueryRequest.newBuilder()
         .couponStockId("123")
         .build());
     this.logger.info(result.toString());
@@ -556,8 +535,7 @@ public void testQueryCouponStock() throws Exception {
   @Test
   public void testQueryCouponInfo() throws Exception {
     WxPayCouponInfoQueryResult result = this.payService.queryCouponInfo(
-      WxPayCouponInfoQueryRequest
-        .newBuilder()
+      WxPayCouponInfoQueryRequest.newBuilder()
         .openid("ojOQA0y9o-Eb6Aep7uVTdbkJqrP4")
         .couponId("11")
         .stockId("1121")
@@ -632,4 +610,28 @@ public void testGetWxApiData() throws Exception {
     //see test in testUnifiedOrder()
   }
 
+  @Test
+  public void testSendMiniProgramRedpack() throws WxPayException {
+    final WxPaySendMiniProgramRedpackResult result = this.payService
+      .sendMiniProgramRedpack(new WxPaySendMiniProgramRedpackRequest()
+        .setReOpenid("ojOQA0y9o-Eb6Aep7uVTdbkJqrP4")
+        .setTotalAmount(1));
+    System.out.println(result);
+  }
+
+  @Test
+  public void testDownloadRawBill() {
+  }
+
+  @Test
+  public void testTestDownloadRawBill() {
+  }
+
+  @Test
+  public void testGetWxPayFaceAuthInfo() {
+  }
+
+  @Test
+  public void testFacepay() {
+  }
 }

From f02ed97c33eccb784b231bf73578683dda26152d Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sun, 1 Dec 2019 17:33:25 +0800
Subject: [PATCH 0007/1706] =?UTF-8?q?:bookmark:=20=E5=8F=91=E5=B8=833.6.1.?=
 =?UTF-8?q?B=E6=B5=8B=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 +-
 spring-boot-starters/pom.xml                                    | 2 +-
 .../wx-java-miniapp-spring-boot-starter/pom.xml                 | 2 +-
 spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml     | 2 +-
 spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml   | 2 +-
 spring-boot-starters/wx-java-pay-spring-boot-starter/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 +-
 12 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/pom.xml b/pom.xml
index 930c7ce901..8c51152fbb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
   4.0.0
   com.github.binarywang
   wx-java
-  3.6.0
+  3.6.1.B
   pom
   WxJava - Weixin/Wechat Java SDK
   微信开发Java SDK
diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml
index a04dc13547..8c415da0bb 100644
--- a/spring-boot-starters/pom.xml
+++ b/spring-boot-starters/pom.xml
@@ -6,7 +6,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.0
+    3.6.1.B
   
   pom
   wx-java-spring-boot-starters
diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml
index c538357675..2b07695911 100644
--- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
   
     wx-java-spring-boot-starters
     com.github.binarywang
-    3.6.0
+    3.6.1.B
   
   4.0.0
 
diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml
index d45c1bd729..18107230e4 100644
--- a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
   
     wx-java-spring-boot-starters
     com.github.binarywang
-    3.6.0
+    3.6.1.B
   
   4.0.0
 
diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml
index 52ab7e3da5..4407d1ec7c 100644
--- a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
   
     wx-java-spring-boot-starters
     com.github.binarywang
-    3.6.0
+    3.6.1.B
   
   4.0.0
 
diff --git a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml
index 6c643615c0..3cadb3a4ec 100644
--- a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
   
     wx-java-spring-boot-starters
     com.github.binarywang
-    3.6.0
+    3.6.1.B
   
   4.0.0
 
diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml
index 68c430f5c8..a87098fa77 100644
--- a/weixin-java-common/pom.xml
+++ b/weixin-java-common/pom.xml
@@ -6,7 +6,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.0
+    3.6.1.B
   
 
   weixin-java-common
diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml
index 2dc09480d4..14eaa4cf08 100644
--- a/weixin-java-cp/pom.xml
+++ b/weixin-java-cp/pom.xml
@@ -7,7 +7,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.0
+    3.6.1.B
   
 
   weixin-java-cp
diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml
index cefda9b5c0..8a336ac089 100644
--- a/weixin-java-miniapp/pom.xml
+++ b/weixin-java-miniapp/pom.xml
@@ -7,7 +7,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.0
+    3.6.1.B
   
 
   weixin-java-miniapp
diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml
index 7db1859375..9c662767ec 100644
--- a/weixin-java-mp/pom.xml
+++ b/weixin-java-mp/pom.xml
@@ -7,7 +7,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.0
+    3.6.1.B
   
 
   weixin-java-mp
diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml
index d25b508380..c74afffdd8 100644
--- a/weixin-java-open/pom.xml
+++ b/weixin-java-open/pom.xml
@@ -7,7 +7,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.0
+    3.6.1.B
   
 
   weixin-java-open
diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml
index fedc9f5045..4e5a2d2a7b 100644
--- a/weixin-java-pay/pom.xml
+++ b/weixin-java-pay/pom.xml
@@ -5,7 +5,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.0
+    3.6.1.B
   
   4.0.0
 

From d4d830fe3a3582f151dddbf214aab7fd7d628e3c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=85=B1=E6=B2=B999=E5=8F=B7?= <779687795@qq.com>
Date: Tue, 3 Dec 2019 17:09:31 +0800
Subject: [PATCH 0008/1706] =?UTF-8?q?:sparkles:=09#1309=20=E5=A2=9E?=
 =?UTF-8?q?=E5=8A=A0=E5=8F=91=E9=80=81=E5=92=8C=E6=9F=A5=E8=AF=A2=E4=BC=81?=
 =?UTF-8?q?=E4=B8=9A=E5=BE=AE=E4=BF=A1=E7=BA=A2=E5=8C=85=E7=9A=84=E6=8E=A5?=
 =?UTF-8?q?=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../entpay/EntPayRedpackQueryRequest.java     |  33 ++++
 .../bean/entpay/EntPayRedpackQueryResult.java | 133 ++++++++++++++++
 .../bean/entpay/EntPayRedpackRequest.java     | 147 ++++++++++++++++++
 .../bean/entpay/EntPayRedpackResult.java      |  80 ++++++++++
 .../wxpay/bean/request/BaseWxPayRequest.java  |  58 +++++--
 .../wxpay/service/EntPayService.java          |  24 +++
 .../wxpay/service/impl/EntPayServiceImpl.java |  63 +++++---
 .../binarywang/wxpay/util/SignUtils.java      |  45 +++++-
 .../service/impl/EntPayServiceImplTest.java   |  62 +++++++-
 9 files changed, 607 insertions(+), 38 deletions(-)
 create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryRequest.java
 create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryResult.java
 create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackRequest.java
 create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackResult.java

diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryRequest.java
new file mode 100644
index 0000000000..29fc517f00
--- /dev/null
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryRequest.java
@@ -0,0 +1,33 @@
+package com.github.binarywang.wxpay.bean.entpay;
+
+import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.*;
+
+/**
+ * 红包发送记录查询请求
+ * @author wuyong
+ * @date 2019-12-01 17:19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Builder(builderMethodName = "newBuilder")
+@NoArgsConstructor
+@AllArgsConstructor
+@XStreamAlias("xml")
+public class EntPayRedpackQueryRequest extends BaseWxPayRequest {
+
+
+  /**
+   * 商户订单号
+   */
+  @XStreamAlias("mch_billno")
+  private String mchBillNo;
+
+
+  @Override
+  protected void checkConstraints() throws WxPayException {
+
+  }
+}
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryResult.java
new file mode 100644
index 0000000000..1235fe1bd4
--- /dev/null
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryResult.java
@@ -0,0 +1,133 @@
+package com.github.binarywang.wxpay.bean.entpay;
+
+import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+/**
+ * 红包发送记录查询返回
+ *
+ * @author wuyong
+ * @date 2019-12-01 17:23
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@NoArgsConstructor
+@XStreamAlias("xml")
+public class EntPayRedpackQueryResult extends BaseWxPayResult {
+
+  /**
+   * 商户订单号
+   * 商户使用查询API填写的商户单号的原路返回
+   */
+  @XStreamAlias("mch_billno")
+  protected String mchBillNo;
+
+  /**
+   * 红包单号
+   * 使用API发放现金红包时返回的红包单号
+   */
+  @XStreamAlias("detailId")
+  private String detailId;
+  /**
+   * 红包状态
+   * SENDING:发放
+   * SENT:
+   * 已发放待领取
+   * FAILED:发放失败
+   * RECEIVED:已领取
+   * RFUND_ING:退款中 REFUND:已退款
+   */
+  @XStreamAlias("status")
+  private String status;
+
+  /**
+   * 发放类型
+   * API:通过API接口发放
+   */
+  @XStreamAlias("send_type")
+  private String sendType;
+
+  /**
+   * 红包金额
+   * 红包总金额(单位分)
+   */
+  @XStreamAlias("total_amount")
+  private Integer totalAmount;
+
+  /**
+   * 失败原因
+   * 发送失败原因
+   */
+  @XStreamAlias("reason")
+  private Integer reason;
+
+  /**
+   * 红包发送时间
+   */
+  @XStreamAlias("send_time")
+  private String sendTime;
+  /**
+   * 红包的退款时间
+   */
+  @XStreamAlias("refund_time")
+  private String refundTime;
+
+  /**
+   * 红包退款金额
+   */
+  @XStreamAlias("refund_amount")
+  private Integer refundAmount;
+
+  /**
+   * 祝福语
+   */
+  @XStreamAlias("wishing")
+  private String wishing;
+
+  /**
+   * 备注
+   */
+  @XStreamAlias("remark")
+  private String remark;
+
+  /**
+   * 活动名称
+   */
+  @XStreamAlias("act_name")
+  private String actName;
+
+  /**
+   * 领取红包的Openid
+   */
+  @XStreamAlias("openid")
+  private String openid;
+
+  /**
+   * 金额
+   */
+  @XStreamAlias("amount")
+  private Integer amount;
+
+  /**
+   * 接收时间
+   */
+  @XStreamAlias("rcv_time")
+  private Integer rcvTime;
+
+  /**
+   * 发送者名称
+   */
+  @XStreamAlias("sender_name")
+  private Integer senderName;
+
+  /**
+   * 发送者头像
+   * 通过企业微信开放接口上传获取
+   */
+  @XStreamAlias("sender_header_media_id")
+  private Integer senderHeaderMediaId;
+
+}
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackRequest.java
new file mode 100644
index 0000000000..0ab8bddab5
--- /dev/null
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackRequest.java
@@ -0,0 +1,147 @@
+package com.github.binarywang.wxpay.bean.entpay;
+
+import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
+import com.github.binarywang.wxpay.exception.WxPayException;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.*;
+import me.chanjar.weixin.common.annotation.Required;
+
+/**
+ * 发送企业红包
+ * @author wuyong
+ * @date 2019-12-1
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Builder(builderMethodName = "newBuilder")
+@NoArgsConstructor
+@AllArgsConstructor
+@XStreamAlias("xml")
+public class EntPayRedpackRequest extends BaseWxPayRequest {
+
+  private static final long serialVersionUID = 1L;
+
+  @Override
+  protected void checkConstraints() throws WxPayException {
+
+  }
+
+  /**
+   * 商户订单号(每个订单号必须唯一)
+   * 组成:mch_id+yyyymmdd+10位一天内不能重复的数字。  接口根据商户订单号支持重入,如出现超时可再调用。
+   * 必填:是
+   */
+  @Required
+  @XStreamAlias("mch_billno")
+  private String mchBillNo;
+
+  /**
+   * 微信分配的公众账号ID(企业微信corpid即为此appId)
+   * 必填:是
+   */
+  @Required
+  @XStreamAlias("wxappid")
+  private String wxAppId;
+
+  /**
+   * 发送者名称
+   * 以个人名义发红包,红包发送者名称(需要utf-8格式)。与agentid互斥,二者只能填一个。
+   * 必填:否
+   */
+  @XStreamAlias("sender_name")
+  private String senderName;
+
+  /**
+   * 发送红包的应用id
+   * 以企业应用的名义发红包,企业应用id,整型,可在企业微信管理端应用的设置页面查看。与sender_name互斥,二者只能填一个。
+   * 必填:否
+   */
+  @XStreamAlias("agentid")
+  private String agentId;
+
+  /**
+   * 发送者头像
+   * 发送者头像素材id,通过企业微信开放上传素材接口获取
+   * 必填:否
+   */
+  @XStreamAlias("sender_header_media_id")
+  private String senderHeaderMediaId;
+
+  /**
+   * 用户openid
+   * 接受红包的用户.用户在wxappid下的openid。
+   * 必填:是
+   */
+  @Required
+  @XStreamAlias("re_openid")
+  private String reOpenid;
+
+  /**
+   * 金额
+   * 单位分,单笔最小金额默认为1元
+   * 必填:是
+   */
+  @Required
+  @XStreamAlias("total_amount")
+  private Integer totalAmount;
+
+  /**
+   * 红包祝福语
+   * 必填:是
+   */
+  @Required
+  @XStreamAlias("wishing")
+  private String wishing;
+
+  /**
+   * 项目名称
+   * 必填:是
+   */
+  @Required
+  @XStreamAlias("act_name")
+  private String actName;
+
+  /**
+   * 备注
+   * 必填:是
+   */
+  @Required
+  @XStreamAlias("remark")
+  private String remark;
+
+  /**
+   * 场景
+   * 发放红包使用场景,红包金额大于200时必传
+   * PRODUCT_1:商品促销
+   * PRODUCT_2:抽奖
+   * PRODUCT_3:虚拟物品兑奖
+   * PRODUCT_4:企业内部福利
+   * PRODUCT_5:渠道分润
+   * PRODUCT_6:保险回馈
+   * PRODUCT_7:彩票派奖
+   * PRODUCT_8:税务刮奖
+   */
+  @XStreamAlias("scene_id")
+  private String sceneId;
+
+
+  @Override
+  protected boolean ignoreAppid() {
+    return true;
+  }
+
+  @Override
+  protected boolean ignoreSubAppId() {
+    return true;
+  }
+
+  @Override
+  protected boolean ignoreSubMchId() {
+    return true;
+  }
+
+  @Override
+  protected boolean isWxWorkSign() {
+    return true;
+  }
+}
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackResult.java
new file mode 100644
index 0000000000..677ac88f89
--- /dev/null
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackResult.java
@@ -0,0 +1,80 @@
+package com.github.binarywang.wxpay.bean.entpay;
+
+import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * 企业微信红包返回
+ * @author wuyong
+ * @date 2019-12-01 11:31
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@NoArgsConstructor
+@XStreamAlias("xml")
+public class EntPayRedpackResult extends BaseWxPayResult implements Serializable {
+
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * 商户订单号
+   * 商户订单号(每个订单号必须唯一)组成:mch_id+yyyymmdd+10位一天内不能重复的数字
+   */
+  @XStreamAlias("mch_billno")
+  private String mchBillNo;
+
+  /**
+   * 商户号
+   * 微信支付分配的商户号
+   */
+  @XStreamAlias("mch_id")
+  private String mchId;
+
+  /**
+   * 公众账号appid
+   * 商户appid,接口传入的所有appid应该为公众号的appid,不能为APP的appid
+   */
+  @XStreamAlias("wxappid")
+  private String wxAppId;
+
+  /**
+   * 用户openid
+   * 接受收红包的用户在wxappid下的openid
+   */
+  @XStreamAlias("re_openid")
+  private String reOpenid;
+
+  /**
+   * 付款金额
+   * 付款金额,单位分
+   */
+  @XStreamAlias("totalAmount")
+  private String totalAmount;
+
+  /**
+   * 微信单号
+   * 红包订单的微信单号
+   */
+  @XStreamAlias("sendListid")
+  private String sendListId;
+
+  /**
+   * 发送者名称
+   * 红包发送者名称(需要utf-8格式)
+   */
+  @XStreamAlias("sender_name")
+  private String senderName;
+
+  /**
+   * 发送者头像
+   * 发送者头像素材id,通过企业微信开放上传素材接口获取
+   */
+  @XStreamAlias("sender_header_media_id")
+  private String senderHeaderMediaId;
+
+}
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java
index 73793a23ff..0b85f41e93 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java
@@ -1,21 +1,20 @@
 package com.github.binarywang.wxpay.bean.request;
 
-import java.io.Serializable;
-import java.math.BigDecimal;
-
-import lombok.experimental.Accessors;
-import org.apache.commons.lang3.StringUtils;
-
 import com.github.binarywang.wxpay.config.WxPayConfig;
 import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.util.SignUtils;
 import com.thoughtworks.xstream.XStream;
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.Data;
+import lombok.experimental.Accessors;
 import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.common.util.BeanUtils;
 import me.chanjar.weixin.common.util.json.WxGsonBuilder;
 import me.chanjar.weixin.common.util.xml.XStreamInitializer;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
 
 import static com.github.binarywang.wxpay.constant.WxPayConstants.SignType.ALL_SIGN_TYPES;
 
@@ -118,6 +117,21 @@ public abstract class BaseWxPayRequest implements Serializable {
   @XStreamAlias("sign_type")
   private String signType;
 
+
+  /**
+   * 企业微信签名
+   */
+  @XStreamAlias("workwx_sign")
+  private String workWxSign;
+
+  public String getWorkWxSign() {
+    return workWxSign;
+  }
+
+  public void setWorkWxSign(String workWxSign) {
+    this.workWxSign = workWxSign;
+  }
+
   /**
    * 将单位为元转换为单位为分.
    *
@@ -205,6 +219,26 @@ protected boolean ignoreAppid() {
     return false;
   }
 
+  /**
+   * 签名时,是否忽略sub_appid.
+   *
+   * @return the boolean
+   */
+  protected boolean ignoreSubAppId() {
+    return false;
+  }
+
+  protected boolean ignoreSubMchId(){
+    return false;
+  }
+
+  /**
+   * 是否是企业微信字段
+   */
+  protected boolean isWxWorkSign(){
+    return false;
+  }
+
   /**
    * 签名时,忽略的参数.
    *
@@ -238,12 +272,16 @@ public void checkAndSign(WxPayConfig config) throws WxPayException {
       this.setMchId(config.getMchId());
     }
 
-    if (StringUtils.isBlank(getSubAppId())) {
-      this.setSubAppId(config.getSubAppId());
+    if (!ignoreSubAppId()) {
+      if (StringUtils.isBlank(getSubAppId())) {
+        this.setSubAppId(config.getSubAppId());
+      }
     }
 
-    if (StringUtils.isBlank(getSubMchId())) {
-      this.setSubMchId(config.getSubMchId());
+    if (!ignoreSubMchId()) {
+      if (StringUtils.isBlank(getSubMchId())) {
+        this.setSubMchId(config.getSubMchId());
+      }
     }
 
     if (StringUtils.isBlank(getSignType())) {
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 df9330fc9f..1b1b76b154 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
@@ -119,4 +119,28 @@ public interface EntPayService {
    * @throws WxPayException the wx pay exception
    */
   EntPayBankQueryResult queryPayBank(EntPayBankQueryRequest request) throws WxPayException;
+
+  /**
+   * 企业发送微信红包给个人用户
+   * 
+   *   文档地址:https://work.weixin.qq.com/api/doc
+   *   接口地址: https://api.mch.weixin.qq.com/mmpaymkttransfers/sendworkwxredpack
+   * 
+ * @param request 请求对象 + * @return the wx pay send redpack result + * @throws WxPayException the wx pay exception + */ + EntPayRedpackResult sendEnterpriseRedpack(EntPayRedpackRequest request) throws WxPayException; + + /** + * 企业发送微信红包查询 + *
+   *   文档地址:https://work.weixin.qq.com/api/doc
+   *   接口地址: https://api.mch.weixin.qq.com/mmpaymkttransfers/queryworkwxredpack
+   * 
+ * @param request 请求对象 + * @return the wx pay send redpack result + * @throws WxPayException the wx pay exception + */ + EntPayRedpackQueryResult queryEnterpriseRedpack(EntPayRedpackQueryRequest request) throws WxPayException; } 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 59db3ee078..1db5bc40fd 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 @@ -1,35 +1,26 @@ package com.github.binarywang.wxpay.service.impl; +import com.github.binarywang.wxpay.bean.entpay.*; +import com.github.binarywang.wxpay.bean.request.WxPayDefaultRequest; +import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.EntPayService; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.util.SignUtils; +import org.apache.commons.codec.binary.Base64; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openssl.PEMParser; +import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; + +import javax.crypto.Cipher; import java.io.File; import java.io.FileReader; -import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.security.PublicKey; import java.security.Security; -import javax.crypto.Cipher; - -import org.apache.commons.codec.binary.Base64; -import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; -import org.bouncycastle.jce.provider.BouncyCastleProvider; -import org.bouncycastle.openssl.PEMParser; -import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; - -import com.github.binarywang.wxpay.bean.entpay.EntPayBankQueryRequest; -import com.github.binarywang.wxpay.bean.entpay.EntPayBankQueryResult; -import com.github.binarywang.wxpay.bean.entpay.EntPayBankRequest; -import com.github.binarywang.wxpay.bean.entpay.EntPayBankResult; -import com.github.binarywang.wxpay.bean.entpay.EntPayQueryRequest; -import com.github.binarywang.wxpay.bean.entpay.EntPayQueryResult; -import com.github.binarywang.wxpay.bean.entpay.EntPayRequest; -import com.github.binarywang.wxpay.bean.entpay.EntPayResult; -import com.github.binarywang.wxpay.bean.entpay.GetPublicKeyResult; -import com.github.binarywang.wxpay.bean.request.WxPayDefaultRequest; -import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; -import com.github.binarywang.wxpay.exception.WxPayException; -import com.github.binarywang.wxpay.service.EntPayService; -import com.github.binarywang.wxpay.service.WxPayService; /** *
@@ -140,6 +131,32 @@ public EntPayBankQueryResult queryPayBank(EntPayBankQueryRequest request) throws
     return result;
   }
 
+  @Override
+  public EntPayRedpackResult sendEnterpriseRedpack(EntPayRedpackRequest request) throws WxPayException {
+    //企业微信签名,需要在请求签名之前
+    request.setNonceStr(String.valueOf(System.currentTimeMillis()));
+    request.setWorkWxSign(SignUtils.createEntSign(request.getActName(),request.getMchBillNo(),request.getMchId(),request.getNonceStr(),request.getReOpenid(),request.getTotalAmount(),request.getWxAppId(),"Hcf-X_dzLeaTIyK33okGmODK8sLzc7kLrgkWXOAoMbE","MD5"));
+
+    request.checkAndSign(this.payService.getConfig());
+
+    String url = this.payService.getPayBaseUrl() + "/mmpaymkttransfers/sendworkwxredpack";
+    String responseContent = this.payService.post(url, request.toXML(), true);
+    final EntPayRedpackResult result = BaseWxPayResult.fromXML(responseContent, EntPayRedpackResult.class);
+
+    result.checkResult(this.payService, request.getSignType(), true);
+    return result;
+  }
+
+  @Override
+  public EntPayRedpackQueryResult queryEnterpriseRedpack(EntPayRedpackQueryRequest request) throws WxPayException {
+    request.checkAndSign(this.payService.getConfig());
+    String url = this.payService.getPayBaseUrl() + "/mmpaymkttransfers/queryworkwxredpack";
+    String responseContent = this.payService.post(url, request.toXML(), true);
+    final EntPayRedpackQueryResult result = BaseWxPayResult.fromXML(responseContent, EntPayRedpackQueryResult.class);
+    result.checkResult(this.payService, request.getSignType(), true);
+    return result;
+  }
+
   private String encryptRSA(File publicKeyFile, String srcString) throws WxPayException {
     try {
       Security.addProvider(new BouncyCastleProvider());
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java
index 5591b016b4..8490e00993 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java
@@ -91,7 +91,7 @@ public static String createSign(Map params, String signType, Str
 
       if (shouldSign) {
         toSign.append(key).append("=").append(value).append("&");
-      }
+    }
     }
 
     toSign.append("key=").append(signKey);
@@ -102,6 +102,49 @@ public static String createSign(Map params, String signType, Str
     }
   }
 
+  /**
+   * 企业微信签名
+   * @param signType md5 目前接口要求使用的加密类型
+   */
+  public static String createEntSign(String actName,String mchBillNo,String mchId,String nonceStr,
+                                     String reOpenid,Integer totalAmount,String wxAppId,String signKey,
+                                     String signType){
+    Map sortedMap = new HashMap<>();
+    sortedMap.put("act_name",actName);
+    sortedMap.put("mch_billno",mchBillNo);
+    sortedMap.put("mch_id",mchId);
+    sortedMap.put("nonce_str",nonceStr);
+    sortedMap.put("re_openid",reOpenid);
+    sortedMap.put("total_amount", totalAmount + "");
+    sortedMap.put("wxappid",wxAppId);
+
+    Map sortParams = new TreeMap<>(sortedMap);
+    Set> entries = sortParams.entrySet();
+    Iterator> iterator = entries.iterator();
+    StringBuilder toSign = new StringBuilder();
+    while(iterator.hasNext()){
+      Map.Entry entry = iterator.next();
+      String key = String.valueOf(entry.getKey());
+      String value = String.valueOf(entry.getValue());
+      boolean shouldSign = false;
+      if (StringUtils.isNotEmpty(value)) {
+        shouldSign = true;
+      }
+
+      if (shouldSign) {
+        toSign.append(key).append("=").append(value).append("&");
+      }
+    }
+    //企业微信这里字段名不一样
+    toSign.append("secret=").append(signKey);
+    if (SignType.HMAC_SHA256.equals(signType)) {
+      return me.chanjar.weixin.common.util.SignUtils.createHmacSha256Sign(toSign.toString(), signKey);
+    } else {
+      return DigestUtils.md5Hex(toSign.toString()).toUpperCase();
+    }
+
+  }
+
   /**
    * 校验签名是否正确.
    *
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/EntPayServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/EntPayServiceImplTest.java
index 4c7f6e3246..142bbbc734 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/EntPayServiceImplTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/EntPayServiceImplTest.java
@@ -1,8 +1,6 @@
 package com.github.binarywang.wxpay.service.impl;
 
-import com.github.binarywang.wxpay.bean.entpay.EntPayBankRequest;
-import com.github.binarywang.wxpay.bean.entpay.EntPayBankResult;
-import com.github.binarywang.wxpay.bean.entpay.EntPayRequest;
+import com.github.binarywang.wxpay.bean.entpay.*;
 import com.github.binarywang.wxpay.constant.WxPayConstants.CheckNameOption;
 import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.service.WxPayService;
@@ -10,7 +8,10 @@
 import com.google.inject.Inject;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.testng.annotations.*;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import java.util.concurrent.TimeUnit;
 
 /**
  * 
@@ -94,4 +95,57 @@ public void testPayBank() throws Exception {
   public void testQueryPayBank() throws Exception {
     this.logger.info(this.payService.getEntPayService().queryPayBank("123").toString());
   }
+
+
+
+  /**
+   * 发送企业红包
+   * @throws Exception the exception
+   */
+  @Test
+  public void testSendEnterpriseRedpack() {
+    EntPayRedpackRequest request = new EntPayRedpackRequest();
+    request.setMchId("1");
+    //商户单号
+    request.setMchBillNo(request.getMchId()+"20191202"+"1");
+    //企业微信corpid即为此appId
+    request.setWxAppId("1");
+//    request.setSenderName("1");
+//    request.setSenderHeaderMediaId("2");
+    request.setAgentId("1");
+    request.setReOpenid("1");
+    //目前企业微信api红包最低1块钱
+    request.setTotalAmount(1000);
+    request.setWishing("1");
+    request.setActName("1");
+    request.setRemark("1");
+
+    EntPayRedpackResult redpackResult = null;
+    try {
+      redpackResult = this.payService.getEntPayService().sendEnterpriseRedpack(request);
+    } catch (WxPayException e) {
+    }
+    this.logger.info(redpackResult.toString());
+  }
+
+  /**
+   * 查询企业红包
+   * @throws Exception
+   */
+  @Test
+  public void testQueryEnterpriseRedpack() throws Exception {
+    while (true) {
+      EntPayRedpackQueryRequest request = new EntPayRedpackQueryRequest();
+      request.setAppid("1");
+      request.setMchId("1");
+      request.setMchBillNo("1");
+
+      try {
+        EntPayRedpackQueryResult result = this.payService.getEntPayService().queryEnterpriseRedpack(request);
+        this.logger.info(result.toString());
+      } catch (Exception e) {
+      }
+      TimeUnit.SECONDS.sleep(3);
+    }
+  }
 }

From 232ea7e3c794ab02100d7e9ba5a5baec1429ee1e Mon Sep 17 00:00:00 2001
From: JoeWoo 
Date: Sun, 8 Dec 2019 22:41:38 +0800
Subject: [PATCH 0009/1706] =?UTF-8?q?:art:=20#1314=20=E4=BC=98=E5=8C=96?=
 =?UTF-8?q?=E5=A2=9E=E5=BC=BA=E5=BE=AE=E4=BF=A1=E5=B0=8F=E7=A8=8B=E5=BA=8F?=
 =?UTF-8?q?Redis=E9=85=8D=E7=BD=AE=E5=AE=9E=E7=8E=B0=E7=B1=BB=E5=8A=9F?=
 =?UTF-8?q?=E8=83=BD?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

修改 Redis 配置实现类以实现选择数据库及密码认证功能
---
 .../config/impl/AbstractWxMaRedisConfig.java  | 280 ++++++++++++++
 .../config/impl/WxMaDefaultConfigImpl.java    |  30 +-
 .../config/impl/WxMaRedisConfigImpl.java      | 363 +-----------------
 .../impl/WxMaRedisConnectionConfigImpl.java   |  24 ++
 4 files changed, 338 insertions(+), 359 deletions(-)
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/AbstractWxMaRedisConfig.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaRedisConnectionConfigImpl.java

diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/AbstractWxMaRedisConfig.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/AbstractWxMaRedisConfig.java
new file mode 100644
index 0000000000..ac75b3697d
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/AbstractWxMaRedisConfig.java
@@ -0,0 +1,280 @@
+package cn.binarywang.wx.miniapp.config.impl;
+
+import com.github.jedis.lock.JedisLock;
+import redis.clients.jedis.Jedis;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+
+/**
+ * @author winter
+ */
+public abstract class AbstractWxMaRedisConfig extends WxMaDefaultConfigImpl {
+
+  public interface JedisConfig {
+    Jedis config(Jedis jedis);
+  }
+
+  private static final String ACCESS_TOKEN = "accessToken";
+  private static final String JSAPI_TICKET = "jsapiTicket";
+  private static final String CARD_API_TICKET = "cardApiTicket";
+
+  private static final String HASH_VALUE_FIELD = "value";
+  private static final String HASH_EXPIRE_FIELD = "expire";
+
+  /**
+   * Redis Key 的前缀,默认为 maConfig
+   */
+  private String redisKeyPrefix = "maConfig";
+
+  /**
+   * 微信小程序唯一id,用于拼接存储到redis时的key,防止key重复.
+   */
+  private String maId;
+
+  private Lock accessTokenLock;
+  private Lock jsapiTicketLock;
+  private Lock cardApiTicketLock;
+
+  /**
+   * 临时文件目录.
+   */
+  protected volatile File tmpDirFile;
+
+  /**
+   * 对从 JedisPool.getResource() 获取到的每个 Jedis 实例进行配置
+   */
+  private JedisConfig jedisConfig;
+
+  protected abstract Jedis getJedis();
+
+  private Jedis getConfiguredJedis() {
+    Jedis jedis = getJedis();
+    if (jedisConfig != null) {
+      return jedisConfig.config(jedis);
+    } else {
+      return jedis;
+    }
+  }
+
+  private String getRedisKey(String key) {
+    StringBuilder redisKey = new StringBuilder(redisKeyPrefix).append(":");
+    if (maId == null) {
+      return redisKey.append(key).toString();
+    } else {
+      return redisKey.append(maId).append(":").append(key).toString();
+    }
+  }
+
+  private String getValueFromRedis(String key) {
+    try (Jedis jedis = getConfiguredJedis()) {
+      return jedis.hget(getRedisKey(key), HASH_VALUE_FIELD);
+    }
+  }
+
+  private void setValueToRedis(String key, long expiresTime, String value) {
+    try (Jedis jedis = getConfiguredJedis()) {
+      Map hash = new HashMap();
+      hash.put(HASH_VALUE_FIELD, value);
+      hash.put(HASH_EXPIRE_FIELD, String.valueOf(expiresTime));
+      jedis.hmset(getRedisKey(key), hash);
+    }
+  }
+
+  private long getExpireFromRedis(String key) {
+    try (Jedis jedis = getConfiguredJedis()) {
+      String expire = jedis.hget(getRedisKey(key), HASH_EXPIRE_FIELD);
+      return expire == null ? 0 : Long.parseLong(expire);
+    }
+  }
+
+  private void setExpire(String key, long expiresTime) {
+    try (Jedis jedis = getConfiguredJedis()) {
+      jedis.hset(getRedisKey(key), HASH_EXPIRE_FIELD, String.valueOf(expiresTime));
+    }
+  }
+
+  public void setRedisKeyPrefix(String redisKeyPrefix) {
+    this.redisKeyPrefix = redisKeyPrefix;
+  }
+
+  public void setJedisConfig(JedisConfig jedisConfig) {
+    this.jedisConfig = jedisConfig;
+  }
+
+  public void setMaId(String maId) {
+    this.maId = maId;
+  }
+
+  @Override
+  public String getAccessToken() {
+    return getValueFromRedis(ACCESS_TOKEN);
+  }
+
+  @Override
+  public Lock getAccessTokenLock() {
+    if (accessTokenLock == null) {
+      synchronized (this) {
+        if (accessTokenLock == null) {
+          accessTokenLock = new DistributedLock(getRedisKey("accessTokenLock"));
+        }
+      }
+    }
+    return accessTokenLock;
+  }
+
+  @Override
+  public boolean isAccessTokenExpired() {
+    return isExpired(getExpireFromRedis(ACCESS_TOKEN));
+  }
+
+  @Override
+  public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
+    setValueToRedis(ACCESS_TOKEN, expiresAheadInMillis(expiresInSeconds), accessToken);
+  }
+
+  @Override
+  public String getJsapiTicket() {
+    return getValueFromRedis(JSAPI_TICKET);
+  }
+
+  @Override
+  public Lock getJsapiTicketLock() {
+    if (jsapiTicketLock == null) {
+      synchronized (this) {
+        if (jsapiTicketLock == null) {
+          jsapiTicketLock = new DistributedLock(getRedisKey("jsapiTicketLock"));
+        }
+      }
+    }
+    return jsapiTicketLock;
+  }
+
+  @Override
+  public boolean isJsapiTicketExpired() {
+    return isExpired(getExpireFromRedis(JSAPI_TICKET));
+  }
+
+  @Override
+  public void expireJsapiTicket() {
+    setExpire(JSAPI_TICKET, 0);
+  }
+
+  @Override
+  public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
+    setValueToRedis(JSAPI_TICKET, expiresAheadInMillis(expiresInSeconds), jsapiTicket);
+  }
+
+
+  @Override
+  public String getCardApiTicket() {
+    return getValueFromRedis(CARD_API_TICKET);
+  }
+
+  @Override
+  public Lock getCardApiTicketLock() {
+    if (cardApiTicketLock == null) {
+      synchronized (this) {
+        if (cardApiTicketLock == null) {
+          cardApiTicketLock = new DistributedLock(getRedisKey("cardApiTicketLock"));
+        }
+      }
+    }
+    return cardApiTicketLock;
+  }
+
+  @Override
+  public boolean isCardApiTicketExpired() {
+    return isExpired(getExpireFromRedis(CARD_API_TICKET));
+  }
+
+  @Override
+  public void expireCardApiTicket() {
+    setExpire(CARD_API_TICKET, 0);
+  }
+
+  @Override
+  public void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) {
+    setValueToRedis(CARD_API_TICKET, expiresAheadInMillis(expiresInSeconds), cardApiTicket);
+  }
+
+  @Override
+  public void expireAccessToken() {
+    setExpiresTime(0);
+  }
+
+  @Override
+  public long getExpiresTime() {
+    return getExpireFromRedis(ACCESS_TOKEN);
+  }
+
+  @Override
+  public void setExpiresTime(long expiresTime) {
+    setExpire(ACCESS_TOKEN, expiresTime);
+  }
+
+  /**
+   * 基于redis的简单分布式锁.
+   */
+  private class DistributedLock implements Lock {
+
+    private JedisLock lock;
+
+    private DistributedLock(String key) {
+      this.lock = new JedisLock(getRedisKey(key));
+    }
+
+    @Override
+    public void lock() {
+      try (Jedis jedis = getConfiguredJedis()) {
+        if (!lock.acquire(jedis)) {
+          throw new RuntimeException("acquire timeouted");
+        }
+      } catch (InterruptedException e) {
+        throw new RuntimeException("lock failed", e);
+      }
+    }
+
+    @Override
+    public void lockInterruptibly() throws InterruptedException {
+      try (Jedis jedis = getConfiguredJedis()) {
+        if (!lock.acquire(jedis)) {
+          throw new RuntimeException("acquire timeouted");
+        }
+      }
+    }
+
+    @Override
+    public boolean tryLock() {
+      try (Jedis jedis = getConfiguredJedis()) {
+        return lock.acquire(jedis);
+      } catch (InterruptedException e) {
+        throw new RuntimeException("lock failed", e);
+      }
+    }
+
+    @Override
+    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
+      try (Jedis jedis = getConfiguredJedis()) {
+        return lock.acquire(jedis);
+      }
+    }
+
+    @Override
+    public void unlock() {
+      try (Jedis jedis = getConfiguredJedis()) {
+        lock.release(jedis);
+      }
+    }
+
+    @Override
+    public Condition newCondition() {
+      throw new RuntimeException("unsupported method");
+    }
+
+  }
+}
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaDefaultConfigImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaDefaultConfigImpl.java
index 76ff7611b4..98929be166 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaDefaultConfigImpl.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaDefaultConfigImpl.java
@@ -48,6 +48,20 @@ public class WxMaDefaultConfigImpl implements WxMaConfig {
 
   private volatile ApacheHttpClientBuilder apacheHttpClientBuilder;
 
+  /**
+   * 会过期的数据提前过期时间,默认预留200秒的时间
+   */
+  protected long expiresAheadInMillis(int expiresInSeconds) {
+    return System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
+  }
+
+  /**
+   * 判断 expiresTime 是否已经过期
+   */
+  protected boolean isExpired(long expiresTime) {
+    return System.currentTimeMillis() > expiresTime;
+  }
+
   @Override
   public String getAccessToken() {
     return this.accessToken;
@@ -68,7 +82,7 @@ public void setAccessTokenLock(Lock accessTokenLock) {
 
   @Override
   public boolean isAccessTokenExpired() {
-    return System.currentTimeMillis() > this.expiresTime;
+    return isExpired(this.expiresTime);
   }
 
   @Override
@@ -78,8 +92,8 @@ public synchronized void updateAccessToken(WxAccessToken accessToken) {
 
   @Override
   public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
-    this.accessToken = accessToken;
-    this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
+    setAccessToken(accessToken);
+    setExpiresTime(expiresAheadInMillis(expiresInSeconds));
   }
 
   @Override
@@ -94,7 +108,7 @@ public Lock getJsapiTicketLock() {
 
   @Override
   public boolean isJsapiTicketExpired() {
-    return System.currentTimeMillis() > this.jsapiTicketExpiresTime;
+    return isExpired(this.jsapiTicketExpiresTime);
   }
 
   @Override
@@ -105,8 +119,7 @@ public void expireJsapiTicket() {
   @Override
   public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
     this.jsapiTicket = jsapiTicket;
-    // 预留200秒的时间
-    this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
+    this.jsapiTicketExpiresTime = expiresAheadInMillis(expiresInSeconds);
   }
 
 
@@ -122,7 +135,7 @@ public Lock getCardApiTicketLock() {
 
   @Override
   public boolean isCardApiTicketExpired() {
-    return System.currentTimeMillis() > this.cardApiTicketExpiresTime;
+    return isExpired(this.cardApiTicketExpiresTime);
   }
 
   @Override
@@ -133,8 +146,7 @@ public void expireCardApiTicket() {
   @Override
   public void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) {
     this.cardApiTicket = cardApiTicket;
-    // 预留200秒的时间
-    this.cardApiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L;
+    this.cardApiTicketExpiresTime = expiresAheadInMillis(expiresInSeconds);
   }
 
   @Override
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaRedisConfigImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaRedisConfigImpl.java
index c9340f8d79..dfff1ceefc 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaRedisConfigImpl.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaRedisConfigImpl.java
@@ -1,377 +1,40 @@
 package cn.binarywang.wx.miniapp.config.impl;
 
-import java.io.File;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.Lock;
-
-import cn.binarywang.wx.miniapp.config.WxMaConfig;
-import com.github.jedis.lock.JedisLock;
-
-import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
-import me.chanjar.weixin.common.bean.WxAccessToken;
-import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
 import redis.clients.jedis.Jedis;
 import redis.clients.jedis.JedisPool;
 
 /**
- * 基于Redis的微信配置provider.
+ * 基于Redis的微信配置provider. 使用连接池 JedisPool 进行 Redis 操作。
  *
  * 
  * 需要引入依赖jedis-lock,才能使用该类。
  * 
- * - * @author winter */ -public class WxMaRedisConfigImpl implements WxMaConfig { - private static final String ACCESS_TOKEN = "accessToken"; - private static final String JSAPI_TICKET = "jsapiTicket"; - private static final String CARD_API_TICKET = "cardApiTicket"; - - private static final String HASH_VALUE_FIELD = "value"; - private static final String HASH_EXPIRE_FIELD = "expire"; +public class WxMaRedisConfigImpl extends AbstractWxMaRedisConfig { private JedisPool jedisPool; - /** - * 微信小程序唯一id,用于拼接存储到redis时的key,防止key重复. - */ - private String maId; - - private volatile String msgDataFormat; - protected volatile String appid; - private volatile String secret; - protected volatile String token; - private volatile String aesKey; - - private volatile String httpProxyHost; - private volatile int httpProxyPort; - private volatile String httpProxyUsername; - private volatile String httpProxyPassword; - - private Lock accessTokenLock; - private Lock jsapiTicketLock; - private Lock cardApiTicketLock; /** - * 临时文件目录. + * JedisPool 在此配置类是必须项,使用 WxMaRedisConfigImpl(JedisPool) 构造方法来构造实例 */ - protected volatile File tmpDirFile; - - private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; - - private String getRedisKey(String key) { - StringBuilder redisKey = new StringBuilder("maConfig:"); - if (maId == null) { - return redisKey.append(key).toString(); - } else { - return redisKey.append(maId).append(":").append(key).toString(); - } + @Deprecated + public WxMaRedisConfigImpl() { } - private String getValueFromRedis(String key) { - try (Jedis jedis = jedisPool.getResource()) { - return jedis.hget(getRedisKey(key), HASH_VALUE_FIELD); - } - } - - private void setValueToRedis(String key, long expiresTime, String value) { - try (Jedis jedis = jedisPool.getResource()) { - Map hash = new HashMap(); - hash.put(HASH_VALUE_FIELD, value); - hash.put(HASH_EXPIRE_FIELD, String.valueOf(expiresTime)); - jedis.hmset(getRedisKey(key), hash); - } - } - - private long getExpireFromRedis(String key) { - try (Jedis jedis = jedisPool.getResource()) { - String expire = jedis.hget(getRedisKey(key), HASH_EXPIRE_FIELD); - return expire == null ? 0 : Long.parseLong(expire); - } - } - - private void setExpire(String key, long expiresTime) { - try (Jedis jedis = jedisPool.getResource()) { - jedis.hset(getRedisKey(key), HASH_EXPIRE_FIELD, String.valueOf(expiresTime)); - } + public WxMaRedisConfigImpl(JedisPool jedisPool) { + this.jedisPool = jedisPool; } + /** + * 使用 WxMaRedisConfigImpl(JedisPool) 构造方法来设置 JedisPool + */ + @Deprecated public void setJedisPool(JedisPool jedisPool) { this.jedisPool = jedisPool; } - public void setMaId(String maId) { - this.maId = maId; - } - - @Override - public String getAccessToken() { - return getValueFromRedis(ACCESS_TOKEN); - } - - @Override - public Lock getAccessTokenLock() { - if (accessTokenLock == null) { - synchronized (this) { - if (accessTokenLock == null) { - accessTokenLock = new DistributedLock(getRedisKey("accessTokenLock")); - } - } - } - return accessTokenLock; - } - - @Override - public boolean isAccessTokenExpired() { - return System.currentTimeMillis() > getExpireFromRedis(ACCESS_TOKEN); - } - - @Override - public synchronized void updateAccessToken(WxAccessToken accessToken) { - updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); - } - - @Override - public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) { - setValueToRedis(ACCESS_TOKEN, System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L, accessToken); - } - - @Override - public String getJsapiTicket() { - return getValueFromRedis(JSAPI_TICKET); - } - - @Override - public Lock getJsapiTicketLock() { - if (jsapiTicketLock == null) { - synchronized (this) { - if (jsapiTicketLock == null) { - jsapiTicketLock = new DistributedLock(getRedisKey("jsapiTicketLock")); - } - } - } - return jsapiTicketLock; - } - - @Override - public boolean isJsapiTicketExpired() { - return System.currentTimeMillis() > getExpireFromRedis(JSAPI_TICKET); - } - - @Override - public void expireJsapiTicket() { - setExpire(JSAPI_TICKET, 0); - } - - @Override - public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) { - // 预留200秒的时间 - setValueToRedis(JSAPI_TICKET, System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L, jsapiTicket); - } - - - @Override - public String getCardApiTicket() { - return getValueFromRedis(CARD_API_TICKET); - } - - @Override - public Lock getCardApiTicketLock() { - if (cardApiTicketLock == null) { - synchronized (this) { - if (cardApiTicketLock == null) { - cardApiTicketLock = new DistributedLock(getRedisKey("cardApiTicketLock")); - } - } - } - return cardApiTicketLock; - } - - @Override - public boolean isCardApiTicketExpired() { - return System.currentTimeMillis() > getExpireFromRedis(CARD_API_TICKET); - } - - @Override - public void expireCardApiTicket() { - setExpire(CARD_API_TICKET, 0); - } - - @Override - public void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) { - setValueToRedis(CARD_API_TICKET, System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L, cardApiTicket); - } - - @Override - public void expireAccessToken() { - setExpire(ACCESS_TOKEN, 0); - } - - @Override - public String getSecret() { - return this.secret; - } - - public void setSecret(String secret) { - this.secret = secret; - } - - @Override - public String getToken() { - return this.token; - } - - public void setToken(String token) { - this.token = token; - } - - @Override - public long getExpiresTime() { - return getExpireFromRedis(ACCESS_TOKEN); - } - - @Override - public String getAesKey() { - return this.aesKey; - } - - public void setAesKey(String aesKey) { - this.aesKey = aesKey; - } - - @Override - public String getMsgDataFormat() { - return this.msgDataFormat; - } - - public void setMsgDataFormat(String msgDataFormat) { - this.msgDataFormat = msgDataFormat; - } - - @Override - public String getHttpProxyHost() { - return this.httpProxyHost; - } - - public void setHttpProxyHost(String httpProxyHost) { - this.httpProxyHost = httpProxyHost; - } - - @Override - public int getHttpProxyPort() { - return this.httpProxyPort; - } - - public void setHttpProxyPort(int httpProxyPort) { - this.httpProxyPort = httpProxyPort; - } - - @Override - public String getHttpProxyUsername() { - return this.httpProxyUsername; - } - - public void setHttpProxyUsername(String httpProxyUsername) { - this.httpProxyUsername = httpProxyUsername; - } - - @Override - public String getHttpProxyPassword() { - return this.httpProxyPassword; - } - - public void setHttpProxyPassword(String httpProxyPassword) { - this.httpProxyPassword = httpProxyPassword; - } - @Override - public String toString() { - return WxMaGsonBuilder.create().toJson(this); - } - - @Override - public ApacheHttpClientBuilder getApacheHttpClientBuilder() { - return this.apacheHttpClientBuilder; - } - - public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { - this.apacheHttpClientBuilder = apacheHttpClientBuilder; - } - - @Override - public boolean autoRefreshToken() { - return true; - } - - @Override - public String getAppid() { - return appid; - } - - public void setAppid(String appid) { - this.appid = appid; - } - - /** - * 基于redis的简单分布式锁. - */ - private class DistributedLock implements Lock { - - private JedisLock lock; - - private DistributedLock(String key) { - this.lock = new JedisLock(getRedisKey(key)); - } - - @Override - public void lock() { - try (Jedis jedis = jedisPool.getResource()) { - if (!lock.acquire(jedis)) { - throw new RuntimeException("acquire timeouted"); - } - } catch (InterruptedException e) { - throw new RuntimeException("lock failed", e); - } - } - - @Override - public void lockInterruptibly() throws InterruptedException { - try (Jedis jedis = jedisPool.getResource()) { - if (!lock.acquire(jedis)) { - throw new RuntimeException("acquire timeouted"); - } - } - } - - @Override - public boolean tryLock() { - try (Jedis jedis = jedisPool.getResource()) { - return lock.acquire(jedis); - } catch (InterruptedException e) { - throw new RuntimeException("lock failed", e); - } - } - - @Override - public boolean tryLock(long time, TimeUnit unit) throws InterruptedException { - try (Jedis jedis = jedisPool.getResource()) { - return lock.acquire(jedis); - } - } - - @Override - public void unlock() { - try (Jedis jedis = jedisPool.getResource()) { - lock.release(jedis); - } - } - - @Override - public Condition newCondition() { - throw new RuntimeException("unsupported method"); - } - + protected Jedis getJedis() { + return jedisPool.getResource(); } } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaRedisConnectionConfigImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaRedisConnectionConfigImpl.java new file mode 100644 index 0000000000..e48cda2040 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaRedisConnectionConfigImpl.java @@ -0,0 +1,24 @@ +package cn.binarywang.wx.miniapp.config.impl; + +import redis.clients.jedis.Jedis; + +/** + * 基于Redis的微信配置provider. 使用自己管理的 Jedis 实例进行 Redis 操作。 + * + *
+ * 需要引入依赖jedis-lock,才能使用该类。
+ * 
+ */ +public class WxMaRedisConnectionConfigImpl extends AbstractWxMaRedisConfig { + + public WxMaRedisConnectionConfigImpl(Jedis jedis) { + this.jedis = jedis; + } + + private Jedis jedis; + + @Override + protected Jedis getJedis() { + return jedis; + } +} From 2369aa7cb3cf397fe239990ba5369d4106f3c58c Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 8 Dec 2019 23:50:17 +0800 Subject: [PATCH 0010/1706] =?UTF-8?q?:art:=20=E4=BC=98=E5=8C=96=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E5=BE=AE=E4=BF=A1=E5=B0=8F=E7=A8=8B=E5=BA=8F=E8=AE=A2?= =?UTF-8?q?=E9=98=85=E6=B6=88=E6=81=AF=E7=9B=B8=E5=85=B3=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wx/miniapp/bean/WxMaSubscribeData.java | 30 ------------------- .../wx/miniapp/bean/WxMaSubscribeMessage.java | 16 +++++++--- .../json/WxMaSubscribeMessageGsonAdapter.java | 10 ++++--- 3 files changed, 18 insertions(+), 38 deletions(-) delete mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeData.java diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeData.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeData.java deleted file mode 100644 index 048e6dae89..0000000000 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeData.java +++ /dev/null @@ -1,30 +0,0 @@ -package cn.binarywang.wx.miniapp.bean; - -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - *
- * 参考文档 https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html
- * 
- */ -@Data -@NoArgsConstructor -public class WxMaSubscribeData { - private String name; - private String value; - private String color; - - public WxMaSubscribeData(String name, String value) { - this.name = name; - this.value = value; - } - - public WxMaSubscribeData(String name, String value, String color) { - this.name = name; - this.value = value; - this.color = color; - } - - -} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeMessage.java index a43fd5b47f..fda1959842 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeMessage.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeMessage.java @@ -10,6 +10,8 @@ /** * 订阅消息. * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html + * + * @author S */ @Getter @Setter @@ -17,7 +19,6 @@ @AllArgsConstructor @Builder public class WxMaSubscribeMessage implements Serializable { - private static final long serialVersionUID = 6846729898251286686L; /** @@ -58,10 +59,9 @@ public class WxMaSubscribeMessage implements Serializable { * 描述: 模板内容,不填则下发空模板 *
*/ - private List data; - + private List data; - public WxMaSubscribeMessage addData(WxMaSubscribeData datum) { + public WxMaSubscribeMessage addData(Data datum) { if (this.data == null) { this.data = new ArrayList<>(); } @@ -74,4 +74,12 @@ public String toJson() { return WxMaGsonBuilder.create().toJson(this); } + @lombok.Data + @NoArgsConstructor + @AllArgsConstructor + public static class Data { + private String name; + private String value; + } + } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaSubscribeMessageGsonAdapter.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaSubscribeMessageGsonAdapter.java index d15226a9e7..1d213d4a05 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaSubscribeMessageGsonAdapter.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaSubscribeMessageGsonAdapter.java @@ -1,6 +1,5 @@ package cn.binarywang.wx.miniapp.util.json; -import cn.binarywang.wx.miniapp.bean.WxMaSubscribeData; import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @@ -9,8 +8,12 @@ import java.lang.reflect.Type; +/** + * . + * + * @author S + */ public class WxMaSubscribeMessageGsonAdapter implements JsonSerializer { - @Override public JsonElement serialize(WxMaSubscribeMessage message, Type typeOfSrc, JsonSerializationContext context) { JsonObject messageJson = new JsonObject(); @@ -20,7 +23,6 @@ public JsonElement serialize(WxMaSubscribeMessage message, Type typeOfSrc, JsonS messageJson.addProperty("page", message.getPage()); } - JsonObject data = new JsonObject(); messageJson.add("data", data); @@ -28,7 +30,7 @@ public JsonElement serialize(WxMaSubscribeMessage message, Type typeOfSrc, JsonS return messageJson; } - for (WxMaSubscribeData datum : message.getData()) { + for (WxMaSubscribeMessage.Data datum : message.getData()) { JsonObject dataJson = new JsonObject(); dataJson.addProperty("value", datum.getValue()); data.add(datum.getName(), dataJson); From 0ab307c34b19e6e9aa8e2a51926bf07a6cbc15c4 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Wed, 11 Dec 2019 17:46:48 +0800 Subject: [PATCH 0011/1706] =?UTF-8?q?:art:=20=E4=BC=98=E5=8C=96=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E5=BE=AE=E4=BF=A1=E5=B0=8F=E7=A8=8B=E5=BA=8F=E8=AE=A2?= =?UTF-8?q?=E9=98=85=E6=B6=88=E6=81=AF=E7=9B=B8=E5=85=B3=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wx/miniapp/api/impl/WxMaMsgServiceImplTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 f5f62cc57f..132ea55e88 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 @@ -64,9 +64,9 @@ public void testSendSubscribeMsg() throws WxErrorException { WxMaSubscribeMessage message = new WxMaSubscribeMessage(); message.setTemplateId(config.getTemplateId()); message.setToUser(config.getOpenid()); - message.addData(new WxMaSubscribeData("thing1", "苹果到货啦")); - message.addData(new WxMaSubscribeData("amount3", "¥5")); - message.addData(new WxMaSubscribeData("thing5", "记得领取哦")); + message.addData(new WxMaSubscribeMessage.Data("thing1", "苹果到货啦")); + message.addData(new WxMaSubscribeMessage.Data("amount3", "¥5")); + message.addData(new WxMaSubscribeMessage.Data("thing5", "记得领取哦")); this.wxService.getMsgService().sendSubscribeMsg(message); } From c70706c9aaa90ac642168dc38e08ac6d820cbcba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=85=B1=E6=B2=B999=E5=8F=B7?= <779687795@qq.com> Date: Wed, 11 Dec 2019 17:50:41 +0800 Subject: [PATCH 0012/1706] =?UTF-8?q?:sparkles:=09#1309=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=8F=91=E9=80=81=E5=92=8C=E6=9F=A5=E8=AF=A2=E4=BC=81?= =?UTF-8?q?=E4=B8=9A=E5=BE=AE=E4=BF=A1=E7=BA=A2=E5=8C=85=E7=9A=84=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加 企业支付密钥的配置参数 --- .../java/com/github/binarywang/wxpay/config/WxPayConfig.java | 4 ++++ .../binarywang/wxpay/service/impl/EntPayServiceImpl.java | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java index 9192a4bafc..c0ca2cf552 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/config/WxPayConfig.java @@ -51,6 +51,10 @@ public class WxPayConfig { * 商户密钥. */ private String mchKey; + /** + * 企业支付密钥. + */ + private String entPayKey; /** * 服务商模式下的子商户号. */ 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 1db5bc40fd..5e768bef99 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 @@ -3,6 +3,7 @@ import com.github.binarywang.wxpay.bean.entpay.*; import com.github.binarywang.wxpay.bean.request.WxPayDefaultRequest; import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; +import com.github.binarywang.wxpay.constant.WxPayConstants; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.EntPayService; import com.github.binarywang.wxpay.service.WxPayService; @@ -135,7 +136,7 @@ public EntPayBankQueryResult queryPayBank(EntPayBankQueryRequest request) throws public EntPayRedpackResult sendEnterpriseRedpack(EntPayRedpackRequest request) throws WxPayException { //企业微信签名,需要在请求签名之前 request.setNonceStr(String.valueOf(System.currentTimeMillis())); - request.setWorkWxSign(SignUtils.createEntSign(request.getActName(),request.getMchBillNo(),request.getMchId(),request.getNonceStr(),request.getReOpenid(),request.getTotalAmount(),request.getWxAppId(),"Hcf-X_dzLeaTIyK33okGmODK8sLzc7kLrgkWXOAoMbE","MD5")); + request.setWorkWxSign(SignUtils.createEntSign(request.getActName(), request.getMchBillNo(), request.getMchId(), request.getNonceStr(), request.getReOpenid(), request.getTotalAmount(), request.getWxAppId(), payService.getConfig().getEntPayKey(), WxPayConstants.SignType.MD5)); request.checkAndSign(this.payService.getConfig()); From dd6a1c05291fc47eceafb40b43aa0eec63d3d8f6 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 16 Dec 2019 00:29:03 +0800 Subject: [PATCH 0013/1706] =?UTF-8?q?:new:=20#1320=20=E5=B0=8F=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F=E6=A8=A1=E5=9D=97=E5=A2=9E=E5=8A=A0=E8=AE=A2=E9=98=85?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E6=A8=A1=E6=9D=BF=E8=AE=BE=E7=BD=AE=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../util/http/apache/Utf8ResponseHandler.java | 2 +- .../wx/miniapp/api/WxMaMsgService.java | 11 +- .../wx/miniapp/api/WxMaService.java | 8 + .../wx/miniapp/api/WxMaSubscribeService.java | 153 ++++++++++++++++++ .../wx/miniapp/api/WxMaTemplateService.java | 4 + .../miniapp/api/impl/WxMaMsgServiceImpl.java | 5 - .../wx/miniapp/api/impl/WxMaServiceImpl.java | 10 +- .../api/impl/WxMaSubscribeServiceImpl.java | 74 +++++++++ .../impl/WxMaSubscribeServiceImplTest.java | 62 +++++++ .../api/impl/WxMaTemplateServiceImplTest.java | 5 +- 10 files changed, 322 insertions(+), 12 deletions(-) create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImpl.java create mode 100644 weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImplTest.java diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/Utf8ResponseHandler.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/Utf8ResponseHandler.java index 697d4695e2..035726d44f 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/Utf8ResponseHandler.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/Utf8ResponseHandler.java @@ -25,7 +25,7 @@ public String handleResponse(final HttpResponse response) throws IOException { final HttpEntity entity = response.getEntity(); if (statusLine.getStatusCode() >= 300) { EntityUtils.consume(entity); - throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase()); + throw new HttpResponseException(statusLine.getStatusCode(), statusLine.toString()); } return entity == null ? null : EntityUtils.toString(entity, Consts.UTF_8); } 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 3dec5140fd..2dc627eb97 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 @@ -33,16 +33,23 @@ public interface WxMaMsgService { * 发送模板消息 * 详情请见: 发送模板消息 * 接口url格式:https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN + * 小程序模板消息接口将于2020年1月10日下线,开发者可使用订阅消息功能 *
+ * + * @param templateMessage 模版消息 + * @throws WxErrorException . */ + @Deprecated void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException; - /** *
+   * 发送订阅消息
    * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.send.html
    * 
- * 发送订阅消息 + * + * @param subscribeMessage 订阅消息 + * @throws WxErrorException . */ void sendSubscribeMsg(WxMaSubscribeMessage subscribeMessage) throws WxErrorException; 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 695590a6b2..49cf594028 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 @@ -158,6 +158,13 @@ public interface WxMaService { */ WxMaTemplateService getTemplateService(); + /** + * 返回订阅消息配置相关接口方法的实现类对象, 以方便调用其各个接口. + * + * @return WxMaSubscribeService + */ + WxMaSubscribeService getSubscribeService(); + /** * 数据分析相关查询服务. * @@ -226,6 +233,7 @@ public interface WxMaService { /** * 获取物流助手接口服务对象 + * * @return */ WxMaExpressService getExpressService(); diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java new file mode 100644 index 0000000000..9aa6cea2cc --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java @@ -0,0 +1,153 @@ +package cn.binarywang.wx.miniapp.api; + +import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryListResult; +import lombok.Data; +import me.chanjar.weixin.common.error.WxErrorException; + +import java.util.List; + +/** + * 订阅消息类 + * + * @author Binary Wang + * @date 2019-12-15 + */ +public interface WxMaSubscribeService { + /** + * 获取模板标题下的关键词列表. + */ + String GET_PUB_TEMPLATE_TITLE_LIST_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatetitles"; + + /** + * 获取模板标题下的关键词列表. + */ + String GET_PUB_TEMPLATE_KEY_WORDS_BY_ID_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatekeywords"; + + /** + * 组合模板并添加至帐号下的个人模板库. + */ + String TEMPLATE_ADD_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate"; + + /** + * 获取当前帐号下的个人模板列表. + */ + String TEMPLATE_LIST_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate"; + + /** + * 删除帐号下的某个模板. + */ + String TEMPLATE_DEL_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/deltemplate"; + + /** + * 获取小程序账号的类目 + */ + String GET_CATEGORY_URL = "https://api.weixin.qq.com/wxaapi/newtmpl/getcategory"; + + /** + *
+   * 获取帐号所属类目下的公共模板标题
+   *
+   * 详情请见: 获取帐号所属类目下的公共模板标题
+   * 接口url格式: https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatetitles?access_token=ACCESS_TOKEN
+   * 
+ * + * @param ids 类目 id,多个用逗号隔开 + * @param limit 用于分页,表示拉取 limit 条记录。最大为 30。 + * @param start 用于分页,表示从 start 开始。从 0 开始计数。 + * @return . + * @throws WxErrorException . + */ + WxMaTemplateLibraryListResult getPubTemplateTitleList(Integer[] ids, int start, int limit) throws WxErrorException; + + /** + *
+   * 获取模板库某个模板标题下关键词库
+   *
+   * 详情请见: 获取模板标题下的关键词列表
+   * 接口url格式: GET https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatekeywords?access_token=ACCESS_TOKEN
+   * 
+ * + * @param id 模板标题 id,可通过接口获取 + * @return . + * @throws WxErrorException . + */ + List getPubTemplateKeyWordsById(String id) throws WxErrorException; + + /** + *
+   * 组合模板并添加至帐号下的个人模板库
+   *
+   * 详情请见: 获取小程序模板库标题列表
+   * 接口url格式: POST https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate?access_token=ACCESS_TOKEN
+   * 
+ * + * @param id 模板标题 id,可通过接口获取,也可登录小程序后台查看获取 + * @param keywordIdList 模板关键词列表 + * @param sceneDesc 服务场景描述,15个字以内 + * @return 添加至帐号下的模板id,发送小程序订阅消息时所需 + * @throws WxErrorException . + */ + String addTemplate(String id, List keywordIdList, String sceneDesc) throws WxErrorException; + + /** + *
+   * 获取当前帐号下的个人模板列表
+   *
+   * 详情请见: 获取当前帐号下的个人模板列表
+   * 接口url格式: GET https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate?access_token=ACCESS_TOKEN
+   * 
+ * + * @return . + * @throws WxErrorException . + */ + List getTemplateList() throws WxErrorException; + + /** + *
+   * 删除帐号下的某个模板
+   *
+   * 详情请见: 删除帐号下的个人模板
+   * 接口url格式: POST https://api.weixin.qq.com/wxaapi/newtmpl/deltemplate?access_token=ACCESS_TOKEN
+   * 
+ * + * @param templateId 要删除的模板id + * @return 删除是否成功 + * @throws WxErrorException . + */ + boolean delTemplate(String templateId) throws WxErrorException; + + /** + *
+   * 获取小程序账号的类目
+   * https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/subscribe-message/subscribeMessage.getCategory.html
+   * GET https://api.weixin.qq.com/wxaapi/newtmpl/getcategory?access_token=ACCESS_TOKEN
+   * 
+ * + * @return . + * @throws WxErrorException . + */ + List getCategory() throws WxErrorException; + + @Data + class CategoryData { + int id; + String name; + } + + @Data + class TemplateInfo { + private String priTmplId; + private String title; + private String content; + private String example; + private int type; + } + + @Data + class PubTemplateKeyword{ + private int kid; + private String name; + private String example; + private String rule; + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaTemplateService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaTemplateService.java index 3973774f00..cbdd3c7585 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaTemplateService.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaTemplateService.java @@ -8,6 +8,10 @@ import java.util.List; +/** + * @author IOMan(lewis.lynn1006@gmail.com) + */ +@Deprecated public interface WxMaTemplateService { /** * 获取小程序模板库标题列表. diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java index 26ebd74bc6..1a059983e2 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java @@ -28,11 +28,6 @@ public boolean sendKefuMsg(WxMaKefuMessage message) throws WxErrorException { return responseContent != null; } - /** - *
-   * 小程序模板消息接口将于2020年1月10日下线,开发者可使用订阅消息功能
-   * 
- */ @Override public void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException { String responseContent = this.wxMaService.post(TEMPLATE_MSG_SEND_URL, templateMessage.toJson()); 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 0a6da86143..6899e708a4 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 @@ -55,6 +55,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttpBinary Wang + * @date 2019-12-15 + */ +@AllArgsConstructor +public class WxMaSubscribeServiceImpl implements WxMaSubscribeService { + private WxMaService wxMaService; + + @Override + public WxMaTemplateLibraryListResult getPubTemplateTitleList(Integer[] ids, int start, int limit) throws WxErrorException { + ImmutableMap params = ImmutableMap.of("ids", StringUtils.join(ids, ","), + "start", start, "limit", limit); + String responseText = this.wxMaService.post(GET_PUB_TEMPLATE_TITLE_LIST_URL, WxGsonBuilder.create().toJson(params)); + return WxMaTemplateLibraryListResult.fromJson(responseText); + } + + @Override + public List getPubTemplateKeyWordsById(String id) throws WxErrorException { + String responseText = this.wxMaService.post(GET_PUB_TEMPLATE_KEY_WORDS_BY_ID_URL, + WxGsonBuilder.create().toJson(ImmutableMap.of("tid", id))); + return WxMaGsonBuilder.create().fromJson(new JsonParser().parse(responseText).getAsJsonObject() + .getAsJsonArray("data"), new TypeToken>() { + }.getType()); + } + + @Override + public String addTemplate(String id, List keywordIdList, String sceneDesc) throws WxErrorException { + String responseText = this.wxMaService.post(TEMPLATE_ADD_URL, WxGsonBuilder.create().toJson(ImmutableMap.of("tid", id, + "kidList", keywordIdList.toArray(), + "sceneDesc", sceneDesc))); + return new JsonParser().parse(responseText).getAsJsonObject().get("priTmplId").getAsString(); + } + + @Override + public List getTemplateList() throws WxErrorException { + String responseText = this.wxMaService.get(TEMPLATE_LIST_URL, null); + return WxMaGsonBuilder.create().fromJson(new JsonParser().parse(responseText).getAsJsonObject() + .getAsJsonArray("data"), new TypeToken>() { + }.getType()); + } + + @Override + public boolean delTemplate(String templateId) throws WxErrorException { + Map params = ImmutableMap.of("priTmplId", templateId); + this.wxMaService.post(TEMPLATE_DEL_URL, WxGsonBuilder.create().toJson(params)); + return true; + } + + @Override + public List getCategory() throws WxErrorException { + String responseText = this.wxMaService.get(GET_CATEGORY_URL, null); + return WxMaGsonBuilder.create().fromJson(new JsonParser().parse(responseText).getAsJsonObject() + .getAsJsonArray("data"), new TypeToken>() { + }.getType()); + } +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImplTest.java new file mode 100644 index 0000000000..706a13dba3 --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImplTest.java @@ -0,0 +1,62 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.api.WxMaSubscribeService; +import cn.binarywang.wx.miniapp.test.ApiTestModule; +import com.google.common.collect.Lists; +import com.google.inject.Inject; +import me.chanjar.weixin.common.error.WxErrorException; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * 测试类. + * + * @author Binary Wang + * @date 2019-12-15 + */ +@Test +@Guice(modules = ApiTestModule.class) +public class WxMaSubscribeServiceImplTest { + @Inject + protected WxMaService wxService; + + @Test + public void testGetPubTemplateTitleList() throws WxErrorException { + this.wxService.getSubscribeService().getPubTemplateTitleList(new Integer[]{578}, 1, 1); + } + + @Test + public void testGetPubTemplateKeyWordsById() throws WxErrorException { + final List result = this.wxService.getSubscribeService().getPubTemplateKeyWordsById("578"); + System.out.println(result); + } + + @Test + public void testAddTemplate() throws WxErrorException { + final String templateId = this.wxService.getSubscribeService().addTemplate("1", Lists.newArrayList(1), ""); + System.out.println(templateId); + } + + @Test + public void testGetTemplateList() throws WxErrorException { + final List templateList = this.wxService.getSubscribeService().getTemplateList(); + System.out.println(templateList); + } + + @Test + public void testDelTemplate() throws WxErrorException { + this.wxService.getSubscribeService().delTemplate("priTmplId"); + } + + @Test + public void testGetCategory() throws WxErrorException { + final List categoryData = this.wxService.getSubscribeService().getCategory(); + assertThat(categoryData).isNotNull(); + System.out.println(categoryData); + } +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaTemplateServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaTemplateServiceImplTest.java index 5dfa86a8b0..57896685bb 100644 --- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaTemplateServiceImplTest.java +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaTemplateServiceImplTest.java @@ -17,7 +17,6 @@ @Test @Guice(modules = ApiTestModule.class) public class WxMaTemplateServiceImplTest { - @Inject protected WxMaService wxService; @@ -36,7 +35,7 @@ public void testFindTemplateLibraryKeywordList() throws Exception { } @Test - public void testAddTemplate() throws Exception{ + public void testAddTemplate() throws Exception { List list = Lists.newArrayList(); list.add(1); list.add(20); @@ -48,7 +47,7 @@ public void testAddTemplate() throws Exception{ } @Test - public void testFindTemplateList() throws Exception{ + public void testFindTemplateList() throws Exception { WxMaTemplateListResult result = this.wxService.getTemplateService().findTemplateList(0, 20); System.out.println(result); } From e1ca4e02b7f8704ed513adaee636f0420436d107 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 16 Dec 2019 09:18:46 +0800 Subject: [PATCH 0014/1706] =?UTF-8?q?:bookmark:=20=E5=8F=91=E5=B8=833.6.2.?= =?UTF-8?q?B=E6=B5=8B=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 +- spring-boot-starters/pom.xml | 2 +- .../wx-java-miniapp-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-pay-spring-boot-starter/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 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index 8c51152fbb..00f79a0a76 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.github.binarywang wx-java - 3.6.1.B + 3.6.2.B pom WxJava - Weixin/Wechat Java SDK 微信开发Java SDK diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml index 8c415da0bb..87e91eaf8e 100644 --- a/spring-boot-starters/pom.xml +++ b/spring-boot-starters/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 3.6.1.B + 3.6.2.B pom wx-java-spring-boot-starters diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml index 2b07695911..441e4dc148 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.1.B + 3.6.2.B 4.0.0 diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml index 18107230e4..b0cd46ade6 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.1.B + 3.6.2.B 4.0.0 diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml index 4407d1ec7c..b5350977e7 100644 --- a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.1.B + 3.6.2.B 4.0.0 diff --git a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml index 3cadb3a4ec..2c8a2476a4 100644 --- a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.1.B + 3.6.2.B 4.0.0 diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index a87098fa77..cfb9182801 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 3.6.1.B + 3.6.2.B weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 14eaa4cf08..ae32e5e2cd 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.1.B + 3.6.2.B weixin-java-cp diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index 8a336ac089..2b08c716a2 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.1.B + 3.6.2.B weixin-java-miniapp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 9c662767ec..b4166d5be1 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.1.B + 3.6.2.B weixin-java-mp diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index c74afffdd8..4002f15376 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.1.B + 3.6.2.B weixin-java-open diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index 4e5a2d2a7b..81daf5f212 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ com.github.binarywang wx-java - 3.6.1.B + 3.6.2.B 4.0.0 From 71ba078768b6544cccd3744842a2b13e393ac7bc Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Fri, 20 Dec 2019 12:54:40 +0800 Subject: [PATCH 0015/1706] =?UTF-8?q?:bug:=20=E4=BF=AE=E5=A4=8D=E5=9B=BE?= =?UTF-8?q?=E6=96=87=E6=B6=88=E6=81=AF=E7=95=99=E8=A8=80=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E4=B8=ADmsgDataId=E7=B1=BB=E5=9E=8B=E4=B8=8E?= =?UTF-8?q?=E7=BE=A4=E5=8F=91=E6=B6=88=E6=81=AF=E6=8E=A5=E5=8F=A3=E7=9A=84?= =?UTF-8?q?=E6=B6=88=E6=81=AFid=E7=B1=BB=E5=9E=8B=E4=B8=8D=E4=B8=80?= =?UTF-8?q?=E8=87=B4=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/mp/api/WxMpCommentService.java | 8 ++++---- .../weixin/mp/api/impl/WxMpCommentServiceImpl.java | 6 +++--- .../weixin/mp/api/impl/WxMpCommentServiceImplTest.java | 10 +++++----- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCommentService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCommentService.java index 423f61a739..1d96c968ae 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCommentService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCommentService.java @@ -5,7 +5,7 @@ /** * 图文消息留言管理接口. - * https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1494572718_WzHIY + * https://developers.weixin.qq.com/doc/offiaccount/Comments_management/Image_Comments_Management_Interface.html * * @author Binary Wang * @date 2019-06-16 @@ -19,7 +19,7 @@ public interface WxMpCommentService { * @param index 多图文时,用来指定第几篇图文,从0开始,不带默认操作该msg_data_id的第一篇图文 * @throws WxErrorException 异常 */ - void open(Integer msgDataId, Integer index) throws WxErrorException; + void open(String msgDataId, Integer index) throws WxErrorException; /** * 关闭已群发文章评论. @@ -29,7 +29,7 @@ public interface WxMpCommentService { * @param index 多图文时,用来指定第几篇图文,从0开始,不带默认操作该msg_data_id的第一篇图文 * @throws WxErrorException 异常 */ - void close(Integer msgDataId, Integer index) throws WxErrorException; + void close(String msgDataId, Integer index) throws WxErrorException; /** * 查看指定文章的评论数据. @@ -43,5 +43,5 @@ public interface WxMpCommentService { * @return 评论列表数据 * @throws WxErrorException 异常 */ - WxMpCommentListVo list(Integer msgDataId, Integer index, int begin, int count, int type) throws WxErrorException; + WxMpCommentListVo list(String msgDataId, Integer index, int begin, int count, int type) throws WxErrorException; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImpl.java index 8d97af36e3..02315cc206 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImpl.java @@ -18,7 +18,7 @@ public class WxMpCommentServiceImpl implements WxMpCommentService { private final WxMpService wxMpService; @Override - public void open(Integer msgDataId, Integer index) throws WxErrorException { + public void open(String msgDataId, Integer index) throws WxErrorException { JsonObject json = new JsonObject(); json.addProperty("msg_data_id", msgDataId); if (index != null) { @@ -29,7 +29,7 @@ public void open(Integer msgDataId, Integer index) throws WxErrorException { } @Override - public void close(Integer msgDataId, Integer index) throws WxErrorException { + public void close(String msgDataId, Integer index) throws WxErrorException { JsonObject json = new JsonObject(); json.addProperty("msg_data_id", msgDataId); if (index != null) { @@ -40,7 +40,7 @@ public void close(Integer msgDataId, Integer index) throws WxErrorException { } @Override - public WxMpCommentListVo list(Integer msgDataId, Integer index, int begin, int count, int type) throws WxErrorException { + public WxMpCommentListVo list(String msgDataId, Integer index, int begin, int count, int type) throws WxErrorException { JsonObject json = new JsonObject(); json.addProperty("msg_data_id", msgDataId); json.addProperty("begin", begin); diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImplTest.java index efbf6e1814..5f4bdecfb9 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImplTest.java @@ -31,14 +31,14 @@ public class WxMpCommentServiceImplTest { @Test public void testOpen() throws WxErrorException { - this.wxService.getCommentService().open(1, null); - this.wxService.getCommentService().open(1, 0); + this.wxService.getCommentService().open("1", null); + this.wxService.getCommentService().open("1", 0); } @Test public void testClose() throws WxErrorException { - this.wxService.getCommentService().close(1000000001, null); - this.wxService.getCommentService().close(1, 0); + this.wxService.getCommentService().close("1000000001", null); + this.wxService.getCommentService().close("1", 0); } @Test @@ -66,7 +66,7 @@ public void testList() throws WxErrorException { WxMpCommentService commentService = new WxMpCommentServiceImpl(wxService); doReturn(expectedResponse).when(wxService).post(anyString(), anyString()); - final WxMpCommentListVo commentListVo = commentService.list(1, 1, 1, 1, 1); + final WxMpCommentListVo commentListVo = commentService.list("1", 1, 1, 1, 1); assertThat(commentListVo).isNotNull(); System.out.println(commentListVo); assertThat(commentListVo.getTotal()).isEqualTo(1); From 5f9c813b4e6d22efe763404b6f662808a0c66559 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Fri, 20 Dec 2019 12:54:58 +0800 Subject: [PATCH 0016/1706] =?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 --- .../java/me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java | 2 +- .../java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java | 2 +- .../java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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 9c7396ab1b..700c4d2e66 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 @@ -205,7 +205,7 @@ public WxCpProviderToken getProviderToken(String corpId, String providerSecret) JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("corpid", corpId); jsonObject.addProperty("provider_secret", providerSecret); - return WxCpProviderToken.fromJson(this.post(this.configStorage.getApiUrl(GET_PROVIDER_TOKEN), jsonObject.toString())); + return WxCpProviderToken.fromJson(this.post(this.configStorage.getApiUrl(Tp.GET_PROVIDER_TOKEN), jsonObject.toString())); } @Override diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java index 4681346451..8681ec7d4e 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java @@ -21,7 +21,6 @@ public final class WxCpApiPathConsts { public static final String BATCH_GET_RESULT = "/cgi-bin/batch/getresult?jobid="; public static final String JSCODE_TO_SESSION = "/cgi-bin/miniprogram/jscode2session"; public static final String GET_TOKEN = "/cgi-bin/gettoken?corpid=%s&corpsecret=%s"; - public static final String GET_PROVIDER_TOKEN = "/cgi-bin/service/get_provider_token"; public static class Agent { public static final String AGENT_GET = "/cgi-bin/agent/get?agentid=%d"; @@ -88,6 +87,7 @@ public static class Tp { public static final String GET_CORP_TOKEN = "/cgi-bin/service/get_corp_token"; public static final String GET_PERMANENT_CODE = "/cgi-bin/service/get_permanent_code"; public static final String GET_SUITE_TOKEN = "/cgi-bin/service/get_suite_token"; + public static final String GET_PROVIDER_TOKEN = "/cgi-bin/service/get_provider_token"; } public static class User { diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java index 9aa6cea2cc..4d570693b3 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java @@ -144,7 +144,7 @@ class TemplateInfo { } @Data - class PubTemplateKeyword{ + class PubTemplateKeyword { private int kid; private String name; private String example; From 9c58930719fba624a278e530755b00a104233452 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Fri, 20 Dec 2019 16:56:12 +0800 Subject: [PATCH 0017/1706] =?UTF-8?q?:art:=20=E4=BC=98=E5=8C=96=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E5=BE=AE=E4=BF=A1=E5=B0=8F=E7=A8=8B=E5=BA=8F=E8=AE=A2?= =?UTF-8?q?=E9=98=85=E6=B6=88=E6=81=AF=E6=A8=A1=E6=9D=BF=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ApacheSimplePostRequestExecutor.java | 1 + .../wx/miniapp/api/WxMaService.java | 5 +++++ .../wx/miniapp/api/impl/WxMaServiceImpl.java | 6 ++++++ .../api/impl/WxMaSubscribeServiceImpl.java | 20 +++++++------------ .../impl/WxMaSubscribeServiceImplTest.java | 2 +- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java index 3405aaab78..960ea865af 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java @@ -36,6 +36,7 @@ public String execute(String uri, String postEntity, WxType wxType) throws WxErr if (postEntity != null) { StringEntity entity = new StringEntity(postEntity, Consts.UTF_8); + entity.setContentType("application/json; charset=utf-8"); httpPost.setEntity(entity); } 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 49cf594028..d4f74683e0 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 @@ -86,6 +86,11 @@ public interface WxMaService { */ String post(String url, String postData) throws WxErrorException; + /** + * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求. + */ + String post(String url, Object obj) throws WxErrorException; + /** *
    * Service没有实现某个API的时候,可以用这个,
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 6899e708a4..38ce9cc4a3 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
@@ -16,6 +16,7 @@
 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 me.chanjar.weixin.common.util.json.WxGsonBuilder;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.http.HttpHost;
 import org.apache.http.client.config.RequestConfig;
@@ -206,6 +207,11 @@ public String post(String url, String postData) throws WxErrorException {
     return execute(SimplePostRequestExecutor.create(this), url, postData);
   }
 
+  @Override
+  public String post(String url, Object obj) throws WxErrorException {
+    return this.execute(SimplePostRequestExecutor.create(this), url, WxGsonBuilder.create().toJson(obj));
+  }
+
   /**
    * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求
    */
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImpl.java
index 8b04b670ed..d4c2af333d 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImpl.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImpl.java
@@ -9,12 +9,9 @@
 import com.google.gson.reflect.TypeToken;
 import lombok.AllArgsConstructor;
 import me.chanjar.weixin.common.error.WxErrorException;
-import me.chanjar.weixin.common.util.json.WxGsonBuilder;
 import org.apache.commons.lang3.StringUtils;
 
-import java.io.Serializable;
 import java.util.List;
-import java.util.Map;
 
 /**
  * @author Binary Wang
@@ -26,16 +23,14 @@ public class WxMaSubscribeServiceImpl implements WxMaSubscribeService {
 
   @Override
   public WxMaTemplateLibraryListResult getPubTemplateTitleList(Integer[] ids, int start, int limit) throws WxErrorException {
-    ImmutableMap params = ImmutableMap.of("ids", StringUtils.join(ids, ","),
-      "start", start, "limit", limit);
-    String responseText = this.wxMaService.post(GET_PUB_TEMPLATE_TITLE_LIST_URL, WxGsonBuilder.create().toJson(params));
-    return WxMaTemplateLibraryListResult.fromJson(responseText);
+    return WxMaTemplateLibraryListResult.fromJson(this.wxMaService.post(GET_PUB_TEMPLATE_TITLE_LIST_URL,
+      ImmutableMap.of("ids", StringUtils.join(ids, ","),
+        "start", start, "limit", limit)));
   }
 
   @Override
   public List getPubTemplateKeyWordsById(String id) throws WxErrorException {
-    String responseText = this.wxMaService.post(GET_PUB_TEMPLATE_KEY_WORDS_BY_ID_URL,
-      WxGsonBuilder.create().toJson(ImmutableMap.of("tid", id)));
+    String responseText = this.wxMaService.post(GET_PUB_TEMPLATE_KEY_WORDS_BY_ID_URL, ImmutableMap.of("tid", id));
     return WxMaGsonBuilder.create().fromJson(new JsonParser().parse(responseText).getAsJsonObject()
       .getAsJsonArray("data"), new TypeToken>() {
     }.getType());
@@ -43,9 +38,9 @@ public List getPubTemplateKeyWordsById(String id) throws WxE
 
   @Override
   public String addTemplate(String id, List keywordIdList, String sceneDesc) throws WxErrorException {
-    String responseText = this.wxMaService.post(TEMPLATE_ADD_URL, WxGsonBuilder.create().toJson(ImmutableMap.of("tid", id,
+    String responseText = this.wxMaService.post(TEMPLATE_ADD_URL, ImmutableMap.of("tid", id,
       "kidList", keywordIdList.toArray(),
-      "sceneDesc", sceneDesc)));
+      "sceneDesc", sceneDesc));
     return new JsonParser().parse(responseText).getAsJsonObject().get("priTmplId").getAsString();
   }
 
@@ -59,8 +54,7 @@ public List getTemplateList() throws WxErrorException {
 
   @Override
   public boolean delTemplate(String templateId) throws WxErrorException {
-    Map params = ImmutableMap.of("priTmplId", templateId);
-    this.wxMaService.post(TEMPLATE_DEL_URL, WxGsonBuilder.create().toJson(params));
+    this.wxMaService.post(TEMPLATE_DEL_URL, ImmutableMap.of("priTmplId", templateId));
     return true;
   }
 
diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImplTest.java
index 706a13dba3..5846743cd8 100644
--- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImplTest.java
+++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImplTest.java
@@ -38,7 +38,7 @@ public void testGetPubTemplateKeyWordsById() throws WxErrorException {
 
   @Test
   public void testAddTemplate() throws WxErrorException {
-    final String templateId = this.wxService.getSubscribeService().addTemplate("1", Lists.newArrayList(1), "");
+    final String templateId = this.wxService.getSubscribeService().addTemplate("1", Lists.newArrayList(1), "hhaa");
     System.out.println(templateId);
   }
 

From 8c514a7850e293d322dd5f35d1f74e2de693feba Mon Sep 17 00:00:00 2001
From: ArBing 
Date: Sun, 22 Dec 2019 16:05:09 +0800
Subject: [PATCH 0018/1706] =?UTF-8?q?:bug:=20#1327=20=E4=BF=AE=E5=A4=8D?=
 =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E8=8E=B7=E5=8F=96=E8=AE=A2=E9=98=85?=
 =?UTF-8?q?=E6=B6=88=E6=81=AF=E5=85=AC=E5=85=B1=E6=A8=A1=E6=9D=BF=E6=A0=87?=
 =?UTF-8?q?=E9=A2=98=E5=92=8C=E8=8E=B7=E5=8F=96=E5=85=B3=E9=94=AE=E8=AF=8D?=
 =?UTF-8?q?=E5=BA=93=E4=B8=A4=E4=B8=AA=E6=8E=A5=E5=8F=A3=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../wx/miniapp/api/WxMaSubscribeService.java      |  2 +-
 .../api/impl/WxMaSubscribeServiceImpl.java        | 15 ++++++++++-----
 .../api/impl/WxMaSubscribeServiceImplTest.java    |  6 +++---
 3 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java
index 4d570693b3..60c0d8a2c1 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java
@@ -57,7 +57,7 @@ public interface WxMaSubscribeService {
    * @return .
    * @throws WxErrorException .
    */
-  WxMaTemplateLibraryListResult getPubTemplateTitleList(Integer[] ids, int start, int limit) throws WxErrorException;
+  WxMaTemplateLibraryListResult getPubTemplateTitleList(String[] ids, int start, int limit) throws WxErrorException;
 
   /**
    * 
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImpl.java
index d4c2af333d..8da372c164 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImpl.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImpl.java
@@ -4,6 +4,7 @@
 import cn.binarywang.wx.miniapp.api.WxMaSubscribeService;
 import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryListResult;
 import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
+import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableMap;
 import com.google.gson.JsonParser;
 import com.google.gson.reflect.TypeToken;
@@ -11,6 +12,7 @@
 import me.chanjar.weixin.common.error.WxErrorException;
 import org.apache.commons.lang3.StringUtils;
 
+import java.io.Serializable;
 import java.util.List;
 
 /**
@@ -22,15 +24,18 @@ public class WxMaSubscribeServiceImpl implements WxMaSubscribeService {
   private WxMaService wxMaService;
 
   @Override
-  public WxMaTemplateLibraryListResult getPubTemplateTitleList(Integer[] ids, int start, int limit) throws WxErrorException {
-    return WxMaTemplateLibraryListResult.fromJson(this.wxMaService.post(GET_PUB_TEMPLATE_TITLE_LIST_URL,
-      ImmutableMap.of("ids", StringUtils.join(ids, ","),
-        "start", start, "limit", limit)));
+  public WxMaTemplateLibraryListResult getPubTemplateTitleList(String[] ids, int start, int limit) throws WxErrorException {
+    ImmutableMap params = ImmutableMap.of("ids", StringUtils.join(ids, ","),
+      "start", start, "limit", limit);
+    String responseText = this.wxMaService.get(GET_PUB_TEMPLATE_TITLE_LIST_URL,
+      Joiner.on("&").withKeyValueSeparator("=").join(params));
+    return WxMaTemplateLibraryListResult.fromJson(responseText);
   }
 
   @Override
   public List getPubTemplateKeyWordsById(String id) throws WxErrorException {
-    String responseText = this.wxMaService.post(GET_PUB_TEMPLATE_KEY_WORDS_BY_ID_URL, ImmutableMap.of("tid", id));
+    String responseText = this.wxMaService.get(GET_PUB_TEMPLATE_KEY_WORDS_BY_ID_URL,
+      Joiner.on("&").withKeyValueSeparator("=").join(ImmutableMap.of("tid", id)));
     return WxMaGsonBuilder.create().fromJson(new JsonParser().parse(responseText).getAsJsonObject()
       .getAsJsonArray("data"), new TypeToken>() {
     }.getType());
diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImplTest.java
index 5846743cd8..ef17d8306e 100644
--- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImplTest.java
+++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImplTest.java
@@ -27,18 +27,18 @@ public class WxMaSubscribeServiceImplTest {
 
   @Test
   public void testGetPubTemplateTitleList() throws WxErrorException {
-    this.wxService.getSubscribeService().getPubTemplateTitleList(new Integer[]{578}, 1, 1);
+    this.wxService.getSubscribeService().getPubTemplateTitleList(new String[]{"2", "616"}, 0, 1);
   }
 
   @Test
   public void testGetPubTemplateKeyWordsById() throws WxErrorException {
-    final List result = this.wxService.getSubscribeService().getPubTemplateKeyWordsById("578");
+    final List result = this.wxService.getSubscribeService().getPubTemplateKeyWordsById("99");
     System.out.println(result);
   }
 
   @Test
   public void testAddTemplate() throws WxErrorException {
-    final String templateId = this.wxService.getSubscribeService().addTemplate("1", Lists.newArrayList(1), "hhaa");
+    final String templateId = this.wxService.getSubscribeService().addTemplate("401", Lists.newArrayList(1, 2), "测试数据");
     System.out.println(templateId);
   }
 

From 5761226887a08f0f40a8a924f351a73b8642dece Mon Sep 17 00:00:00 2001
From: yang229 
Date: Sun, 22 Dec 2019 16:06:36 +0800
Subject: [PATCH 0019/1706] =?UTF-8?q?:new:=20#1328=20=E5=BE=AE=E4=BF=A1?=
 =?UTF-8?q?=E5=8D=A1=E5=8A=B5=E5=A2=9E=E5=8A=A0=E7=94=A8=E6=88=B7=E5=B7=B2?=
 =?UTF-8?q?=E9=A2=86=E5=8F=96=E5=8D=A1=E5=88=B8=E5=88=97=E8=A1=A8=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/mp/api/WxMpCardService.java        | 11 ++++++
 .../mp/api/impl/WxMpCardServiceImpl.java      | 10 +++++
 .../chanjar/weixin/mp/bean/card/UserCard.java | 34 +++++++++++++++++
 .../mp/bean/card/WxUserCardListResult.java    | 38 +++++++++++++++++++
 .../chanjar/weixin/mp/enums/WxMpApiUrl.java   |  5 +++
 .../mp/api/impl/WxMpCardServiceImplTest.java  |  9 +++++
 6 files changed, 107 insertions(+)
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/UserCard.java
 create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxUserCardListResult.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 2202f5568b..f0bd0b8f04 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
@@ -283,4 +283,15 @@ WxMpCardLandingPageCreateResult createLandingPage(WxMpCardLandingPageCreateReque
   void cardSelfConsumeCellSet(String cardId, Boolean isOpen,
                               Boolean needVerifyCod, Boolean needRemarkAmount) throws WxErrorException;
 
+  /**
+   * 获取用户已领取卡券接口
+   * https://developers.weixin.qq.com/doc/offiaccount/Cards_and_Offer/Managing_Coupons_Vouchers_and_Cards.html#1
+   *
+   * @param openId 需要查询的用户openid
+   * @param cardId 卡券ID。不填写时默认查询当前appid下的卡券
+   * @return
+   * @throws WxErrorException
+   */
+  WxUserCardListResult getUserCardList(String openId, 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 5cdc605baa..740c96e959 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
@@ -351,6 +351,16 @@ public void cardSelfConsumeCellSet(String cardId, Boolean isOpen,
   }
 
 
+  @Override
+  public WxUserCardListResult getUserCardList(String openId, String cardId) throws WxErrorException {
+    JsonObject param = new JsonObject();
+    param.addProperty("openid", openId);
+    param.addProperty("card_id", cardId);
+    String response = this.wxMpService.post(WxMpApiUrl.Card.CARD_USER_CARD_LIST, param.toString());
+    return WxUserCardListResult.fromJson(response);
+  }
+
+
   private void checkCardId(String cardId) throws WxErrorException {
     if (StringUtils.isEmpty(cardId)) {
       throw new WxErrorException(WxError.builder().errorCode(41012).errorMsg("cardId不能为空").build());
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/UserCard.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/UserCard.java
new file mode 100644
index 0000000000..5985988e01
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/UserCard.java
@@ -0,0 +1,34 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
+/**
+ * 用户已领卡圈对象
+ * @author yang229
+ * @date 2019/12/22
+ */
+@Data
+public class UserCard implements java.io.Serializable {
+  /**
+   * 用户卡券code码
+   */
+  @SerializedName("code")
+  private String code;
+
+  /**
+   * 卡券ID
+   */
+  @SerializedName("card_id")
+  private String cardId;
+
+  public static UserCard fromJson(String json) {
+    return WxMpGsonBuilder.create().fromJson(json, UserCard.class);
+  }
+
+  @Override
+  public String toString() {
+    return WxMpGsonBuilder.create().toJson(this);
+  }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxUserCardListResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxUserCardListResult.java
new file mode 100644
index 0000000000..9133a32f17
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/card/WxUserCardListResult.java
@@ -0,0 +1,38 @@
+package me.chanjar.weixin.mp.bean.card;
+
+import com.google.gson.annotations.SerializedName;
+import lombok.Data;
+import me.chanjar.weixin.mp.bean.result.WxMpResult;
+import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+
+import java.util.List;
+
+/**
+ * 用户已领卡券返回
+ * @author yang229
+ * @date 2019/12/22
+ */
+@Data
+public class WxUserCardListResult extends WxMpResult implements java.io.Serializable {
+
+  /**
+   * 卡券列表
+   */
+  @SerializedName("card_list")
+  private List cardList;
+
+  /**
+   * 是否有可用的朋友的券
+   */
+  @SerializedName("has_share_card")
+  private Boolean hasShareCard;
+
+  public static WxUserCardListResult fromJson(String json) {
+    return WxMpGsonBuilder.create().fromJson(json, WxUserCardListResult.class);
+  }
+
+  @Override
+  public String toString() {
+    return WxMpGsonBuilder.create().toJson(this);
+  }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java
index 5963af929d..c296481a80 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java
@@ -596,6 +596,11 @@ enum Card implements WxMpApiUrl {
      * 设置自助核销接口
      */
     CARD_SELF_CONSUME_CELL_SET(API_DEFAULT_HOST_URL, "/card/selfconsumecell/set"),
+
+    /**
+     * 获取用户已领取卡券接口
+     */
+    CARD_USER_CARD_LIST(API_DEFAULT_HOST_URL, "/card/user/getcardlist"),
     ;
 
     private String prefix;
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 948af00cd9..4fa75b7f98 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
@@ -227,4 +227,13 @@ public void testCreateQrcodeCard2() {
   @Test
   public void testCreateLandingPage() {
   }
+
+  @Test
+  public void testGetUserCardList() throws WxErrorException {
+    String openId = "ou7Gr5sJZgFGgj38sRCNQg5pc3Fc";
+    String cardId = "pu7Gr5secJXPkxBeuYUhmp8TYsuY";
+    WxUserCardListResult result = this.wxService.getCardService().getUserCardList(openId, cardId);
+    assertTrue(result.isSuccess());
+    System.out.println(result);
+  }
 }

From f60a7d911b4f25360c75c315569104243e169418 Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sun, 22 Dec 2019 16:12:07 +0800
Subject: [PATCH 0020/1706] =?UTF-8?q?=E8=A1=A5=E5=85=85=E9=83=A8=E5=88=86?=
 =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../mp/api/impl/WxMpMarketingServiceImplTest.java  | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMarketingServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMarketingServiceImplTest.java
index 900453b669..3d1b74e6c3 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMarketingServiceImplTest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpMarketingServiceImplTest.java
@@ -1,5 +1,12 @@
 package me.chanjar.weixin.mp.api.impl;
 
+import com.google.common.collect.Lists;
+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.bean.marketing.WxMpUserAction;
+import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
 import static org.testng.Assert.*;
@@ -10,7 +17,11 @@
  * @author Binary Wang
  * @date 2019-07-14
  */
+@Test
+@Guice(modules = ApiTestModule.class)
 public class WxMpMarketingServiceImplTest {
+  @Inject
+  protected WxMpService wxService;
 
   @Test
   public void testAddUserActionSets() {
@@ -21,7 +32,8 @@ public void testGetUserActionSets() {
   }
 
   @Test
-  public void testAddUserAction() {
+  public void testAddUserAction() throws WxErrorException {
+    this.wxService.getMarketingService().addUserAction(Lists.newArrayList(new WxMpUserAction()));
   }
 
   @Test

From 491134b4ac624d991d9bd4c3d3bc8cd7606d8364 Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sun, 22 Dec 2019 16:47:57 +0800
Subject: [PATCH 0021/1706] =?UTF-8?q?:art:=20#1307=20=E4=BC=98=E5=8C=96?=
 =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=BE=AE=E4=BF=A1=E5=B0=8F=E7=A8=8B=E5=BA=8F?=
 =?UTF-8?q?=E5=86=85=E5=AE=B9=E5=AE=89=E5=85=A8=E6=A0=A1=E9=AA=8C=E6=8E=A5?=
 =?UTF-8?q?=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../wx/miniapp/api/WxMaSecCheckService.java   |  8 ++++
 .../api/impl/WxMaSecCheckServiceImpl.java     | 22 ++++++++--
 .../bean/WxMaMediaAsyncCheckResult.java       |  8 +++-
 .../wx/miniapp/bean/WxMaMessage.java          | 41 +++++++++++++++----
 4 files changed, 68 insertions(+), 11 deletions(-)

diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSecCheckService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSecCheckService.java
index 4c821e0714..7733b77ed8 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSecCheckService.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSecCheckService.java
@@ -32,6 +32,14 @@ public interface WxMaSecCheckService {
    */
   boolean checkImage(File file) throws WxErrorException;
 
+  /**
+   * 校验一张图片是否含有违法违规内容
+   * @param fileUrl 文件网络地址
+   * @return 是否违规
+   * @throws WxErrorException .
+   */
+  boolean checkImage(String fileUrl) throws WxErrorException;
+
   /**
    * 
    * 检查一段文本是否含有违法违规内容。
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSecCheckServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSecCheckServiceImpl.java
index c69ca5eb11..1dd58bb698 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSecCheckServiceImpl.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSecCheckServiceImpl.java
@@ -4,11 +4,16 @@
 import cn.binarywang.wx.miniapp.api.WxMaService;
 import cn.binarywang.wx.miniapp.bean.WxMaMediaAsyncCheckResult;
 import com.google.gson.JsonObject;
-import java.io.File;
 import lombok.AllArgsConstructor;
 import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
+import me.chanjar.weixin.common.error.WxError;
 import me.chanjar.weixin.common.error.WxErrorException;
 import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
+import org.apache.commons.io.FileUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
 
 /**
  * 
@@ -20,17 +25,28 @@
  */
 @AllArgsConstructor
 public class WxMaSecCheckServiceImpl implements WxMaSecCheckService {
-
   private WxMaService service;
 
   @Override
   public boolean checkImage(File file) throws WxErrorException {
-    //这里只是借用MediaUploadRequestExecutor,并不使用其返回值WxMediaUploadResult
     WxMediaUploadResult result = this.service.execute(MediaUploadRequestExecutor
       .create(this.service.getRequestHttp()), IMG_SEC_CHECK_URL, file);
     return result != null;
   }
 
+  @Override
+  public boolean checkImage(String fileUrl) throws WxErrorException {
+    File file = new File(FileUtils.getTempDirectory(), System.currentTimeMillis() + ".tmp");
+    try {
+      URL url = new URL(fileUrl);
+      FileUtils.copyURLToFile(url, file);
+    } catch (IOException e) {
+      throw new WxErrorException(WxError.builder().errorCode(-1).errorMsg("文件地址读取异常").build(), e);
+    }
+    
+    return this.checkImage(file);
+  }
+
   @Override
   public boolean checkMessage(String msgString) throws WxErrorException {
     JsonObject jsonObject = new JsonObject();
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMediaAsyncCheckResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMediaAsyncCheckResult.java
index 807f807652..56bf0b8045 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMediaAsyncCheckResult.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMediaAsyncCheckResult.java
@@ -2,10 +2,16 @@
 
 import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
 import com.google.gson.annotations.SerializedName;
+import com.oracle.webservices.internal.api.databinding.DatabindingMode;
+import lombok.Data;
+
 import java.io.Serializable;
 
+/**
+ * @author borisbao
+ */
+@Data
 public class WxMaMediaAsyncCheckResult implements Serializable {
-
   private static final long serialVersionUID = 3928132365399916183L;
 
   /**
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java
index 1152820df2..483dd7c54a 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java
@@ -1,12 +1,5 @@
 package cn.binarywang.wx.miniapp.bean;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Serializable;
-import java.nio.charset.StandardCharsets;
-
-import org.apache.commons.io.IOUtils;
-
 import cn.binarywang.wx.miniapp.config.WxMaConfig;
 import cn.binarywang.wx.miniapp.util.crypt.WxMaCryptUtils;
 import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
@@ -16,6 +9,12 @@
 import com.thoughtworks.xstream.annotations.XStreamConverter;
 import lombok.Data;
 import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
+import org.apache.commons.io.IOUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.nio.charset.StandardCharsets;
 
 /**
  * @author Binary Wang
@@ -108,6 +107,34 @@ public class WxMaMessage implements Serializable {
   @XStreamConverter(value = XStreamCDataConverter.class)
   private String sessionFrom;
 
+  /**
+   * 以下是异步校验图片/音频是否含有违法违规内容的异步检测结果推送报文中的参数
+   */
+  @SerializedName("isrisky")
+  @XStreamAlias("isrisky")
+  @XStreamConverter(value = XStreamCDataConverter.class)
+  private String isRisky;
+
+  @SerializedName("extra_info_json")
+  @XStreamAlias("extra_info_json")
+  @XStreamConverter(value = XStreamCDataConverter.class)
+  private String extraInfoJson;
+
+  @SerializedName("appid")
+  @XStreamAlias("appid")
+  @XStreamConverter(value = XStreamCDataConverter.class)
+  private String appid;
+
+  @SerializedName("trace_id")
+  @XStreamAlias("trace_id")
+  @XStreamConverter(value = XStreamCDataConverter.class)
+  private String traceId;
+
+  @SerializedName("status_code")
+  @XStreamAlias("status_code")
+  @XStreamConverter(value = XStreamCDataConverter.class)
+  private String statusCode;
+
   public static WxMaMessage fromXml(String xml) {
     return XStreamTransformer.fromXml(WxMaMessage.class, xml);
   }

From 34ae0c5643ac46d7bde69831b0fc431eea524c98 Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sun, 22 Dec 2019 16:58:35 +0800
Subject: [PATCH 0022/1706] =?UTF-8?q?:art:=20#1307=20=E4=BC=98=E5=8C=96?=
 =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=BE=AE=E4=BF=A1=E5=B0=8F=E7=A8=8B=E5=BA=8F?=
 =?UTF-8?q?=E5=86=85=E5=AE=B9=E5=AE=89=E5=85=A8=E6=A0=A1=E9=AA=8C=E6=8E=A5?=
 =?UTF-8?q?=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../cn/binarywang/wx/miniapp/bean/WxMaMediaAsyncCheckResult.java | 1 -
 1 file changed, 1 deletion(-)

diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMediaAsyncCheckResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMediaAsyncCheckResult.java
index 56bf0b8045..e7fda61a02 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMediaAsyncCheckResult.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMediaAsyncCheckResult.java
@@ -2,7 +2,6 @@
 
 import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
 import com.google.gson.annotations.SerializedName;
-import com.oracle.webservices.internal.api.databinding.DatabindingMode;
 import lombok.Data;
 
 import java.io.Serializable;

From 7627c8d66653b5e5f94a94bbafa4ac0ddec2a318 Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sun, 22 Dec 2019 17:15:14 +0800
Subject: [PATCH 0023/1706] =?UTF-8?q?:bookmark:=20=E5=8F=91=E5=B8=833.6.3.?=
 =?UTF-8?q?B=E6=B5=8B=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 +-
 spring-boot-starters/pom.xml                                    | 2 +-
 .../wx-java-miniapp-spring-boot-starter/pom.xml                 | 2 +-
 spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml     | 2 +-
 spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml   | 2 +-
 spring-boot-starters/wx-java-pay-spring-boot-starter/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 +-
 12 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/pom.xml b/pom.xml
index 00f79a0a76..3a7835627b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
   4.0.0
   com.github.binarywang
   wx-java
-  3.6.2.B
+  3.6.3.B
   pom
   WxJava - Weixin/Wechat Java SDK
   微信开发Java SDK
diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml
index 87e91eaf8e..4794e18cbd 100644
--- a/spring-boot-starters/pom.xml
+++ b/spring-boot-starters/pom.xml
@@ -6,7 +6,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.2.B
+    3.6.3.B
   
   pom
   wx-java-spring-boot-starters
diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml
index 441e4dc148..a4a958dda0 100644
--- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
   
     wx-java-spring-boot-starters
     com.github.binarywang
-    3.6.2.B
+    3.6.3.B
   
   4.0.0
 
diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml
index b0cd46ade6..dddd3dcc77 100644
--- a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
   
     wx-java-spring-boot-starters
     com.github.binarywang
-    3.6.2.B
+    3.6.3.B
   
   4.0.0
 
diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml
index b5350977e7..f87b4653d4 100644
--- a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
   
     wx-java-spring-boot-starters
     com.github.binarywang
-    3.6.2.B
+    3.6.3.B
   
   4.0.0
 
diff --git a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml
index 2c8a2476a4..3d5fa4882d 100644
--- a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
   
     wx-java-spring-boot-starters
     com.github.binarywang
-    3.6.2.B
+    3.6.3.B
   
   4.0.0
 
diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml
index cfb9182801..e7b5b590aa 100644
--- a/weixin-java-common/pom.xml
+++ b/weixin-java-common/pom.xml
@@ -6,7 +6,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.2.B
+    3.6.3.B
   
 
   weixin-java-common
diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml
index ae32e5e2cd..0df56b7917 100644
--- a/weixin-java-cp/pom.xml
+++ b/weixin-java-cp/pom.xml
@@ -7,7 +7,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.2.B
+    3.6.3.B
   
 
   weixin-java-cp
diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml
index 2b08c716a2..d92c4122bf 100644
--- a/weixin-java-miniapp/pom.xml
+++ b/weixin-java-miniapp/pom.xml
@@ -7,7 +7,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.2.B
+    3.6.3.B
   
 
   weixin-java-miniapp
diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml
index b4166d5be1..1ba60ef812 100644
--- a/weixin-java-mp/pom.xml
+++ b/weixin-java-mp/pom.xml
@@ -7,7 +7,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.2.B
+    3.6.3.B
   
 
   weixin-java-mp
diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml
index 4002f15376..4acda5b122 100644
--- a/weixin-java-open/pom.xml
+++ b/weixin-java-open/pom.xml
@@ -7,7 +7,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.2.B
+    3.6.3.B
   
 
   weixin-java-open
diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml
index 81daf5f212..da16bc88ac 100644
--- a/weixin-java-pay/pom.xml
+++ b/weixin-java-pay/pom.xml
@@ -5,7 +5,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.2.B
+    3.6.3.B
   
   4.0.0
 

From 45f3e54526e524f8ade88b944866b2931a2efaa6 Mon Sep 17 00:00:00 2001
From: yang229 
Date: Tue, 24 Dec 2019 16:13:20 +0800
Subject: [PATCH 0024/1706] =?UTF-8?q?:bug:=20#1332=20=E5=BE=AE=E4=BF=A1?=
 =?UTF-8?q?=E5=8D=A1=E5=88=B8=E4=BF=AE=E5=A4=8D=E7=AD=BE=E5=90=8D=E7=94=9F?=
 =?UTF-8?q?=E6=88=90=E9=94=99=E8=AF=AF=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

微信卡券签名生成错误
https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html#65
签名说明#1
参数字符串的应先按照字典序排序,再进行sha1加密
---
 .../java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java  | 1 +
 1 file changed, 1 insertion(+)

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 740c96e959..1bf61ffe39 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
@@ -81,6 +81,7 @@ public WxCardApiSignature createCardApiSignature(String... optionalSignParam) th
     signParams[optionalSignParam.length + 1] = nonceStr;
     signParams[optionalSignParam.length + 2] = cardApiTicket;
     StringBuilder sb = new StringBuilder();
+    Arrays.sort(signParams);
     for (String a : signParams) {
       sb.append(a);
     }

From 1d50acace74527b3e825715e9cfc045f76c0fc75 Mon Sep 17 00:00:00 2001
From: ArBing 
Date: Tue, 24 Dec 2019 17:37:01 +0800
Subject: [PATCH 0025/1706] =?UTF-8?q?:bug:=20#1331=20=E4=BF=AE=E5=A4=8D?=
 =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E8=8E=B7=E5=8F=96=E8=AE=A2=E9=98=85?=
 =?UTF-8?q?=E6=B6=88=E6=81=AF=E5=85=AC=E5=85=B1=E6=A8=A1=E6=9D=BF=E6=A0=87?=
 =?UTF-8?q?=E9=A2=98Result=E4=B8=8D=E5=8C=B9=E9=85=8D=E7=9A=84=E9=97=AE?=
 =?UTF-8?q?=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../wx/miniapp/api/WxMaSubscribeService.java  |  4 +--
 .../api/impl/WxMaSubscribeServiceImpl.java    |  6 ++--
 .../WxMaPubTemplateTitleListResult.java       | 32 +++++++++++++++++++
 .../impl/WxMaSubscribeServiceImplTest.java    |  5 ++-
 4 files changed, 41 insertions(+), 6 deletions(-)
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/template/WxMaPubTemplateTitleListResult.java

diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java
index 60c0d8a2c1..19e22a5eb6 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaSubscribeService.java
@@ -1,6 +1,6 @@
 package cn.binarywang.wx.miniapp.api;
 
-import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryListResult;
+import cn.binarywang.wx.miniapp.bean.template.WxMaPubTemplateTitleListResult;
 import lombok.Data;
 import me.chanjar.weixin.common.error.WxErrorException;
 
@@ -57,7 +57,7 @@ public interface WxMaSubscribeService {
    * @return .
    * @throws WxErrorException .
    */
-  WxMaTemplateLibraryListResult getPubTemplateTitleList(String[] ids, int start, int limit) throws WxErrorException;
+  WxMaPubTemplateTitleListResult getPubTemplateTitleList(String[] ids, int start, int limit) throws WxErrorException;
 
   /**
    * 
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImpl.java
index 8da372c164..ffd54b3b10 100644
--- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImpl.java
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImpl.java
@@ -2,7 +2,7 @@
 
 import cn.binarywang.wx.miniapp.api.WxMaService;
 import cn.binarywang.wx.miniapp.api.WxMaSubscribeService;
-import cn.binarywang.wx.miniapp.bean.template.WxMaTemplateLibraryListResult;
+import cn.binarywang.wx.miniapp.bean.template.WxMaPubTemplateTitleListResult;
 import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
 import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableMap;
@@ -24,12 +24,12 @@ public class WxMaSubscribeServiceImpl implements WxMaSubscribeService {
   private WxMaService wxMaService;
 
   @Override
-  public WxMaTemplateLibraryListResult getPubTemplateTitleList(String[] ids, int start, int limit) throws WxErrorException {
+  public WxMaPubTemplateTitleListResult getPubTemplateTitleList(String[] ids, int start, int limit) throws WxErrorException {
     ImmutableMap params = ImmutableMap.of("ids", StringUtils.join(ids, ","),
       "start", start, "limit", limit);
     String responseText = this.wxMaService.get(GET_PUB_TEMPLATE_TITLE_LIST_URL,
       Joiner.on("&").withKeyValueSeparator("=").join(params));
-    return WxMaTemplateLibraryListResult.fromJson(responseText);
+    return WxMaPubTemplateTitleListResult.fromJson(responseText);
   }
 
   @Override
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/template/WxMaPubTemplateTitleListResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/template/WxMaPubTemplateTitleListResult.java
new file mode 100644
index 0000000000..a249619f9a
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/template/WxMaPubTemplateTitleListResult.java
@@ -0,0 +1,32 @@
+package cn.binarywang.wx.miniapp.bean.template;
+
+import lombok.Data;
+import me.chanjar.weixin.common.util.json.WxGsonBuilder;
+
+import java.io.Serializable;
+import java.util.List;
+
+@Data
+public class WxMaPubTemplateTitleListResult implements Serializable {
+  private static final long serialVersionUID = -7718911668757837527L;
+
+  private int count;
+
+  private List data;
+
+  public static WxMaPubTemplateTitleListResult fromJson(String json) {
+    return WxGsonBuilder.create().fromJson(json, WxMaPubTemplateTitleListResult.class);
+  }
+
+  @Data
+  public static class TemplateItem {
+
+    private Integer type;
+
+    private Integer tid;
+
+    private String categoryId;
+
+    private String title;
+  }
+}
diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImplTest.java
index ef17d8306e..e40cf10e71 100644
--- a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImplTest.java
+++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaSubscribeServiceImplTest.java
@@ -2,6 +2,7 @@
 
 import cn.binarywang.wx.miniapp.api.WxMaService;
 import cn.binarywang.wx.miniapp.api.WxMaSubscribeService;
+import cn.binarywang.wx.miniapp.bean.template.WxMaPubTemplateTitleListResult;
 import cn.binarywang.wx.miniapp.test.ApiTestModule;
 import com.google.common.collect.Lists;
 import com.google.inject.Inject;
@@ -27,7 +28,9 @@ public class WxMaSubscribeServiceImplTest {
 
   @Test
   public void testGetPubTemplateTitleList() throws WxErrorException {
-    this.wxService.getSubscribeService().getPubTemplateTitleList(new String[]{"2", "616"}, 0, 1);
+    WxMaPubTemplateTitleListResult result = this.wxService.getSubscribeService().getPubTemplateTitleList(new String[]{"2", "616"}, 0, 30);
+    System.out.println(result);
+
   }
 
   @Test

From 3e3d4e8345839b08e296e290d7c2e486f5cabd01 Mon Sep 17 00:00:00 2001
From: bongQ417 
Date: Wed, 25 Dec 2019 15:00:32 +0800
Subject: [PATCH 0026/1706] =?UTF-8?q?:bug:=20=20#1330=20=E4=BF=AE=E5=A4=8D?=
 =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98=E5=9B=9E=E8=B0=83=E9=80=9A?=
 =?UTF-8?q?=E7=9F=A5sign=5Ftype=E7=BC=BA=E5=A4=B1=E5=AF=BC=E8=87=B4?=
 =?UTF-8?q?=E9=AA=8C=E7=AD=BE=E5=A4=B1=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../wxpay/bean/notify/WxPayOrderNotifyResult.java    | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResult.java
index d0242788a1..93fb4b2705 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResult.java
@@ -300,6 +300,18 @@ public class WxPayOrderNotifyResult extends BaseWxPayResult {
   @XStreamAlias("rate_value")
   private String rateValue;
 
+  /**
+   * 
+   * 字段名:签名类型.
+   * 变量名:sign_type
+   * 类型:String(32)
+   * 示例值:HMAC-SHA256
+   * 签名类型,目前支持HMAC-SHA256和MD5,默认为MD5
+   * 
+ */ + @XStreamAlias("sign_type") + private String signType; + @Override public void checkResult(WxPayService wxPayService, String signType, boolean checkSuccess) throws WxPayException { //防止伪造成功通知 From fa1f085e1dad5be533f0d999b190bd9bf2953ced Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 26 Dec 2019 14:15:28 +0800 Subject: [PATCH 0027/1706] =?UTF-8?q?:bug:=20#1338=20=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E4=BF=AE=E5=A4=8D=E5=8F=91=E9=80=81=E5=B0=8F?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E7=BA=A2=E5=8C=85=E6=8E=A5=E5=8F=A3=E7=9A=84?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WxPaySendMiniProgramRedpackRequest.java | 20 ++++ .../wxpay/service/RedpackService.java | 76 +++++++++++++ .../wxpay/service/WxPayService.java | 58 +++------- .../service/impl/BaseWxPayServiceImpl.java | 53 +++------ .../service/impl/RedpackServiceImpl.java | 72 ++++++++++++ .../impl/BaseWxPayServiceImplTest.java | 105 ++++++------------ .../service/impl/RedpackServiceImplTest.java | 63 +++++++++++ 7 files changed, 296 insertions(+), 151 deletions(-) create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/RedpackService.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/RedpackServiceImpl.java create mode 100644 weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/RedpackServiceImplTest.java diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendMiniProgramRedpackRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendMiniProgramRedpackRequest.java index 4215399d4a..62cfe490a7 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendMiniProgramRedpackRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendMiniProgramRedpackRequest.java @@ -105,8 +105,28 @@ protected String[] getIgnoredParamsForSign() { @XStreamAlias("scene_id") private String sceneId; + /** + * wxappid. + * 微信分配的公众账号ID(企业号corpid即为此appId)。 + * 接口传入的所有appid应该为公众号的appid(在mp.weixin.qq.com申请的), + * 不能为APP的appid(在open.weixin.qq.com申请的) + */ + @XStreamAlias("wxappid") + private String wxAppid; + @Override protected void checkConstraints() { } + + @Override + public String getAppid() { + return this.wxAppid; + } + + @Override + public void setAppid(String appid) { + this.wxAppid = appid; + } + } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/RedpackService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/RedpackService.java new file mode 100644 index 0000000000..131205d07a --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/RedpackService.java @@ -0,0 +1,76 @@ +package com.github.binarywang.wxpay.service; + +import com.github.binarywang.wxpay.bean.request.WxPayRedpackQueryRequest; +import com.github.binarywang.wxpay.bean.request.WxPaySendMiniProgramRedpackRequest; +import com.github.binarywang.wxpay.bean.request.WxPaySendRedpackRequest; +import com.github.binarywang.wxpay.bean.result.WxPayRedpackQueryResult; +import com.github.binarywang.wxpay.bean.result.WxPaySendMiniProgramRedpackResult; +import com.github.binarywang.wxpay.bean.result.WxPaySendRedpackResult; +import com.github.binarywang.wxpay.exception.WxPayException; + +/** + * 红包相关接口. + * + * @author Binary Wang + * @date 2019-12-26 + */ +public interface RedpackService { + /** + *
+   * 发送小程序红包.
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/api/tools/miniprogram_hb.php?chapter=13_9&index=2
+   *  接口地址:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendminiprogramhb
+   * 
+ * + * @param request 请求对象 + * @return the result + * @throws WxPayException the exception + */ + WxPaySendMiniProgramRedpackResult sendMiniProgramRedpack(WxPaySendMiniProgramRedpackRequest request) throws WxPayException; + + /** + * 发送微信红包给个人用户. + *
+   * 文档详见:
+   * 发送普通红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3
+   *  接口地址:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack
+   * 发送裂变红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_5&index=4
+   *  接口地址:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendgroupredpack
+   * 
+ * + * @param request 请求对象 + * @return the wx pay send redpack result + * @throws WxPayException the wx pay exception + */ + WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) 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(String mchBillNo) throws WxPayException; + + /** + *
+   *   查询红包记录.
+   *   用于商户对已发放的红包进行查询红包的具体信息,可支持普通红包和裂变包。
+   *   请求Url:https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo
+   *   是否需要证书:是(证书及使用说明详见商户证书)
+   *   请求方式:POST
+   * 
+ * + * @param request 红包查询请求 + * @return the wx pay redpack query result + * @throws WxPayException the wx pay exception + */ + WxPayRedpackQueryResult queryRedpack(WxPayRedpackQueryRequest 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 0534058138..3d95148d0f 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 @@ -60,6 +60,13 @@ public interface WxPayService { */ EntPayService getEntPayService(); + /** + * 获取红包接口服务类. + * + * @return . + */ + RedpackService getRedpackService(); + /** * 获取分账服务类. * @@ -277,62 +284,27 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri WxScanPayNotifyResult parseScanPayNotifyResult(String xmlData) throws WxPayException; /** - *
-   * 发送小程序红包.
-   * 文档详见: https://pay.weixin.qq.com/wiki/doc/api/tools/miniprogram_hb.php?chapter=13_9&index=2
-   *  接口地址:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendminiprogramhb
-   * 
- * - * @param request 请求对象 - * @return the result - * @throws WxPayException the exception + * @deprecated 建议使用 {@link RedpackService#sendMiniProgramRedpack(WxPaySendMiniProgramRedpackRequest)} */ + @Deprecated WxPaySendMiniProgramRedpackResult sendMiniProgramRedpack(WxPaySendMiniProgramRedpackRequest request) throws WxPayException; /** - * 发送微信红包给个人用户. - *
-   * 文档详见:
-   * 发送普通红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3
-   *  接口地址:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack
-   * 发送裂变红包 https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_5&index=4
-   *  接口地址:https://api.mch.weixin.qq.com/mmpaymkttransfers/sendgroupredpack
-   * 
- * - * @param request 请求对象 - * @return the wx pay send redpack result - * @throws WxPayException the wx pay exception + * @deprecated 建议使用 {@link RedpackService#sendRedpack(WxPaySendRedpackRequest)} */ + @Deprecated WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) 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 + * @deprecated 建议使用 {@link RedpackService#queryRedpack(String)} */ + @Deprecated WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxPayException; /** - *
-   *   查询红包记录.
-   *   用于商户对已发放的红包进行查询红包的具体信息,可支持普通红包和裂变包。
-   *   请求Url:https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo
-   *   是否需要证书:是(证书及使用说明详见商户证书)
-   *   请求方式:POST
-   * 
- * - * @param request 红包查询请求 - * @return the wx pay redpack query result - * @throws WxPayException the wx pay exception + * @deprecated 建议使用 {@link RedpackService#queryRedpack(WxPayRedpackQueryRequest)} */ + @Deprecated WxPayRedpackQueryResult queryRedpack(WxPayRedpackQueryRequest 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 093997e06b..9f363eaf25 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 @@ -13,12 +13,12 @@ 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; import com.github.binarywang.wxpay.constant.WxPayConstants.TradeType; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.EntPayService; import com.github.binarywang.wxpay.service.ProfitSharingService; +import com.github.binarywang.wxpay.service.RedpackService; import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.util.SignUtils; import com.google.common.base.Joiner; @@ -61,6 +61,8 @@ public abstract class BaseWxPayServiceImpl implements WxPayService { private EntPayService entPayService = new EntPayServiceImpl(this); private ProfitSharingService profitSharingService = new ProfitSharingServiceImpl(this); + private RedpackService redpackService = new RedpackServiceImpl(this); + /** * The Config. */ @@ -76,6 +78,11 @@ public ProfitSharingService getProfitSharingService() { return profitSharingService; } + @Override + public RedpackService getRedpackService() { + return this.redpackService; + } + @Override public void setEntPayService(EntPayService entPayService) { this.entPayService = entPayService; @@ -182,51 +189,25 @@ public WxScanPayNotifyResult parseScanPayNotifyResult(String xmlData) throws WxP } - @Override - public WxPaySendMiniProgramRedpackResult sendMiniProgramRedpack(WxPaySendMiniProgramRedpackRequest request) - throws WxPayException { - request.checkAndSign(this.getConfig()); - String url = this.getPayBaseUrl() + "/mmpaymkttransfers/sendminiprogramhb"; - String responseContent = this.post(url, request.toXML(), true); - - WxPaySendMiniProgramRedpackResult result = BaseWxPayResult.fromXML(responseContent, WxPaySendMiniProgramRedpackResult.class); - result.checkResult(this, request.getSignType(), true); - return result; - } + @Override + public WxPaySendMiniProgramRedpackResult sendMiniProgramRedpack(WxPaySendMiniProgramRedpackRequest request) + throws WxPayException { + return this.redpackService.sendMiniProgramRedpack(request); + } - @Override + @Override public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) throws WxPayException { - request.checkAndSign(this.getConfig()); - - String url = this.getPayBaseUrl() + "/mmpaymkttransfers/sendredpack"; - if (request.getAmtType() != null) { - //裂变红包 - url = this.getPayBaseUrl() + "/mmpaymkttransfers/sendgroupredpack"; - } - - String responseContent = this.post(url, request.toXML(), true); - final WxPaySendRedpackResult result = BaseWxPayResult.fromXML(responseContent, WxPaySendRedpackResult.class); - result.checkResult(this, request.getSignType(), true); - return result; + return this.redpackService.sendRedpack(request); } @Override public WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxPayException { - WxPayRedpackQueryRequest request = new WxPayRedpackQueryRequest(); - request.setMchBillNo(mchBillNo); - return this.queryRedpack(request); + return this.redpackService.queryRedpack(mchBillNo); } @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; + return this.redpackService.queryRedpack(request); } @Override diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/RedpackServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/RedpackServiceImpl.java new file mode 100644 index 0000000000..03ce8333e2 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/RedpackServiceImpl.java @@ -0,0 +1,72 @@ +package com.github.binarywang.wxpay.service.impl; + +import com.github.binarywang.wxpay.bean.request.WxPayRedpackQueryRequest; +import com.github.binarywang.wxpay.bean.request.WxPaySendMiniProgramRedpackRequest; +import com.github.binarywang.wxpay.bean.request.WxPaySendRedpackRequest; +import com.github.binarywang.wxpay.bean.result.BaseWxPayResult; +import com.github.binarywang.wxpay.bean.result.WxPayRedpackQueryResult; +import com.github.binarywang.wxpay.bean.result.WxPaySendMiniProgramRedpackResult; +import com.github.binarywang.wxpay.bean.result.WxPaySendRedpackResult; +import com.github.binarywang.wxpay.constant.WxPayConstants; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.RedpackService; +import com.github.binarywang.wxpay.service.WxPayService; +import lombok.RequiredArgsConstructor; + +/** + * 老板加点注释吧. + * + * @author Binary Wang + * @date 2019-12-26 + */ +@RequiredArgsConstructor +public class RedpackServiceImpl implements RedpackService { + private final WxPayService payService; + + @Override + public WxPaySendMiniProgramRedpackResult sendMiniProgramRedpack(WxPaySendMiniProgramRedpackRequest request) + throws WxPayException { + request.checkAndSign(this.payService.getConfig()); + String url = this.payService.getPayBaseUrl() + "/mmpaymkttransfers/sendminiprogramhb"; + String responseContent = this.payService.post(url, request.toXML(), true); + + WxPaySendMiniProgramRedpackResult result = BaseWxPayResult.fromXML(responseContent, WxPaySendMiniProgramRedpackResult.class); + result.checkResult(this.payService, request.getSignType(), true); + return result; + } + + @Override + public WxPaySendRedpackResult sendRedpack(WxPaySendRedpackRequest request) throws WxPayException { + request.checkAndSign(this.payService.getConfig()); + + String url = this.payService.getPayBaseUrl() + "/mmpaymkttransfers/sendredpack"; + if (request.getAmtType() != null) { + //裂变红包 + url = this.payService.getPayBaseUrl() + "/mmpaymkttransfers/sendgroupredpack"; + } + + String responseContent = this.payService.post(url, request.toXML(), true); + final WxPaySendRedpackResult result = BaseWxPayResult.fromXML(responseContent, WxPaySendRedpackResult.class); + result.checkResult(this.payService, request.getSignType(), true); + return result; + } + + @Override + public WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxPayException { + WxPayRedpackQueryRequest request = new WxPayRedpackQueryRequest(); + request.setMchBillNo(mchBillNo); + return this.queryRedpack(request); + } + + @Override + public WxPayRedpackQueryResult queryRedpack(WxPayRedpackQueryRequest request) throws WxPayException { + request.setBillType(WxPayConstants.BillType.MCHT); + request.checkAndSign(this.payService.getConfig()); + + String url = this.payService.getPayBaseUrl() + "/mmpaymkttransfers/gethbinfo"; + String responseContent = this.payService.post(url, request.toXML(), true); + WxPayRedpackQueryResult result = BaseWxPayResult.fromXML(responseContent, WxPayRedpackQueryResult.class); + result.checkResult(this.payService, request.getSignType(), true); + return result; + } +} diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java index 551b00ee52..d6e688cf50 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java @@ -18,6 +18,7 @@ import com.github.binarywang.wxpay.testbase.ApiTestModule; import com.github.binarywang.wxpay.testbase.XmlWxPayConfig; import com.google.inject.Inject; +import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.annotations.DataProvider; @@ -39,10 +40,10 @@ * * @author Binary Wang */ +@Slf4j @Test @Guice(modules = ApiTestModule.class) public class BaseWxPayServiceImplTest { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Inject private WxPayService payService; @@ -65,8 +66,8 @@ public void testUnifiedOrder() throws WxPayException { .build(); request.setSignType(SignType.HMAC_SHA256); WxPayUnifiedOrderResult result = this.payService.unifiedOrder(request); - this.logger.info(result.toString()); - this.logger.warn(this.payService.getWxApiData().toString()); + log.info(result.toString()); + log.warn(this.payService.getWxApiData().toString()); } /** @@ -96,8 +97,8 @@ public void testCreateOrder_jsapi() throws Exception { .openid(((XmlWxPayConfig) this.payService.getConfig()).getOpenid()) .outTradeNo("1111112") .build()); - this.logger.info(result.toString()); - this.logger.warn(this.payService.getWxApiData().toString()); + log.info(result.toString()); + log.warn(this.payService.getWxApiData().toString()); } /** @@ -116,8 +117,8 @@ public void testCreateOrder_app() throws Exception { .tradeType(TradeType.APP) .outTradeNo("1111112") .build()); - this.logger.info(result.toString()); - this.logger.warn(this.payService.getWxApiData().toString()); + log.info(result.toString()); + log.warn(this.payService.getWxApiData().toString()); } /** @@ -137,8 +138,8 @@ public void testCreateOrder_native() throws Exception { .tradeType(TradeType.NATIVE) .outTradeNo("111111290") .build()); - this.logger.info(result.toString()); - this.logger.warn(this.payService.getWxApiData().toString()); + log.info(result.toString()); + log.warn(this.payService.getWxApiData().toString()); } /** @@ -158,8 +159,8 @@ public void testGetPayInfo() throws Exception { */ @Test public void testQueryOrder() throws WxPayException { - this.logger.info(this.payService.queryOrder("11212121", null).toString()); - this.logger.info(this.payService.queryOrder(null, "11111").toString()); + log.info(this.payService.queryOrder("11212121", null).toString()); + log.info(this.payService.queryOrder(null, "11111").toString()); } /** @@ -169,7 +170,7 @@ public void testQueryOrder() throws WxPayException { */ @Test public void testCloseOrder() throws WxPayException { - this.logger.info(this.payService.closeOrder("11212121").toString()); + log.info(this.payService.closeOrder("11212121").toString()); } /** @@ -205,7 +206,7 @@ public void testDownloadBill(String billDate, String billType, String tarType, String deviceInfo) throws Exception { WxPayBillResult billResult = this.payService.downloadBill(billDate, billType, tarType, deviceInfo); assertThat(billResult).isNotNull(); - this.logger.info(billResult.toString()); + log.info(billResult.toString()); } /** @@ -248,7 +249,7 @@ public Object[][] fundFlowData() { public void testDownloadFundFlow(String billDate, String accountType, String tarType) throws Exception { WxPayFundFlowResult fundFlowResult = this.payService.downloadFundFlow(billDate, accountType, tarType); assertThat(fundFlowResult).isNotNull(); - this.logger.info(fundFlowResult.toString()); + log.info(fundFlowResult.toString()); } /** @@ -293,7 +294,7 @@ public void testRefund() throws Exception { .totalFee(1222) .refundFee(111) .build()); - this.logger.info(result.toString()); + log.info(result.toString()); } /** @@ -306,20 +307,20 @@ public void testRefundQuery() throws Exception { WxPayRefundQueryResult result; result = this.payService.refundQuery("1", "", "", ""); - this.logger.info(result.toString()); + log.info(result.toString()); result = this.payService.refundQuery("", "2", "", ""); - this.logger.info(result.toString()); + log.info(result.toString()); result = this.payService.refundQuery("", "", "3", ""); - this.logger.info(result.toString()); + log.info(result.toString()); result = this.payService.refundQuery("", "", "", "4"); - this.logger.info(result.toString()); + log.info(result.toString()); //测试四个参数都填的情况,应该报异常的 result = this.payService.refundQuery("1", "2", "3", "4"); - this.logger.info(result.toString()); + log.info(result.toString()); } /** @@ -332,37 +333,6 @@ public void testParseRefundNotifyResult() throws Exception { // 请参考com.github.binarywang.wxpay.bean.notify.WxPayRefundNotifyResultTest里的单元测试 } - /** - * Test method for {@link WxPayService#sendRedpack(WxPaySendRedpackRequest)} . - * - * @throws Exception the exception - */ - @Test - public void testSendRedpack() throws Exception { - WxPaySendRedpackRequest request = new WxPaySendRedpackRequest(); - request.setActName("abc"); - request.setClientIp("aaa"); - request.setMchBillNo("aaaa"); - request.setWishing("what"); - request.setSendName("111"); - request.setTotalAmount(1); - request.setTotalNum(1); - request.setReOpenid(((XmlWxPayConfig) this.payService.getConfig()).getOpenid()); - WxPaySendRedpackResult redpackResult = this.payService.sendRedpack(request); - this.logger.info(redpackResult.toString()); - } - - /** - * Test method for {@link WxPayService#queryRedpack(String)}. - * - * @throws Exception the exception - */ - @Test - public void testQueryRedpack() throws Exception { - WxPayRedpackQueryResult redpackResult = this.payService.queryRedpack("aaaa"); - this.logger.info(redpackResult.toString()); - } - /** * Test create scan pay qrcode mode 1. * @@ -375,7 +345,7 @@ public void testCreateScanPayQrcodeMode1() throws Exception { Path qrcodeFilePath = Files.createTempFile("qrcode_", ".jpg"); Files.write(qrcodeFilePath, bytes); String qrcodeContent = QrcodeUtils.decodeQrcode(qrcodeFilePath.toFile()); - this.logger.info(qrcodeContent); + log.info(qrcodeContent); assertTrue(qrcodeContent.startsWith("weixin://wxpay/bizpayurl?")); assertTrue(qrcodeContent.contains("product_id=" + productId)); @@ -411,7 +381,7 @@ public void testMicropay() throws Exception { .spbillCreateIp("127.0.0.1") .authCode("aaa") .build()); - this.logger.info(result.toString()); + log.info(result.toString()); } /** @@ -446,7 +416,7 @@ public void testReverseOrder() throws Exception { .outTradeNo("1111") .build()); assertNotNull(result); - this.logger.info(result.toString()); + log.info(result.toString()); } /** @@ -460,11 +430,11 @@ public void testShorturl() throws Exception { String result = this.payService.shorturl(new WxPayShorturlRequest(longUrl)); assertNotNull(result); - this.logger.info(result); + log.info(result); result = this.payService.shorturl(longUrl); assertNotNull(result); - this.logger.info(result); + log.info(result); } /** @@ -478,11 +448,11 @@ public void testAuthcode2Openid() throws Exception { String result = this.payService.authcode2Openid(new WxPayAuthcode2OpenidRequest(authCode)); assertNotNull(result); - this.logger.info(result); + log.info(result); result = this.payService.authcode2Openid(authCode); assertNotNull(result); - this.logger.info(result); + log.info(result); } /** @@ -494,7 +464,7 @@ public void testAuthcode2Openid() throws Exception { public void testGetSandboxSignKey() throws Exception { final String signKey = this.payService.getSandboxSignKey(); assertNotNull(signKey); - this.logger.info(signKey); + log.info(signKey); } /** @@ -510,7 +480,7 @@ public void testSendCoupon() throws Exception { .partnerTradeNo("1212") .openidCount(1) .build()); - this.logger.info(result.toString()); + log.info(result.toString()); } /** @@ -524,7 +494,7 @@ public void testQueryCouponStock() throws Exception { WxPayCouponStockQueryRequest.newBuilder() .couponStockId("123") .build()); - this.logger.info(result.toString()); + log.info(result.toString()); } /** @@ -540,7 +510,7 @@ public void testQueryCouponInfo() throws Exception { .couponId("11") .stockId("1121") .build()); - this.logger.info(result.toString()); + log.info(result.toString()); } /** @@ -556,7 +526,7 @@ public void testQueryComment() throws Exception { calendar.add(Calendar.DAY_OF_MONTH, -88); Date beginDate = calendar.getTime(); String result = this.payService.queryComment(beginDate, endDate, 0, 1); - this.logger.info(result); + log.info(result); } /** @@ -610,15 +580,6 @@ public void testGetWxApiData() throws Exception { //see test in testUnifiedOrder() } - @Test - public void testSendMiniProgramRedpack() throws WxPayException { - final WxPaySendMiniProgramRedpackResult result = this.payService - .sendMiniProgramRedpack(new WxPaySendMiniProgramRedpackRequest() - .setReOpenid("ojOQA0y9o-Eb6Aep7uVTdbkJqrP4") - .setTotalAmount(1)); - System.out.println(result); - } - @Test public void testDownloadRawBill() { } diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/RedpackServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/RedpackServiceImplTest.java new file mode 100644 index 0000000000..161135b51f --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/RedpackServiceImplTest.java @@ -0,0 +1,63 @@ +package com.github.binarywang.wxpay.service.impl; + +import com.github.binarywang.wxpay.bean.request.WxPaySendMiniProgramRedpackRequest; +import com.github.binarywang.wxpay.bean.request.WxPaySendRedpackRequest; +import com.github.binarywang.wxpay.bean.result.WxPayRedpackQueryResult; +import com.github.binarywang.wxpay.bean.result.WxPaySendMiniProgramRedpackResult; +import com.github.binarywang.wxpay.bean.result.WxPaySendRedpackResult; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.testbase.ApiTestModule; +import com.github.binarywang.wxpay.testbase.XmlWxPayConfig; +import com.google.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +/** + * 测试类. + * + * @author Binary Wang + * @date 2019-12-26 + */ +@Slf4j +@Test +@Guice(modules = ApiTestModule.class) +public class RedpackServiceImplTest { + @Inject + private WxPayService payService; + + @Test + public void testSendRedpack() throws Exception { + WxPaySendRedpackRequest request = new WxPaySendRedpackRequest(); + request.setActName("abc"); + request.setClientIp("aaa"); + request.setMchBillNo("aaaa"); + request.setWishing("what"); + request.setSendName("111"); + request.setTotalAmount(1); + request.setTotalNum(1); + request.setReOpenid(((XmlWxPayConfig) this.payService.getConfig()).getOpenid()); + WxPaySendRedpackResult redpackResult = this.payService.getRedpackService().sendRedpack(request); + log.info(redpackResult.toString()); + } + + @Test + public void testQueryRedpack() throws Exception { + WxPayRedpackQueryResult redpackResult = this.payService.getRedpackService().queryRedpack("aaaa"); + log.info(redpackResult.toString()); + } + + @Test + public void testSendMiniProgramRedpack() throws WxPayException { + final WxPaySendMiniProgramRedpackResult result = this.payService.getRedpackService() + .sendMiniProgramRedpack(new WxPaySendMiniProgramRedpackRequest() + .setReOpenid("ojOQA0y9o-Eb6Aep7uVTdbkJqrP4") + .setWishing("haha") + .setMchBillNo("123") + .setActName("11") + .setSendName("111") + .setTotalAmount(1)); + System.out.println(result); + } +} From 79f85176cb96c460c0da4e04820ee265b4add08c Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 26 Dec 2019 17:29:10 +0800 Subject: [PATCH 0028/1706] =?UTF-8?q?:bug:=20#1275=20=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E4=BC=98=E5=8C=96=E5=AF=B9=E8=B4=A6=E5=8D=95?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=E8=A7=A3=E6=9E=90=E6=8E=A5=E5=8F=A3=EF=BC=8C?= =?UTF-8?q?=E5=85=BC=E5=AE=B9=E6=99=AE=E9=80=9A=E7=BB=93=E7=AE=97=E5=AF=B9?= =?UTF-8?q?=E8=B4=A6=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wxpay/bean/result/WxPayBillResult.java | 26 ++++--- .../bean/result/WxPayBillResultTest.java | 68 ++++++++++++------- 2 files changed, 61 insertions(+), 33 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBillResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBillResult.java index 15416b1f2a..84a382db3c 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBillResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayBillResult.java @@ -66,16 +66,16 @@ public String toString() { */ public static WxPayBillResult fromRawBillResultString(String responseContent, String billType) { switch (billType) { - case "ALL":{ + case "ALL": { return fromRawBillResultString(responseContent); } - case "SUCCESS":{ + case "SUCCESS": { return fromRawBillResultStringToSuccess(responseContent); } - case "REFUND" :{ + case "REFUND": { return fromRawBillResultStringToRefund(responseContent); } - case "RECHARGE_REFUND" :{ + case "RECHARGE_REFUND": { return fromRawBillResultStringToRechargeRefund(responseContent); } default: { @@ -106,7 +106,9 @@ private static WxPayBillResult fromRawBillResultString(String responseContent) { int j = tempStr.length / t.length; // 纪录数组下标 int k = 1; - // 交易时间,公众账号ID,商户号,特约商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,应结订单金额,代金券金额,微信退款单号,商户退款单号,退款金额,充值券退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率,订单金额,申请退款金额,费率备注 + // 交易时间,公众账号ID,商户号,特约商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类, + // 应结订单金额,代金券金额,微信退款单号,商户退款单号,退款金额,充值券退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率, + // 订单金额,申请退款金额,费率备注 (开通免充值券后的结算对账单专有的三个字段) for (int i = 0; i < j; i++) { WxPayBillInfo result = new WxPayBillInfo(); result.setTradeTime(tempStr[k].trim()); @@ -133,9 +135,14 @@ private static WxPayBillResult fromRawBillResultString(String responseContent) { result.setAttach(tempStr[k + 21].trim()); result.setPoundage(tempStr[k + 22].trim()); result.setPoundageRate(tempStr[k + 23].trim()); - result.setTotalAmount(tempStr[k + 24].trim()); - result.setAppliedRefundAmount(tempStr[k + 25].trim()); - result.setFeeRemark(tempStr[k + 26].trim()); + + if (t.length > 24) { + // 开通免充值券后的结算对账单 + result.setTotalAmount(tempStr[k + 24].trim()); + result.setAppliedRefundAmount(tempStr[k + 25].trim()); + result.setFeeRemark(tempStr[k + 26].trim()); + } + results.add(result); k += t.length; } @@ -181,7 +188,8 @@ private static WxPayBillResult fromRawBillResultStringToSuccess(String responseC int j = tempStr.length / t.length; // 纪录数组下标 int k = 1; - // 交易时间,公众账号ID,商户号,特约商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,应结订单金额,代金券金额,商品名称,商户数据包,手续费,费率,订单金额,费率备注 + // 交易时间,公众账号ID,商户号,特约商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类, + // 应结订单金额,代金券金额,商品名称,商户数据包,手续费,费率,订单金额,费率备注 for (int i = 0; i < j; i++) { WxPayBillInfo result = new WxPayBillInfo(); result.setTradeTime(tempStr[k].trim()); diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayBillResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayBillResultTest.java index 76bbf05742..6d5d322602 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayBillResultTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayBillResultTest.java @@ -1,27 +1,35 @@ package com.github.binarywang.wxpay.bean.result; import com.github.binarywang.wxpay.constant.WxPayConstants; -import org.testng.Assert; import org.testng.annotations.Test; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNull; + /** * @author m8cool */ public class WxPayBillResultTest { - - public static final String PAY_BILL_RESULT_ALL_CONTENT = "交易时间,公众账号ID,商户号,特约商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,应结订单金额,代金券金额,微信退款单号,商户退款单号,退款金额,充值券退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率,订单金额,申请退款金额,费率备注\n" + + private static final String PAY_BILL_RESULT_ALL_CONTENT = "交易时间,公众账号ID,商户号,特约商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,应结订单金额,代金券金额,微信退款单号,商户退款单号,退款金额,充值券退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率,订单金额,申请退款金额,费率备注\n" + "`2019-07-25 08:35:41,`WWWW,`XXXXXXXX,`0,`,`XXXXXXXXXXXXX,`XXXXXXXXXX,`XXXXXXXXXXX,`JSAPI,`SUCCESS,`PSBC_DEBIT,`CNY,`6.00,`0.00,`0,`0,`0.00,`0.00,`,`,`XXXXXX,`XXXXXXX,`0.04000,`0.60%,`6.00,`0.00,`\n" + "总交易单数,应结订单总金额,退款总金额,充值券退款总金额,手续费总金额,订单总金额,申请退款总金额\n" + "`48,`5.76,`1.42,`0.00,`0.01000,`5.76,`1.42\n"; - public static final String PAY_BILL_RESULT_SUCCESS_CONTENT = "交易时间,公众账号ID,商户号,特约商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,应结订单金额,代金券金额,商品名称,商户数据包,手续费,费率,订单金额,费率备注\n" + + private static final String PAY_BILL_RESULT_ALL_CONTENT_1 = "交易时间,公众账号ID,商户号,子商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,总金额,代金券或立减优惠金额,微信退款单号,商户退款单号,退款金额,代金券或立减优惠退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率\n" + + "`2014-11-10 16:33:45,`wx2421b1c4370ec43b,`10000100,`0,`1000,`1001690740201411100005734289,`1415640626,`085e9858e3ba5186aafcbaed1,`MICROPAY,`SUCCESS,`OTHERS,`CNY,`0.01,`0.0,`0,`0,`0,`0,`,`,`被扫支付测试,`订单额外描述,`0,`0.60%\n" + + "`2014-11-10 16:46:14,`wx2421b1c4370ec43b,`10000100,`0,`1000,`1002780740201411100005729794,`1415635270,`085e9858e90ca40c0b5aee463,`MICROPAY,`SUCCESS,`OTHERS,`CNY,`0.01,`0.0,`0,`0,`0,`0,`,`,`被扫支付测试,`订单额外描述,`0,`0.60%\n" + + "总交易单数,总交易额,总退款金额,总代金券或立减优惠退款金额,手续费总金额\n" + + "`2,`0.02,`0.0,`0.0,`0"; + + private static final String PAY_BILL_RESULT_SUCCESS_CONTENT = "交易时间,公众账号ID,商户号,特约商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,应结订单金额,代金券金额,商品名称,商户数据包,手续费,费率,订单金额,费率备注\n" + "`2019-07-23 18:46:41,`XXXX,`XXX,`XXX,`,`XXX,`XXX,`XXX,`JSAPI,`SUCCESS,`CFT,`CNY,`0.01,`0.00,`XXX,`XXXX,`0.00000,`0.60%,`0.01,`\n" + "总交易单数,应结订单总金额,退款总金额,充值券退款总金额,手续费总金额,订单总金额,申请退款总金额\n" + "`31,`3.05,`0.00,`0.00,`0.02000,`3.05,`0.00"; - public static final String PAY_BILL_RESULT_REFUND_CONTENT = "交易时间,公众账号ID,商户号,特约商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,应结订单金额,代金券金额,退款申请时间,退款成功时间,微信退款单号,商户退款单号,退款金额,充值券退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率,订单金额,申请退款金额,费率备注\n" + + private static final String PAY_BILL_RESULT_REFUND_CONTENT = "交易时间,公众账号ID,商户号,特约商户号,设备号,微信订单号,商户订单号,用户标识,交易类型,交易状态,付款银行,货币种类,应结订单金额,代金券金额,退款申请时间,退款成功时间,微信退款单号,商户退款单号,退款金额,充值券退款金额,退款类型,退款状态,商品名称,商户数据包,手续费,费率,订单金额,申请退款金额,费率备注\n" + "`2019-07-23 20:53:36,`xxx,`xxx,`xxx,`,`xxx,`xxxx,`xxxxx,`JSAPI,`REFUND,`CFT,`CNY,`0.00,`0.00,`2019-07-23 20:53:36,`2019-07-23 20:53:40,`xxxx,`xxx,`0.01,`0.00,`ORIGINAL,`SUCCESS,`xxxx,`xxxx,`0.00000,`0.60%,`0.00,`0.01,`\n" + "总交易单数,应结订单总金额,退款总金额,充值券退款总金额,手续费总金额,订单总金额,申请退款总金额\n" + "`4,`0.00,`2.02,`0.00,`-0.02000,`0.00,`2.02"; + /** * 测试微信返回类型为ALL时,解析结果是否正确 */ @@ -29,17 +37,29 @@ public class WxPayBillResultTest { public void testFromRawBillResultStringAll() { WxPayBillResult result = WxPayBillResult.fromRawBillResultString(PAY_BILL_RESULT_ALL_CONTENT, WxPayConstants.BillType.ALL); - Assert.assertEquals(result.getTotalRecord(), "48"); - Assert.assertEquals(result.getTotalFee(), "5.76"); - Assert.assertEquals(result.getTotalRefundFee(), "1.42"); - Assert.assertEquals(result.getTotalCouponFee(), "0.00"); - Assert.assertEquals(result.getTotalPoundageFee(), "0.01000"); - Assert.assertEquals(result.getTotalAmount(), "5.76"); - Assert.assertEquals(result.getTotalAppliedRefundFee(), "1.42"); - Assert.assertEquals(result.getBillInfoList().get(0).getTotalAmount(), "6.00"); - Assert.assertEquals(result.getBillInfoList().get(0).getAppliedRefundAmount(), "0.00"); - Assert.assertEquals(result.getBillInfoList().get(0).getFeeRemark(), ""); + assertEquals(result.getTotalRecord(), "48"); + assertEquals(result.getTotalFee(), "5.76"); + assertEquals(result.getTotalRefundFee(), "1.42"); + assertEquals(result.getTotalCouponFee(), "0.00"); + assertEquals(result.getTotalPoundageFee(), "0.01000"); + assertEquals(result.getTotalAmount(), "5.76"); + assertEquals(result.getTotalAppliedRefundFee(), "1.42"); + assertEquals(result.getBillInfoList().get(0).getTotalAmount(), "6.00"); + assertEquals(result.getBillInfoList().get(0).getAppliedRefundAmount(), "0.00"); + assertEquals(result.getBillInfoList().get(0).getFeeRemark(), ""); + + result = WxPayBillResult.fromRawBillResultString(PAY_BILL_RESULT_ALL_CONTENT_1, WxPayConstants.BillType.ALL); + assertEquals(result.getTotalRecord(), "2"); + assertEquals(result.getTotalFee(), "0.02"); + assertEquals(result.getTotalRefundFee(), "0.0"); + assertEquals(result.getTotalCouponFee(), "0.0"); + assertEquals(result.getTotalPoundageFee(), "0"); + assertNull(result.getTotalAmount()); + assertNull(result.getTotalAppliedRefundFee()); + assertNull(result.getBillInfoList().get(0).getTotalAmount()); + assertNull(result.getBillInfoList().get(0).getAppliedRefundAmount()); + assertNull(result.getBillInfoList().get(0).getFeeRemark()); } @@ -50,15 +70,15 @@ public void testFromRawBillResultStringAll() { public void testFromRawBillResultStringSuccess() { WxPayBillResult result = WxPayBillResult.fromRawBillResultString(PAY_BILL_RESULT_SUCCESS_CONTENT, WxPayConstants.BillType.SUCCESS); - Assert.assertEquals(result.getTotalRecord(), "31"); - Assert.assertEquals(result.getTotalFee(), "3.05"); - Assert.assertEquals(result.getTotalRefundFee(), "0.00"); - Assert.assertEquals(result.getTotalCouponFee(), "0.00"); - Assert.assertEquals(result.getTotalPoundageFee(), "0.02000"); - Assert.assertEquals(result.getTotalAmount(), "3.05"); - Assert.assertEquals(result.getTotalAppliedRefundFee(), "0.00"); - Assert.assertEquals(result.getBillInfoList().get(0).getTotalAmount(), "0.01"); - Assert.assertEquals(result.getBillInfoList().get(0).getFeeRemark(), ""); + assertEquals(result.getTotalRecord(), "31"); + assertEquals(result.getTotalFee(), "3.05"); + assertEquals(result.getTotalRefundFee(), "0.00"); + assertEquals(result.getTotalCouponFee(), "0.00"); + assertEquals(result.getTotalPoundageFee(), "0.02000"); + assertEquals(result.getTotalAmount(), "3.05"); + assertEquals(result.getTotalAppliedRefundFee(), "0.00"); + assertEquals(result.getBillInfoList().get(0).getTotalAmount(), "0.01"); + assertEquals(result.getBillInfoList().get(0).getFeeRemark(), ""); } } From db1f10b6fa7d8a43d0968f4eb44398710fddbbf1 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 28 Dec 2019 16:42:14 +0800 Subject: [PATCH 0029/1706] =?UTF-8?q?:bookmark:=20=E5=8F=91=E5=B8=833.6.4.?= =?UTF-8?q?B=E6=B5=8B=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 +- spring-boot-starters/pom.xml | 2 +- .../wx-java-miniapp-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-pay-spring-boot-starter/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 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index 3a7835627b..91b0418d2d 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.github.binarywang wx-java - 3.6.3.B + 3.6.4.B pom WxJava - Weixin/Wechat Java SDK 微信开发Java SDK diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml index 4794e18cbd..9dbe4aa5f8 100644 --- a/spring-boot-starters/pom.xml +++ b/spring-boot-starters/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 3.6.3.B + 3.6.4.B pom wx-java-spring-boot-starters diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml index a4a958dda0..6f8934a8eb 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.3.B + 3.6.4.B 4.0.0 diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml index dddd3dcc77..ebbe34c58e 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.3.B + 3.6.4.B 4.0.0 diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml index f87b4653d4..0a19e07b60 100644 --- a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.3.B + 3.6.4.B 4.0.0 diff --git a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml index 3d5fa4882d..94888c80e1 100644 --- a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.3.B + 3.6.4.B 4.0.0 diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index e7b5b590aa..656956a55e 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 3.6.3.B + 3.6.4.B weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 0df56b7917..c9b071e958 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.3.B + 3.6.4.B weixin-java-cp diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index d92c4122bf..ae198aa2a5 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.3.B + 3.6.4.B weixin-java-miniapp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 1ba60ef812..58695ca908 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.3.B + 3.6.4.B weixin-java-mp diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index 4acda5b122..4d3db6bc00 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.3.B + 3.6.4.B weixin-java-open diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index da16bc88ac..eb039ba966 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ com.github.binarywang wx-java - 3.6.3.B + 3.6.4.B 4.0.0 From aad2e5be45ba0192540247e27d2ded3d06605d9d Mon Sep 17 00:00:00 2001 From: zx_freedom <40882731+zxfreedom@users.noreply.github.com> Date: Mon, 30 Dec 2019 15:40:31 +0800 Subject: [PATCH 0030/1706] =?UTF-8?q?:art:=20#1347=20=E5=BC=80=E6=94=BE?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0=E6=A8=A1=E5=9D=97=E6=9B=B4=E6=96=B0=E4=BB=A3?= =?UTF-8?q?=E5=BC=80=E5=8F=91=E5=B0=8F=E7=A8=8B=E5=BA=8F=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E5=AE=A1=E6=A0=B8=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../open/bean/ma/WxOpenMaPreviewInfo.java | 27 +++++++++++++++++++ .../message/WxOpenMaSubmitAuditMessage.java | 13 +++++++++ 2 files changed, 40 insertions(+) create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaPreviewInfo.java diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaPreviewInfo.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaPreviewInfo.java new file mode 100644 index 0000000000..a1f0416dd2 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/ma/WxOpenMaPreviewInfo.java @@ -0,0 +1,27 @@ +package me.chanjar.weixin.open.bean.ma; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.util.List; + +/** + * @author zxfreedom + * @description + * @date 2019/12/30 + */ +@Data +public class WxOpenMaPreviewInfo { + + /** + * 录屏mediaid列表,可以通过提审素材上传接口获得 + */ + @SerializedName("video_id_list") + private String[] videoIdList; + + /** + * 截屏mediaid列表,可以通过提审素材上传接口获得 + */ + @SerializedName("pic_id_list") + private String[] picIdList; +} diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenMaSubmitAuditMessage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenMaSubmitAuditMessage.java index 51698a9c28..56129a9845 100644 --- a/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenMaSubmitAuditMessage.java +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/bean/message/WxOpenMaSubmitAuditMessage.java @@ -2,6 +2,7 @@ import com.google.gson.annotations.SerializedName; import lombok.Data; +import me.chanjar.weixin.open.bean.ma.WxOpenMaPreviewInfo; import me.chanjar.weixin.open.bean.ma.WxOpenMaSubmitAudit; import java.io.Serializable; @@ -22,6 +23,18 @@ public class WxOpenMaSubmitAuditMessage implements Serializable { @SerializedName("item_list") private List itemList; + /** + * 预览信息(小程序页面截图和操作录屏) + */ + @SerializedName("preview_info") + private List previewInfo; + + /** + * 小程序版本说明和功能解释 + */ + @SerializedName("version_desc") + private String versionDesc; + /** * 反馈内容,不超过200字 */ From db8f7e6a061f50d3348bbcd0784d0e7956048ab8 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Tue, 31 Dec 2019 17:43:22 +0800 Subject: [PATCH 0031/1706] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6d862fe418..e4e5054944 100644 --- a/README.md +++ b/README.md @@ -25,12 +25,12 @@ - + - + From 7d4dfadae93f82861be2434bd68bab666acfe035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E5=9B=A0=E6=96=AF=E5=94=90?= Date: Fri, 3 Jan 2020 12:51:48 +0800 Subject: [PATCH 0032/1706] =?UTF-8?q?:new:=20#1344=20=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=A2=9E=E5=8A=A0=E6=96=B0=E7=9A=84=E5=AE=A1?= =?UTF-8?q?=E6=89=B9=E6=8E=A5=E5=8F=A3=EF=BC=9A=20=E2=80=9C=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E8=8E=B7=E5=8F=96=E5=AE=A1=E6=89=B9=E5=8D=95=E5=8F=B7?= =?UTF-8?q?=E2=80=9D=E5=8F=8A=E2=80=9C=E8=8E=B7=E5=8F=96=E5=AE=A1=E6=89=B9?= =?UTF-8?q?=E7=94=B3=E8=AF=B7=E8=AF=A6=E6=83=85=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chanjar/weixin/cp/api/WxCpOaService.java | 81 ++++++++++++-- .../weixin/cp/api/impl/WxCpOaServiceImpl.java | 77 +++++++++++-- .../cp/bean/oa/WxCpApprovalApplyData.java | 21 ++++ .../cp/bean/oa/WxCpApprovalApplyer.java | 23 ++++ .../cp/bean/oa/WxCpApprovalComment.java | 48 ++++++++ .../bean/{ => oa}/WxCpApprovalDataResult.java | 3 +- .../weixin/cp/bean/oa/WxCpApprovalDetail.java | 78 +++++++++++++ .../cp/bean/oa/WxCpApprovalDetailResult.java | 27 +++++ .../weixin/cp/bean/oa/WxCpApprovalInfo.java | 29 +++++ .../bean/oa/WxCpApprovalInfoQueryFilter.java | 61 +++++++++++ .../weixin/cp/bean/oa/WxCpApprovalRecord.java | 26 +++++ .../cp/bean/oa/WxCpApprovalRecordDetail.java | 48 ++++++++ .../weixin/cp/bean/oa/WxCpApproverAttr.java | 28 +++++ .../cp/bean/{ => oa}/WxCpCheckinData.java | 2 +- .../cp/bean/{ => oa}/WxCpCheckinOption.java | 2 +- .../cp/bean/{ => oa}/WxCpDialRecord.java | 2 +- .../weixin/cp/bean/oa/WxCpOperator.java | 24 ++++ .../weixin/cp/bean/oa/WxCpRecordSpStatus.java | 41 +++++++ .../weixin/cp/bean/oa/WxCpSpStatus.java | 54 +++++++++ .../weixin/cp/bean/oa/applydata/Content.java | 24 ++++ .../cp/bean/oa/applydata/ContentTitle.java | 18 +++ .../cp/bean/oa/applydata/ContentValue.java | 103 ++++++++++++++++++ .../weixin/cp/constant/WxCpApiPathConsts.java | 5 +- .../cp/api/impl/WxCpOaServiceImplTest.java | 51 +++++++-- 24 files changed, 843 insertions(+), 33 deletions(-) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalApplyData.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalApplyer.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalComment.java rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/{ => oa}/WxCpApprovalDataResult.java (96%) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetail.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetailResult.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalInfo.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalInfoQueryFilter.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalRecord.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalRecordDetail.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApproverAttr.java rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/{ => oa}/WxCpCheckinData.java (96%) rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/{ => oa}/WxCpCheckinOption.java (98%) rename weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/{ => oa}/WxCpDialRecord.java (97%) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpOperator.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpRecordSpStatus.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpSpStatus.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/Content.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentTitle.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentValue.java 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 index c6f90d3e64..f244700251 100644 --- 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 @@ -1,10 +1,8 @@ package me.chanjar.weixin.cp.api; +import lombok.NonNull; 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 me.chanjar.weixin.cp.bean.oa.*; import java.util.Date; import java.util.List; @@ -30,7 +28,8 @@ public interface WxCpOaService { * @return 打卡数据列表 * @throws WxErrorException 异常 */ - List getCheckinData(Integer openCheckinDataType, Date startTime, Date endTime, List userIdList) throws WxErrorException; + List getCheckinData(Integer openCheckinDataType, Date startTime, Date endTime, + List userIdList) throws WxErrorException; /** *
@@ -41,13 +40,63 @@ public interface WxCpOaService {
    * @param datetime   需要获取规则的当天日期
    * @param userIdList 需要获取打卡规则的用户列表
    * @return 打卡规则列表
-   * @throws WxErrorException 异常
+   * @throws WxErrorException
    */
   List getCheckinOption(Date datetime, List userIdList) throws WxErrorException;
 
   /**
    * 
-   *   获取审批数据
+   *
+   * 批量获取审批单号
+   *
+   * 审批应用及有权限的自建应用,可通过Secret调用本接口,以获取企业一段时间内企业微信“审批应用”单据的审批编号,支持按模板类型、申请人、部门、申请单审批状态等条件筛选。
+   * 自建应用调用此接口,需在“管理后台-应用管理-审批-API-审批数据权限”中,授权应用允许提交审批单据。
+   *
+   * 一次拉取调用最多拉取100个审批记录,可以通过多次拉取的方式来满足需求,但调用频率不可超过600次/分。
+   *
+   * API doc : https://work.weixin.qq.com/api/doc/90000/90135/91816
+   * 
+ * + * @param startTime 开始时间 + * @param endTime 结束时间 + * @param cursor 分页查询游标,默认为0,后续使用返回的next_cursor进行分页拉取 + * @param size 一次请求拉取审批单数量,默认值为100,上限值为100 + * @param filters 筛选条件,可对批量拉取的审批申请设置约束条件,支持设置多个条件,nullable + * @return WxCpApprovalInfo + * @throws WxErrorException + */ + WxCpApprovalInfo getApprovalInfo(@NonNull Date startTime, @NonNull Date endTime, Integer cursor, Integer size, + List filters) throws WxErrorException; + + /** + * short method + * + * @param startTime 开始时间 + * @param endTime 结束时间 + * @return WxCpApprovalInfo + * @throws WxErrorException + * @see me.chanjar.weixin.cp.api.WxCpOaService#getApprovalInfo + */ + WxCpApprovalInfo getApprovalInfo(@NonNull Date startTime, @NonNull Date endTime) throws WxErrorException; + + /** + *
+   *   获取审批申请详情
+   *
+   *   企业可通过审批应用或自建应用Secret调用本接口,根据审批单号查询企业微信“审批应用”的审批申请详情。
+   *
+   *   API Doc : https://work.weixin.qq.com/api/doc/90000/90135/91983
+   * 
+ * + * @param spNo 审批单编号。 + * @return WxCpApprovaldetail + * @throws WxErrorException + */ + WxCpApprovalDetailResult getApprovalDetail(@NonNull String spNo) throws WxErrorException; + + /** + *
+   *   获取审批数据 (已过期, 请使用"批量获取审批单号" && "获取审批申请详情")
    *   通过本接口来获取公司一段时间内的审批记录。一次拉取调用最多拉取10000个审批记录,可以通过多次拉取的方式来满足需求,但调用频率不可超过600次/分。
    *   API doc : https://work.weixin.qq.com/api/doc#90000/90135/91530
    * 
@@ -55,10 +104,24 @@ public interface WxCpOaService { * @param startTime 获取审批记录的开始时间 * @param endTime 获取审批记录的结束时间 * @param nextSpnum 第一个拉取的审批单号,不填从该时间段的第一个审批单拉取 - * @throws WxErrorException 异常 + * @throws WxErrorException + * @see me.chanjar.weixin.cp.api.WxCpOaService#getApprovalInfo + * @see me.chanjar.weixin.cp.api.WxCpOaService#getApprovalDetail */ + @Deprecated WxCpApprovalDataResult getApprovalData(Date startTime, Date endTime, Long nextSpnum) throws WxErrorException; - List getDialRecord(Date startTime, Date endTime, Integer offset, Integer limit) throws WxErrorException; + /** + * 获取公费电话拨打记录 + * + * @param startTime 查询的起始时间戳 + * @param endTime 查询的结束时间戳 + * @param offset 分页查询的偏移量 + * @param limit 分页查询的每页大小,默认为100条,如该参数大于100则按100处理 + * @return + * @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/impl/WxCpOaServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpOaServiceImpl.java index b8449ced13..2a1d41ec7a 100644 --- 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 @@ -5,15 +5,12 @@ import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.reflect.TypeToken; +import lombok.NonNull; import lombok.RequiredArgsConstructor; 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.constant.WxCpApiPathConsts; +import me.chanjar.weixin.cp.bean.oa.*; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; import java.util.Date; @@ -22,7 +19,7 @@ import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Oa.*; /** - * . + * 企业微信 OA 接口实现 * * @author Element * @date 2019-04-06 11:20 @@ -31,6 +28,9 @@ public class WxCpOaServiceImpl implements WxCpOaService { private final WxCpService mainService; + private static final int MONTH_SECONDS = 30 * 24 * 60 * 60; + private static final int USER_IDS_LIMIT = 100; + @Override public List getCheckinData(Integer openCheckinDataType, Date startTime, Date endTime, List userIdList) throws WxErrorException { @@ -38,14 +38,14 @@ public List getCheckinData(Integer openCheckinDataType, Date st throw new RuntimeException("starttime and endtime can't be null"); } - if (userIdList == null || userIdList.size() > 100) { - throw new RuntimeException("用户列表不能为空,不超过100个,若用户超过100个,请分批获取"); + if (userIdList == null || userIdList.size() > USER_IDS_LIMIT) { + throw new RuntimeException("用户列表不能为空,不超过 " + USER_IDS_LIMIT + " 个,若用户超过 " + USER_IDS_LIMIT + " 个,请分批获取"); } long endtimestamp = endTime.getTime() / 1000L; long starttimestamp = startTime.getTime() / 1000L; - if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= 30 * 24 * 60 * 60) { + if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= MONTH_SECONDS) { throw new RuntimeException("获取记录时间跨度不超过一个月"); } @@ -79,8 +79,8 @@ public List getCheckinOption(Date datetime, List user throw new RuntimeException("datetime can't be null"); } - if (userIdList == null || userIdList.size() > 100) { - throw new RuntimeException("用户列表不能为空,不超过100个,若用户超过100个,请分批获取"); + if (userIdList == null || userIdList.size() > USER_IDS_LIMIT) { + throw new RuntimeException("用户列表不能为空,不超过 " + USER_IDS_LIMIT + " 个,若用户超过 " + USER_IDS_LIMIT + " 个,请分批获取"); } JsonArray jsonArray = new JsonArray(); @@ -104,6 +104,59 @@ public List getCheckinOption(Date datetime, List user ); } + @Override + public WxCpApprovalInfo getApprovalInfo(@NonNull Date startTime, @NonNull Date endTime, + Integer cursor, Integer size, List filters) throws WxErrorException { + + if (cursor == null) { + cursor = 0; + } + + if (size == null) { + size = 100; + } + + if (size < 0 || size > 100) { + throw new IllegalArgumentException("size参数错误,请使用[1-100]填充,默认100"); + } + + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("starttime", startTime.getTime() / 1000L); + jsonObject.addProperty("endtime", endTime.getTime() / 1000L); + jsonObject.addProperty("size", size); + jsonObject.addProperty("cursor", cursor); + + if (filters != null && !filters.isEmpty()) { + JsonArray filterJsonArray = new JsonArray(); + for (WxCpApprovalInfoQueryFilter filter : filters) { + filterJsonArray.add(new JsonParser().parse(filter.toJson())); + } + jsonObject.add("filters", filterJsonArray); + } + + final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_APPROVAL_INFO); + String responseContent = this.mainService.post(url, jsonObject.toString()); + + return WxCpGsonBuilder.create().fromJson(responseContent, WxCpApprovalInfo.class); + } + + @Override + public WxCpApprovalInfo getApprovalInfo(@NonNull Date startTime, @NonNull Date endTime) throws WxErrorException { + return this.getApprovalInfo(startTime, endTime, null, null, null); + } + + @Override + public WxCpApprovalDetailResult getApprovalDetail(@NonNull String spNo) throws WxErrorException { + + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("sp_no", spNo); + + final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_APPROVAL_DETAIL); + String responseContent = this.mainService.post(url, jsonObject.toString()); + + return WxCpGsonBuilder.create().fromJson(responseContent, WxCpApprovalDetailResult.class); + } + @Override public WxCpApprovalDataResult getApprovalData(Date startTime, Date endTime, Long nextSpnum) throws WxErrorException { JsonObject jsonObject = new JsonObject(); @@ -139,7 +192,7 @@ public List getDialRecord(Date startTime, Date endTime, Integer long endtimestamp = endTime.getTime() / 1000L; long starttimestamp = startTime.getTime() / 1000L; - if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= 30 * 24 * 60 * 60) { + if (endtimestamp - starttimestamp < 0 || endtimestamp - starttimestamp >= MONTH_SECONDS) { throw new RuntimeException("受限于网络传输,起止时间的最大跨度为30天,如超过30天,则以结束时间为基准向前取30天进行查询"); } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalApplyData.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalApplyData.java new file mode 100644 index 0000000000..26b37aea9c --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalApplyData.java @@ -0,0 +1,21 @@ +package me.chanjar.weixin.cp.bean.oa; + +import lombok.Data; +import me.chanjar.weixin.cp.bean.oa.applydata.Content; + +import java.io.Serializable; +import java.util.List; + +/** + * 审批申请数据 + * + * @author element + */ +@Data +public class WxCpApprovalApplyData implements Serializable { + + private static final long serialVersionUID = 4061352949894274704L; + + private List contents; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalApplyer.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalApplyer.java new file mode 100644 index 0000000000..f648a6a915 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalApplyer.java @@ -0,0 +1,23 @@ +package me.chanjar.weixin.cp.bean.oa; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 申请人信息 + * @author element + */ +@Data +public class WxCpApprovalApplyer extends WxCpOperator implements Serializable { + + private static final long serialVersionUID = -8974662568286821271L; + + /** + * 申请人所在部门id + */ + @SerializedName("partyid") + private String partyId; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalComment.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalComment.java new file mode 100644 index 0000000000..8a70e3e6e9 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalComment.java @@ -0,0 +1,48 @@ +package me.chanjar.weixin.cp.bean.oa; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 审批申请备注信息 + * + * @author element + */ +@Data +public class WxCpApprovalComment implements Serializable { + + private static final long serialVersionUID = -5430367411926856292L; + + /** + * 备注人信息 + */ + private WxCpOperator commentUserInfo; + + /** + * 备注提交时间戳,Unix时间戳 + */ + @SerializedName("commenttime") + private Long commentTime; + + /** + * 备注id + */ + @SerializedName("commentid") + private String commentId; + + /** + * 备注文本内容 + */ + @SerializedName("commentcontent") + private String commentContent; + + /** + * 备注附件id,可能有多个 + */ + @SerializedName("media_id") + private List mediaIds; + +} 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/oa/WxCpApprovalDataResult.java similarity index 96% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpApprovalDataResult.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDataResult.java index 383c526568..b348c97a94 100644 --- 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/oa/WxCpApprovalDataResult.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.oa; import com.google.gson.annotations.SerializedName; import lombok.Data; @@ -12,6 +12,7 @@ * @author Element * @date 2019-04-06 14:36 */ +@Deprecated @Data public class WxCpApprovalDataResult implements Serializable { private static final long serialVersionUID = -1046940445840716590L; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetail.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetail.java new file mode 100644 index 0000000000..5021a57ee6 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetail.java @@ -0,0 +1,78 @@ +package me.chanjar.weixin.cp.bean.oa; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 审批申请详情 + * + * @author element + */ +@Data +public class WxCpApprovalDetail implements Serializable { + + private static final long serialVersionUID = 1353393306564207170L; + + /** + * 审批编号 + */ + @SerializedName("sp_no") + private String spNo; + + /** + * 审批申请类型名称(审批模板名称) + */ + @SerializedName("sp_name") + private String spName; + + /** + * 申请单状态:1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付 + */ + @SerializedName("sp_status") + private WxCpSpStatus spStatus; + + /** + * 审批模板id。可在“获取审批申请详情”、“审批状态变化回调通知”中获得,也可在审批模板的模板编辑页面链接中获得。 + */ + @SerializedName("template_id") + private String templateId; + + /** + * 审批申请提交时间,Unix时间戳 + */ + @SerializedName("apply_time") + private Long applyTime; + + /** + * 申请人信息 + */ + private WxCpApprovalApplyer applyer; + + /** + * 审批流程信息,可能有多个审批节点 + */ + @SerializedName("sp_record") + private WxCpApprovalRecord spRecord; + + /** + * 抄送信息,可能有多个抄送节点 + */ + @SerializedName("notifyer") + private WxCpOperator notifyer; + + /** + * 审批申请数据 + */ + @SerializedName("apply_data") + private WxCpApprovalApplyData applyData; + + /** + * 审批申请备注信息,可能有多个备注节点 + */ + @SerializedName("comments") + private List comments; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetailResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetailResult.java new file mode 100644 index 0000000000..eb8cd1c1ad --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetailResult.java @@ -0,0 +1,27 @@ +package me.chanjar.weixin.cp.bean.oa; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 审批申请详情响应结果 + * + * @author element + */ +@Data +public class WxCpApprovalDetailResult implements Serializable { + + private static final long serialVersionUID = 3909779949756252918L; + + @SerializedName("errcode") + private Integer errCode; + + @SerializedName("errmsg") + private String errMsg; + + @SerializedName("info") + private WxCpApprovalDetail info; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalInfo.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalInfo.java new file mode 100644 index 0000000000..b12d88baf8 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalInfo.java @@ -0,0 +1,29 @@ +package me.chanjar.weixin.cp.bean.oa; + +import java.io.Serializable; +import java.util.List; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +/** + * @author element + */ +@Data +public class WxCpApprovalInfo implements Serializable { + + private static final long serialVersionUID = 7387181805254287167L; + + @SerializedName("errcode") + private Integer errCode; + + @SerializedName("errmsg") + private String errMsg; + + @SerializedName("sp_no_list") + private List spNoList; + + @SerializedName("next_cursor") + private Integer nextCursor; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalInfoQueryFilter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalInfoQueryFilter.java new file mode 100644 index 0000000000..5271312081 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalInfoQueryFilter.java @@ -0,0 +1,61 @@ +package me.chanjar.weixin.cp.bean.oa; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.io.Serializable; + +/** + *
+ *  批量获取审批单号的筛选条件,可对批量拉取的审批申请设置约束条件,支持设置多个条件
+ *  注意:
+ *  仅“部门”支持同时配置多个筛选条件。
+ *  不同类型的筛选条件之间为“与”的关系,同类型筛选条件之间为“或”的关系
+ * 
+ * + * @author element + */ +@Data +public class WxCpApprovalInfoQueryFilter implements Serializable { + + private static final long serialVersionUID = 3318064927980231802L; + + private WxCpApprovalInfoQueryFilter.KEY key; + + private Object value; + + public String toJson() { + return WxGsonBuilder.create().toJson(this); + } + + public static enum KEY { + + /** + * template_id - 模板类型/模板id; + */ + @SerializedName("template_id") + TEMPLATE_ID("template_id"), + /** + * creator - 申请人; + */ + @SerializedName("creator") + CREATOR("creator"), + /** + * department - 审批单提单者所在部门; + */ + @SerializedName("department") + DEPARTMENT("department"), + /** + * sp_status - 审批状态。 + */ + @SerializedName("sp_status") + SP_STATUS("sp_status"); + + private String value; + + private KEY(String value) { + this.value = value; + } + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalRecord.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalRecord.java new file mode 100644 index 0000000000..3325eaa4ac --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalRecord.java @@ -0,0 +1,26 @@ +package me.chanjar.weixin.cp.bean.oa; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 审批流程信息 + * @author element + */ +@Data +public class WxCpApprovalRecord implements Serializable { + + private static final long serialVersionUID = -327230786004105887L; + + @SerializedName("sp_status") + private WxCpRecordSpStatus status; + + @SerializedName("approverattr") + private WxCpApproverAttr approverAttr; + + private List details; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalRecordDetail.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalRecordDetail.java new file mode 100644 index 0000000000..4c966c9d6f --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalRecordDetail.java @@ -0,0 +1,48 @@ +package me.chanjar.weixin.cp.bean.oa; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 审批节点详情 + * @author element + */ +@Data +public class WxCpApprovalRecordDetail implements Serializable { + + private static final long serialVersionUID = -9142079764088495301L; + + /** + * 分支审批人 + */ + @SerializedName("approver") + private WxCpOperator approver; + + /** + * 审批意见 + */ + @SerializedName("speech") + private String speech; + + /** + * 分支审批人审批状态 + */ + @SerializedName("sp_status") + private WxCpRecordSpStatus spStatus; + + /** + * 节点分支审批人审批操作时间戳,0表示未操作 + */ + @SerializedName("sptime") + private Long spTime; + + /** + * 节点分支审批人审批意见附件 + */ + @SerializedName("media_id") + private List mediaIds; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApproverAttr.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApproverAttr.java new file mode 100644 index 0000000000..15e55f2f72 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApproverAttr.java @@ -0,0 +1,28 @@ +package me.chanjar.weixin.cp.bean.oa; + +import com.google.gson.annotations.SerializedName; + +/** + * 审批方式 + * + * @author element + */ +public enum WxCpApproverAttr { + /** + * 或签 + */ + @SerializedName("1") + ONE_SIGN(1), + /** + * 会签 + */ + @SerializedName("2") + ALL_SIGN(2); + + private Integer attr; + + private WxCpApproverAttr(Integer attr) { + this.attr = attr; + } + +} 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/oa/WxCpCheckinData.java similarity index 96% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpCheckinData.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpCheckinData.java index d2fbf0f9d7..555f59c017 100644 --- 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/oa/WxCpCheckinData.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.oa; import com.google.gson.annotations.SerializedName; import lombok.Data; 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/oa/WxCpCheckinOption.java similarity index 98% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpCheckinOption.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpCheckinOption.java index c554e3d706..70cd4b202a 100644 --- 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/oa/WxCpCheckinOption.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.oa; import com.google.gson.annotations.SerializedName; import lombok.Data; 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/oa/WxCpDialRecord.java similarity index 97% rename from weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDialRecord.java rename to weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpDialRecord.java index 4f93b3decc..f3cf7d9881 100644 --- 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/oa/WxCpDialRecord.java @@ -1,4 +1,4 @@ -package me.chanjar.weixin.cp.bean; +package me.chanjar.weixin.cp.bean.oa; import com.google.gson.annotations.SerializedName; import lombok.Data; diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpOperator.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpOperator.java new file mode 100644 index 0000000000..063234dac2 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpOperator.java @@ -0,0 +1,24 @@ +package me.chanjar.weixin.cp.bean.oa; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + + +/** + * 企业微信操作人 + * + * @author element + */ +@Data +public class WxCpOperator implements Serializable { + + private static final long serialVersionUID = 5797144853574346736L; + + /** + * 企业微信userid + */ + @SerializedName("userid") + private String userId; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpRecordSpStatus.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpRecordSpStatus.java new file mode 100644 index 0000000000..206a0aa04e --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpRecordSpStatus.java @@ -0,0 +1,41 @@ +package me.chanjar.weixin.cp.bean.oa; + +import com.google.gson.annotations.SerializedName; + +/** + * 审批记录(节点)分支审批状态 + * + * 1-审批中;2-已同意;3-已驳回;4-已转审 + * + * @author element + */ +public enum WxCpRecordSpStatus { + + /** + * 审批中 + */ + @SerializedName("1") + AUDITING(1), + /** + * 已同意 + */ + @SerializedName("2") + PASSED(2), + /** + * 已驳回 + */ + @SerializedName("3") + REJECTED(3), + /** + * 已转审 + */ + @SerializedName("4") + TURNED(4); + + private Integer status; + + private WxCpRecordSpStatus(Integer status) { + this.status = status; + } + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpSpStatus.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpSpStatus.java new file mode 100644 index 0000000000..c3d8005f50 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpSpStatus.java @@ -0,0 +1,54 @@ +package me.chanjar.weixin.cp.bean.oa; + +import com.google.gson.annotations.SerializedName; + +/** + * 审批单状态 + * (1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付) + * + * @author element + */ +public enum WxCpSpStatus { + + /** + * 审批中 + */ + @SerializedName("1") + AUDITING(1), + /** + * 已通过 + */ + @SerializedName("2") + PASSED(2), + /** + * 已驳回 + */ + @SerializedName("3") + REJECTED(3), + /** + * 已撤销 + */ + @SerializedName("4") + UNDONE(4), + /** + * 通过后撤销 + */ + @SerializedName("6") + PASS_UNDONE(6), + /** + * 已删除 + */ + @SerializedName("7") + DELETED(7), + /** + * 已支付 + */ + @SerializedName("10") + ALREADY_PAY(10); + + private Integer status; + + private WxCpSpStatus(Integer status) { + this.status = status; + } +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/Content.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/Content.java new file mode 100644 index 0000000000..c4eb4ada0f --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/Content.java @@ -0,0 +1,24 @@ +package me.chanjar.weixin.cp.bean.oa.applydata; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author element + */ +@Data +public class Content implements Serializable { + private static final long serialVersionUID = 8456821731930526935L; + + private String control; + + private String id; + + @SerializedName("title") + private List titles; + + private ContentValue value; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentTitle.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentTitle.java new file mode 100644 index 0000000000..24d5fafc2d --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentTitle.java @@ -0,0 +1,18 @@ +package me.chanjar.weixin.cp.bean.oa.applydata; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author element + */ +@Data +public class ContentTitle implements Serializable { + + private static final long serialVersionUID = -4501999157383517007L; + + private String text; + private String lang; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentValue.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentValue.java new file mode 100644 index 0000000000..7798338aa1 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentValue.java @@ -0,0 +1,103 @@ +package me.chanjar.weixin.cp.bean.oa.applydata; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author element + */ +@Data +public class ContentValue implements Serializable { + + private static final long serialVersionUID = -5607678965965065261L; + + private String text; + + @SerializedName("new_number") + private Integer newNumber; + + @SerializedName("new_money") + private Integer newMoney; + + private ContentValue.Date date; + + private ContentValue.Selector selector; + + private List members; + + private List departments; + + private List files; + + private List children; + + @Data + public static class Date implements Serializable { + + private static final long serialVersionUID = -6181554080062231138L; + private String type; + + @SerializedName("s_timestamp") + private Long timestamp; + } + + @Data + public static class Selector implements Serializable { + + private static final long serialVersionUID = 7305458759126951773L; + private String type; + private List
* * @param userId 外部联系人的userid + * @return . + * @deprecated 建议使用 {@link #getContactDetail(String)} */ + @Deprecated WxCpUserExternalContactInfo getExternalContact(String userId) throws WxErrorException; /** - * 获取外部联系人列表. + * 获取客户详情. *
-   *   企业可通过此接口获取指定成员添加的客户列表。
-   *   客户是指配置了客户联系功能的成员所添加的外部联系人。
-   *   没有配置客户联系功能的成员,所添加的外部联系人将不会作为客户返回。
+   *
+   * 企业可通过此接口,根据外部联系人的userid(如何获取?),拉取客户详情。
+   *
+   * 请求方式:GET(HTTPS)
+   * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/get?access_token=ACCESS_TOKEN&external_userid=EXTERNAL_USERID
+   *
+   * 权限说明:
+   *
+   * 企业需要使用“客户联系”secret或配置到“可调用应用”列表中的自建应用secret所获取的accesstoken来调用(accesstoken如何获取?);
+   * 第三方/自建应用调用时,返回的跟进人follow_user仅包含应用可见范围之内的成员。
+   * 
+ * + * @param userId 外部联系人的userid,注意不是企业成员的帐号 + * @return . + * @throws WxErrorException . + */ + WxCpUserExternalContactInfo getContactDetail(String userId) throws WxErrorException; + + /** + * 获取客户列表. + *
+   *   企业可通过此接口获取指定成员添加的客户列表。客户是指配置了客户联系功能的成员所添加的外部联系人。没有配置客户联系功能的成员,所添加的外部联系人将不会作为客户返回。
+   *
+   * 请求方式:GET(HTTPS)
+   * 请求地址:https://qyapi.weixin.qq.com/cgi-bin/externalcontact/list?access_token=ACCESS_TOKEN&userid=USERID
+   *
+   * 权限说明:
+   *
+   * 企业需要使用“客户联系”secret或配置到“可调用应用”列表中的自建应用secret所获取的accesstoken来调用(accesstoken如何获取?);
    * 第三方应用需拥有“企业客户”权限。
-   * 第三方应用调用时,返回的跟进人follow_user仅包含应用可见范围之内的成员。
+   * 第三方/自建应用只能获取到可见范围内的配置了客户联系功能的成员。
    * 
* - * @param userId 外部联系人的userid + * @param userId 企业成员的userid * @return List of External wx id + * @throws WxErrorException . */ List listExternalContacts(String userId) throws WxErrorException; - /** * 企业和第三方服务商可通过此接口获取配置了客户联系功能的成员(Customer Contact)列表。 *
@@ -52,7 +81,9 @@ public interface WxCpExternalContactService {
    * 
* * @return List of CpUser id + * @throws WxErrorException . */ + @Deprecated List listFollowUser() throws WxErrorException; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImpl.java index 8a5b7d56e8..044b1e5d49 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImpl.java @@ -25,6 +25,13 @@ public WxCpUserExternalContactInfo getExternalContact(String userId) throws WxEr return WxCpUserExternalContactInfo.fromJson(responseContent); } + @Override + public WxCpUserExternalContactInfo getContactDetail(String userId) throws WxErrorException { + final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_CONTACT_DETAIL + userId); + String responseContent = this.mainService.get(url, null); + return WxCpUserExternalContactInfo.fromJson(responseContent); + } + @Override public List listExternalContacts(String userId) throws WxErrorException { final String url = this.mainService.getWxCpConfigStorage().getApiUrl(LIST_EXTERNAL_CONTACT + userId); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java index 77058adbe7..2a26a40359 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java @@ -110,8 +110,12 @@ public static class User { } public static class ExternalContact { + @Deprecated public static final String GET_EXTERNAL_CONTACT = "/cgi-bin/crm/get_external_contact?external_userid="; - public static final String LIST_EXTERNAL_CONTACT = "/cgi-bin/externalcontact/list?userid="; + @Deprecated public static final String GET_FOLLOW_USER_LIST = "/cgi-bin/externalcontact/get_follow_user_list"; + + public static final String GET_CONTACT_DETAIL = "/cgi-bin/externalcontact/get?external_userid="; + public static final String LIST_EXTERNAL_CONTACT = "/cgi-bin/externalcontact/list?userid="; } } diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java index d39fd6e493..97d8c02ca3 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpExternalContactServiceImplTest.java @@ -42,4 +42,13 @@ public void testListExternalWithPermission() throws WxErrorException { System.out.println(ret); assertNotNull(ret); } + + @Test + public void testGetContactDetail() throws WxErrorException { + String externalUserId = this.configStorage.getExternalUserId(); + WxCpUserExternalContactInfo result = this.wxCpService.getExternalContactService().getContactDetail(externalUserId); + System.out.println(result); + assertNotNull(result); + } + } From 9f33b347406a63ea2a2a86361ecdf3f691c8a115 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 13 Jan 2020 00:13:42 +0800 Subject: [PATCH 0042/1706] =?UTF-8?q?:bookmark:=20=E5=8F=91=E5=B8=833.6.6.?= =?UTF-8?q?B=E6=B5=8B=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 +- spring-boot-starters/pom.xml | 2 +- .../wx-java-miniapp-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-pay-spring-boot-starter/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 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pom.xml b/pom.xml index 4fae139484..fe57185a2b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.github.binarywang wx-java - 3.6.5.B + 3.6.6.B pom WxJava - Weixin/Wechat Java SDK 微信开发Java SDK diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml index ff1ee6524e..7989530367 100644 --- a/spring-boot-starters/pom.xml +++ b/spring-boot-starters/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 3.6.5.B + 3.6.6.B pom wx-java-spring-boot-starters diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml index 2a1f6e4ccf..93dd68f2a2 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.5.B + 3.6.6.B 4.0.0 diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml index 3faf85203b..ab75bdde78 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.5.B + 3.6.6.B 4.0.0 diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml index a887a22651..64e479a292 100644 --- a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.5.B + 3.6.6.B 4.0.0 diff --git a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml index add9b72ad4..135115478a 100644 --- a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.5.B + 3.6.6.B 4.0.0 diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 065d88a8a5..5fdb62f720 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 3.6.5.B + 3.6.6.B weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 6834d22e85..13c1498790 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.5.B + 3.6.6.B weixin-java-cp diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index 8226d27b57..50d9bfcb01 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.5.B + 3.6.6.B weixin-java-miniapp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 703bd5d890..cd96531e0a 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.5.B + 3.6.6.B weixin-java-mp diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index 0922852fb2..abf673bd55 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.5.B + 3.6.6.B weixin-java-open diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index 48c3a47366..cc860e9366 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ com.github.binarywang wx-java - 3.6.5.B + 3.6.6.B 4.0.0 From 75421148e267b9695a2b99df331966b472c54a13 Mon Sep 17 00:00:00 2001 From: yydzxz <79861784@qq.com> Date: Mon, 13 Jan 2020 18:28:08 +0800 Subject: [PATCH 0043/1706] =?UTF-8?q?:art:=20#1377=20=E5=BC=80=E6=94=BE?= =?UTF-8?q?=E5=B9=B3=E5=8F=B0redis=E5=AD=98=E5=82=A8=E7=B1=BB=E8=BF=9B?= =?UTF-8?q?=E8=A1=8C=E6=8A=BD=E8=B1=A1=E9=87=8D=E6=9E=84=EF=BC=8C=E6=96=B9?= =?UTF-8?q?=E4=BE=BF=E6=89=A9=E5=B1=95=EF=BC=8C=E5=B9=B6=E6=8F=90=E4=BE=9B?= =?UTF-8?q?redisson=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 6 + .../wx-java-mp-spring-boot-starter/pom.xml | 5 + .../config/WxMpStorageAutoConfiguration.java | 4 + .../wx-java-open-spring-boot-starter/pom.xml | 5 + .../WxOpenStorageAutoConfiguration.java | 46 +++++- .../open/properties/WxOpenProperties.java | 10 +- weixin-java-open/pom.xml | 4 + .../weixin/open/api/WxOpenConfigStorage.java | 9 ++ .../AbstractWxOpenInRedisConfigStorage.java | 47 +++++++ .../api/impl/WxOpenInMemoryConfigStorage.java | 108 ++------------- .../api/impl/WxOpenInRedisConfigStorage.java | 37 +---- .../impl/WxOpenInRedissonConfigStorage.java | 128 +++++++++++++++++ .../impl/WxOpenInRedisConfigStorageTest.java | 131 ++++++++++++++++++ .../WxOpenInRedissonConfigStorageTest.java | 129 +++++++++++++++++ 14 files changed, 527 insertions(+), 142 deletions(-) create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/AbstractWxOpenInRedisConfigStorage.java create mode 100644 weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInRedissonConfigStorage.java create mode 100644 weixin-java-open/src/test/java/me/chanjar/weixin/open/api/impl/WxOpenInRedisConfigStorageTest.java create mode 100644 weixin-java-open/src/test/java/me/chanjar/weixin/open/api/impl/WxOpenInRedissonConfigStorageTest.java diff --git a/pom.xml b/pom.xml index fe57185a2b..f9d48319b7 100644 --- a/pom.xml +++ b/pom.xml @@ -242,6 +242,12 @@ 2.9.0 provided + + org.redisson + redisson + 3.12.0 + provided + org.projectlombok lombok diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml index ab75bdde78..10ae964974 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml @@ -24,6 +24,11 @@ jedis compile + + org.redisson + redisson + compile + diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpStorageAutoConfiguration.java b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpStorageAutoConfiguration.java index 18024707a4..4ddff5a72a 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpStorageAutoConfiguration.java +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/mp/config/WxMpStorageAutoConfiguration.java @@ -6,6 +6,7 @@ import me.chanjar.weixin.mp.config.WxMpConfigStorage; import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl; +import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; @@ -26,6 +27,9 @@ public class WxMpStorageAutoConfiguration { @Autowired(required = false) private JedisPool jedisPool; + @Autowired(required = false) + private RedissonClient redissonClient; + @Bean @ConditionalOnMissingBean(WxMpConfigStorage.class) public WxMpConfigStorage wxMpInMemoryConfigStorage() { diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml index 64e479a292..55c23378c8 100644 --- a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml @@ -24,6 +24,11 @@ jedis compile + + org.redisson + redisson + compile + diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/config/WxOpenStorageAutoConfiguration.java b/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/config/WxOpenStorageAutoConfiguration.java index 5b57551973..b7afd53249 100644 --- a/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/config/WxOpenStorageAutoConfiguration.java +++ b/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/config/WxOpenStorageAutoConfiguration.java @@ -6,7 +6,12 @@ import me.chanjar.weixin.open.api.WxOpenConfigStorage; import me.chanjar.weixin.open.api.impl.WxOpenInMemoryConfigStorage; import me.chanjar.weixin.open.api.impl.WxOpenInRedisConfigStorage; +import me.chanjar.weixin.open.api.impl.WxOpenInRedissonConfigStorage; import org.apache.commons.lang3.StringUtils; +import org.redisson.Redisson; +import org.redisson.api.RedissonClient; +import org.redisson.config.Config; +import org.redisson.config.TransportMode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -28,6 +33,9 @@ public class WxOpenStorageAutoConfiguration { @Autowired(required = false) private JedisPool jedisPool; + @Autowired(required = false) + private RedissonClient redissonClient; + @Value("${wx.open.config-storage.redis.host:}") private String redisHost; @@ -40,12 +48,20 @@ public WxOpenConfigStorage wxOpenConfigStorage() { if (type == WxOpenProperties.StorageType.redis) { return getWxOpenInRedisConfigStorage(); } + + if (type == WxOpenProperties.StorageType.jedis){ + return getWxOpenInRedisConfigStorage(); + } + + if (type == WxOpenProperties.StorageType.redisson){ + return getWxOpenInRedissonConfigStorage(); + } return getWxOpenInMemoryConfigStorage(); } private WxOpenInMemoryConfigStorage getWxOpenInMemoryConfigStorage() { WxOpenInMemoryConfigStorage config = new WxOpenInMemoryConfigStorage(); - setWxOpenInfo(config); + config.setWxOpenInfo(properties.getAppId(),properties.getSecret(), properties.getToken(), properties.getAesKey()); return config; } @@ -55,17 +71,21 @@ private WxOpenInRedisConfigStorage getWxOpenInRedisConfigStorage() { poolToUse = getJedisPool(); } WxOpenInRedisConfigStorage config = new WxOpenInRedisConfigStorage(poolToUse); - setWxOpenInfo(config); + config.setWxOpenInfo(properties.getAppId(),properties.getSecret(), properties.getToken(), properties.getAesKey()); return config; } - private void setWxOpenInfo(WxOpenConfigStorage config) { - config.setComponentAppId(properties.getAppId()); - config.setComponentAppSecret(properties.getSecret()); - config.setComponentToken(properties.getToken()); - config.setComponentAesKey(properties.getAesKey()); + private WxOpenInRedissonConfigStorage getWxOpenInRedissonConfigStorage(){ + RedissonClient redissonClientToUse = this.redissonClient; + if(redissonClient == null){ + redissonClientToUse = getRedissonClient(); + } + WxOpenInRedissonConfigStorage config = new WxOpenInRedissonConfigStorage(redissonClientToUse); + config.setWxOpenInfo(properties.getAppId(),properties.getSecret(), properties.getToken(), properties.getAesKey()); + return config; } + private JedisPool getJedisPool() { WxOpenProperties.ConfigStorage storage = properties.getConfigStorage(); RedisProperties redis = storage.getRedis(); @@ -90,4 +110,16 @@ private JedisPool getJedisPool() { redis.getTimeout(), redis.getPassword(), redis.getDatabase()); return pool; } + + private RedissonClient getRedissonClient(){ + WxOpenProperties.ConfigStorage storage = properties.getConfigStorage(); + RedisProperties redis = storage.getRedis(); + + Config config = new Config(); + config.useSingleServer() + .setAddress("redis://" + redis.getHost() + ":" + redis.getPort()) + .setPassword(redis.getPassword()); + config.setTransportMode(TransportMode.NIO); + return Redisson.create(config); + } } diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenProperties.java b/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenProperties.java index 64cc3d0672..03e3427ec5 100644 --- a/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenProperties.java +++ b/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenProperties.java @@ -63,6 +63,14 @@ public enum StorageType { /** * redis. */ - redis + redis, + /** + * jedis. + */ + jedis, + /** + * redisson. + */ + redisson } } diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index abf673bd55..2d40676b6e 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -87,6 +87,10 @@ org.projectlombok lombok + + org.redisson + redisson + 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 40833c1b98..79969228ad 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 @@ -128,4 +128,13 @@ public interface WxOpenConfigStorage { * @param expiresInSeconds 过期时间,以秒为单位 */ void updateCardApiTicket(String appId, String cardApiTicket, int expiresInSeconds); + + /** + * 设置第三方平台基础信息 + * @param componentAppId 第三方平台 appid + * @param componentAppSecret 第三方平台 appsecret + * @param componentToken 消息校验Token + * @param componentAesKey 消息加解密Key + */ + void setWxOpenInfo(String componentAppId, String componentAppSecret, String componentToken, String componentAesKey); } diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/AbstractWxOpenInRedisConfigStorage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/AbstractWxOpenInRedisConfigStorage.java new file mode 100644 index 0000000000..0d0b1bf255 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/AbstractWxOpenInRedisConfigStorage.java @@ -0,0 +1,47 @@ +package me.chanjar.weixin.open.api.impl; + + +import org.apache.commons.lang3.StringUtils; + +/** + * @author yangyidian + * @date 2020/01/09 + **/ +public abstract class AbstractWxOpenInRedisConfigStorage extends WxOpenInMemoryConfigStorage { + protected final static String COMPONENT_VERIFY_TICKET_KEY = "wechat_component_verify_ticket:"; + protected final static String COMPONENT_ACCESS_TOKEN_KEY = "wechat_component_access_token:"; + + protected final static String AUTHORIZER_REFRESH_TOKEN_KEY = "wechat_authorizer_refresh_token:"; + protected final static String AUTHORIZER_ACCESS_TOKEN_KEY = "wechat_authorizer_access_token:"; + protected final static String JSAPI_TICKET_KEY = "wechat_jsapi_ticket:"; + protected final static String CARD_API_TICKET_KEY = "wechat_card_api_ticket:"; + + /** + * redis 存储的 key 的前缀,可为空 + */ + protected String keyPrefix; + protected String componentVerifyTicketKey; + protected String componentAccessTokenKey; + protected String authorizerRefreshTokenKey; + protected String authorizerAccessTokenKey; + protected String jsapiTicketKey; + protected String cardApiTicket; + + @Override + public void setComponentAppId(String componentAppId) { + super.setComponentAppId(componentAppId); + String prefix = StringUtils.isBlank(keyPrefix) ? "" : + (StringUtils.endsWith(keyPrefix, ":") ? keyPrefix : (keyPrefix + ":")); + componentVerifyTicketKey = prefix + COMPONENT_VERIFY_TICKET_KEY.concat(componentAppId); + componentAccessTokenKey = prefix + COMPONENT_ACCESS_TOKEN_KEY.concat(componentAppId); + authorizerRefreshTokenKey = prefix + AUTHORIZER_REFRESH_TOKEN_KEY.concat(componentAppId); + authorizerAccessTokenKey = prefix + AUTHORIZER_ACCESS_TOKEN_KEY.concat(componentAppId); + this.jsapiTicketKey = JSAPI_TICKET_KEY.concat(componentAppId); + this.cardApiTicket = CARD_API_TICKET_KEY.concat(componentAppId); + } + + protected String getKey(String prefix, String appId) { + return prefix.endsWith(":") ? prefix.concat(appId) : prefix.concat(":").concat(appId); + } + +} 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 e67cb29e6d..491dc6b7bc 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,6 +2,7 @@ import cn.binarywang.wx.miniapp.config.WxMaConfig; +import lombok.Data; import me.chanjar.weixin.common.bean.WxAccessToken; import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder; import me.chanjar.weixin.mp.bean.WxMpHostConfig; @@ -23,6 +24,7 @@ * * @author 007 */ +@Data public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage { private String componentAppId; private String componentAppSecret; @@ -43,60 +45,7 @@ public class WxOpenInMemoryConfigStorage implements WxOpenConfigStorage { private Map jsapiTickets = new ConcurrentHashMap<>(); private Map cardApiTickets = new ConcurrentHashMap<>(); - @Override - public String getComponentAppId() { - return componentAppId; - } - - @Override - public void setComponentAppId(String componentAppId) { - this.componentAppId = componentAppId; - } - - @Override - public String getComponentAppSecret() { - return componentAppSecret; - } - - @Override - public void setComponentAppSecret(String componentAppSecret) { - this.componentAppSecret = componentAppSecret; - } - - @Override - public String getComponentToken() { - return componentToken; - } - - @Override - public void setComponentToken(String componentToken) { - this.componentToken = componentToken; - } - - @Override - public String getComponentAesKey() { - return componentAesKey; - } - @Override - public void setComponentAesKey(String componentAesKey) { - this.componentAesKey = componentAesKey; - } - - @Override - public String getComponentVerifyTicket() { - return componentVerifyTicket; - } - - @Override - public void setComponentVerifyTicket(String componentVerifyTicket) { - this.componentVerifyTicket = componentVerifyTicket; - } - - @Override - public String getComponentAccessToken() { - return componentAccessToken; - } @Override public boolean isComponentAccessTokenExpired() { @@ -113,51 +62,6 @@ public void updateComponentAccessToken(WxOpenComponentAccessToken componentAcces updateComponentAccessToken(componentAccessToken.getComponentAccessToken(), componentAccessToken.getExpiresIn()); } - @Override - public String getHttpProxyHost() { - return httpProxyHost; - } - - public void setHttpProxyHost(String httpProxyHost) { - this.httpProxyHost = httpProxyHost; - } - - @Override - public int getHttpProxyPort() { - return httpProxyPort; - } - - public void setHttpProxyPort(int httpProxyPort) { - this.httpProxyPort = httpProxyPort; - } - - @Override - public String getHttpProxyUsername() { - return httpProxyUsername; - } - - public void setHttpProxyUsername(String httpProxyUsername) { - this.httpProxyUsername = httpProxyUsername; - } - - @Override - public String getHttpProxyPassword() { - return httpProxyPassword; - } - - public void setHttpProxyPassword(String httpProxyPassword) { - this.httpProxyPassword = httpProxyPassword; - } - - @Override - public ApacheHttpClientBuilder getApacheHttpClientBuilder() { - return apacheHttpClientBuilder; - } - - public ApacheHttpClientBuilder setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { - return this.apacheHttpClientBuilder = apacheHttpClientBuilder; - } - @Override public WxMpConfigStorage getWxMpConfigStorage(String appId) { return new WxOpenInnerConfigStorage(this, appId); @@ -174,6 +78,14 @@ public void updateComponentAccessToken(String componentAccessToken, int expiresI this.componentExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000L; } + @Override + public void setWxOpenInfo(String componentAppId, String componentAppSecret, String componentToken, String componentAesKey) { + setComponentAppId(componentAppId); + setComponentAppSecret(componentAppSecret); + setComponentToken(componentToken); + setComponentAesKey(componentAesKey); + } + @Override public boolean autoRefreshToken() { return true; 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 8962b38c3a..f1b903d472 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 @@ -1,6 +1,5 @@ package me.chanjar.weixin.open.api.impl; -import org.apache.commons.lang3.StringUtils; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.util.Pool; @@ -8,26 +7,9 @@ /** * @author 007 */ -public class WxOpenInRedisConfigStorage extends WxOpenInMemoryConfigStorage { - private final static String COMPONENT_VERIFY_TICKET_KEY = "wechat_component_verify_ticket:"; - private final static String COMPONENT_ACCESS_TOKEN_KEY = "wechat_component_access_token:"; - - private final static String AUTHORIZER_REFRESH_TOKEN_KEY = "wechat_authorizer_refresh_token:"; - private final static String AUTHORIZER_ACCESS_TOKEN_KEY = "wechat_authorizer_access_token:"; - private final static String JSAPI_TICKET_KEY = "wechat_jsapi_ticket:"; - private final static String CARD_API_TICKET_KEY = "wechat_card_api_ticket:"; +public class WxOpenInRedisConfigStorage extends AbstractWxOpenInRedisConfigStorage { protected final Pool jedisPool; - /** - * redis 存储的 key 的前缀,可为空 - */ - private String keyPrefix; - private String componentVerifyTicketKey; - private String componentAccessTokenKey; - private String authorizerRefreshTokenKey; - private String authorizerAccessTokenKey; - private String jsapiTicketKey; - private String cardApiTicket; public WxOpenInRedisConfigStorage(Pool jedisPool) { this.jedisPool = jedisPool; @@ -42,19 +24,6 @@ public WxOpenInRedisConfigStorage(JedisPool jedisPool) { this.jedisPool = jedisPool; } - @Override - public void setComponentAppId(String componentAppId) { - super.setComponentAppId(componentAppId); - String prefix = StringUtils.isBlank(keyPrefix) ? "" : - (StringUtils.endsWith(keyPrefix, ":") ? keyPrefix : (keyPrefix + ":")); - componentVerifyTicketKey = prefix + COMPONENT_VERIFY_TICKET_KEY.concat(componentAppId); - componentAccessTokenKey = prefix + COMPONENT_ACCESS_TOKEN_KEY.concat(componentAppId); - authorizerRefreshTokenKey = prefix + AUTHORIZER_REFRESH_TOKEN_KEY.concat(componentAppId); - authorizerAccessTokenKey = prefix + AUTHORIZER_ACCESS_TOKEN_KEY.concat(componentAppId); - this.jsapiTicketKey = JSAPI_TICKET_KEY.concat(componentAppId); - this.cardApiTicket = CARD_API_TICKET_KEY.concat(componentAppId); - } - @Override public String getComponentVerifyTicket() { try (Jedis jedis = this.jedisPool.getResource()) { @@ -97,10 +66,6 @@ public void updateComponentAccessToken(String componentAccessToken, int expiresI } } - private String getKey(String prefix, String appId) { - return prefix.endsWith(":") ? prefix.concat(appId) : prefix.concat(":").concat(appId); - } - @Override public String getAuthorizerRefreshToken(String appId) { try (Jedis jedis = this.jedisPool.getResource()) { diff --git a/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInRedissonConfigStorage.java b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInRedissonConfigStorage.java new file mode 100644 index 0000000000..7fdf1ba1b6 --- /dev/null +++ b/weixin-java-open/src/main/java/me/chanjar/weixin/open/api/impl/WxOpenInRedissonConfigStorage.java @@ -0,0 +1,128 @@ +package me.chanjar.weixin.open.api.impl; + +import java.util.concurrent.TimeUnit; +import org.redisson.api.RedissonClient; + +/** + * @author yangyidian + * @date 2020/01/06 + **/ +public class WxOpenInRedissonConfigStorage extends AbstractWxOpenInRedisConfigStorage{ + + private RedissonClient redissonClient; + + public WxOpenInRedissonConfigStorage(RedissonClient redissonClient, String keyPrefix) { + this.keyPrefix = keyPrefix; + this.redissonClient = redissonClient; + } + + public WxOpenInRedissonConfigStorage(RedissonClient redissonClient) { + this.redissonClient = redissonClient; + } + + @Override + public String getComponentVerifyTicket() { + Object value = redissonClient.getBucket(this.componentVerifyTicketKey).get(); + return value == null ? null : value.toString(); + } + + @Override + public void setComponentVerifyTicket(String componentVerifyTicket) { + redissonClient.getBucket(this.componentVerifyTicketKey).set(componentVerifyTicket); + } + + @Override + public String getComponentAccessToken() { + Object value = redissonClient.getBucket(this.componentAccessTokenKey).get(); + return value == null ? null : value.toString(); + } + + @Override + public boolean isComponentAccessTokenExpired() { + return redissonClient.getBucket(this.componentAccessTokenKey).remainTimeToLive() < 2; + } + + @Override + public void expireComponentAccessToken() { + redissonClient.getBucket(this.componentAccessTokenKey).expire(0, TimeUnit.SECONDS); + } + + @Override + public void updateComponentAccessToken(String componentAccessToken, int expiresInSeconds) { + redissonClient.getBucket(this.componentAccessTokenKey).set(componentAccessToken, expiresInSeconds - 200, TimeUnit.SECONDS); + } + + @Override + public String getAuthorizerRefreshToken(String appId) { + Object value = redissonClient.getBucket(this.getKey(this.authorizerRefreshTokenKey, appId)).get(); + return value == null ? null : value.toString(); + } + + @Override + public void setAuthorizerRefreshToken(String appId, String authorizerRefreshToken) { + redissonClient.getBucket(this.getKey(this.authorizerRefreshTokenKey, appId)).set(authorizerRefreshToken); + } + + @Override + public String getAuthorizerAccessToken(String appId) { + Object value = redissonClient.getBucket(this.getKey(this.authorizerAccessTokenKey, appId)).get(); + return value == null ? null : value.toString(); + } + + @Override + public boolean isAuthorizerAccessTokenExpired(String appId) { + return redissonClient.getBucket(this.getKey(this.authorizerAccessTokenKey, appId)).remainTimeToLive() < 2; + } + + @Override + public void expireAuthorizerAccessToken(String appId) { + redissonClient.getBucket(this.getKey(this.authorizerAccessTokenKey, appId)).expire(0, TimeUnit.SECONDS); + } + + @Override + public void updateAuthorizerAccessToken(String appId, String authorizerAccessToken, int expiresInSeconds) { + redissonClient.getBucket(this.getKey(this.authorizerAccessTokenKey, appId)).set(authorizerAccessToken, expiresInSeconds - 200, TimeUnit.SECONDS); + } + + @Override + public String getJsapiTicket(String appId) { + Object value = redissonClient.getBucket(this.getKey(this.jsapiTicketKey, appId)).get(); + return value == null ? null : value.toString(); + } + + @Override + public boolean isJsapiTicketExpired(String appId) { + return redissonClient.getBucket(this.getKey(this.jsapiTicketKey, appId)).remainTimeToLive() < 2; + } + + @Override + public void expireJsapiTicket(String appId) { + redissonClient.getBucket(this.getKey(this.jsapiTicketKey, appId)).expire(0, TimeUnit.SECONDS); + } + + @Override + public void updateJsapiTicket(String appId, String jsapiTicket, int expiresInSeconds) { + redissonClient.getBucket(this.getKey(this.jsapiTicketKey, appId)).set(jsapiTicket, expiresInSeconds - 200, TimeUnit.SECONDS); + } + + @Override + public String getCardApiTicket(String appId) { + Object value = redissonClient.getBucket(this.getKey(this.cardApiTicket, appId)).get(); + return value == null ? null : value.toString(); + } + + @Override + public boolean isCardApiTicketExpired(String appId) { + return redissonClient.getBucket(this.getKey(this.cardApiTicket, appId)).remainTimeToLive() < 2; + } + + @Override + public void expireCardApiTicket(String appId) { + redissonClient.getBucket(this.getKey(this.cardApiTicket, appId)).expire(0 ,TimeUnit.SECONDS); + } + + @Override + public void updateCardApiTicket(String appId, String cardApiTicket, int expiresInSeconds) { + redissonClient.getBucket(this.getKey(this.cardApiTicket, appId)).set(cardApiTicket, expiresInSeconds - 200, TimeUnit.SECONDS); + } +} diff --git a/weixin-java-open/src/test/java/me/chanjar/weixin/open/api/impl/WxOpenInRedisConfigStorageTest.java b/weixin-java-open/src/test/java/me/chanjar/weixin/open/api/impl/WxOpenInRedisConfigStorageTest.java new file mode 100644 index 0000000000..26a30a2040 --- /dev/null +++ b/weixin-java-open/src/test/java/me/chanjar/weixin/open/api/impl/WxOpenInRedisConfigStorageTest.java @@ -0,0 +1,131 @@ +package me.chanjar.weixin.open.api.impl; + +import me.chanjar.weixin.open.api.WxOpenConfigStorage; +import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; +import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; +import redis.clients.jedis.JedisPool; + +public class WxOpenInRedisConfigStorageTest { + + private WxOpenConfigStorage wxOpenConfigStorage; + + private JedisPool pool; + + @BeforeClass + public void setWxOpenConfigStorage(){ + pool = new JedisPool("127.0.0.1", 6379); + this.wxOpenConfigStorage = new WxOpenInRedisConfigStorage(pool); + this.wxOpenConfigStorage.setWxOpenInfo("ComponentAppId", "ComponentAppSecret", "ComponentToken","ComponentAesKey"); + this.wxOpenConfigStorage.setComponentVerifyTicket("ComponentVerifyTicket"); + } + + @AfterClass + public void clearResource(){ + pool.close(); + } + + @Test + public void testGetComponentVerifyTicket() { + String componentVerifyTicket = this.wxOpenConfigStorage.getComponentVerifyTicket(); + Assert.assertEquals(componentVerifyTicket, "ComponentVerifyTicket"); + } + + @Test + public void testSetComponentVerifyTicket() { + this.wxOpenConfigStorage.setComponentVerifyTicket("new ComponentVerifyTicket"); + String componentVerifyTicket = this.wxOpenConfigStorage.getComponentVerifyTicket(); + Assert.assertEquals(componentVerifyTicket, "new ComponentVerifyTicket"); + } + + @Test + public void testIsComponentAccessTokenExpired() { + String responseContent = "{\"component_access_token\": \"new componentAccessToken\", \"expires_in\": 10000}"; + WxOpenComponentAccessToken componentAccessToken = WxOpenComponentAccessToken.fromJson(responseContent); + this.wxOpenConfigStorage.updateComponentAccessToken(componentAccessToken); + boolean expired = this.wxOpenConfigStorage.isComponentAccessTokenExpired(); + Assert.assertEquals(expired, false); + + this.wxOpenConfigStorage.expireComponentAccessToken(); + expired = this.wxOpenConfigStorage.isComponentAccessTokenExpired(); + Assert.assertEquals(expired, true); + + } + + @Test + public void testGetAuthorizerRefreshToken() { + String appid = "appid1"; + this.wxOpenConfigStorage.setAuthorizerRefreshToken(appid, "AuthorizerRefreshToken 1"); + String authorizerAccessToken = this.wxOpenConfigStorage.getAuthorizerRefreshToken(appid); + Assert.assertEquals(authorizerAccessToken, "AuthorizerRefreshToken 1"); + + + this.wxOpenConfigStorage.setAuthorizerRefreshToken(appid, "AuthorizerRefreshToken 2"); + authorizerAccessToken = this.wxOpenConfigStorage.getAuthorizerRefreshToken(appid); + Assert.assertEquals(authorizerAccessToken, "AuthorizerRefreshToken 2"); + } + + @Test + public void testGetAuthorizerAccessToken() { + String appid = "appid1"; + String responseContent = "{\"authorizer_access_token\": \"new authorizer_access_token\",\"expires_in\": 100000}"; + WxOpenAuthorizerAccessToken wxOpenAuthorizerAccessToken = WxOpenAuthorizerAccessToken.fromJson(responseContent); + this.wxOpenConfigStorage.updateAuthorizerAccessToken(appid, wxOpenAuthorizerAccessToken); + String authorizerAccessToken = this.wxOpenConfigStorage.getAuthorizerAccessToken(appid); + Assert.assertEquals(authorizerAccessToken, "new authorizer_access_token"); + } + + @Test + public void testIsAuthorizerAccessTokenExpired() { + String appid = "appid1"; + String responseContent = "{\"authorizer_access_token\": \"new authorizer_access_token\",\"expires_in\": 100000}"; + WxOpenAuthorizerAccessToken wxOpenAuthorizerAccessToken = WxOpenAuthorizerAccessToken.fromJson(responseContent); + this.wxOpenConfigStorage.updateAuthorizerAccessToken(appid, wxOpenAuthorizerAccessToken); + String authorizerAccessToken = this.wxOpenConfigStorage.getAuthorizerAccessToken(appid); + Assert.assertEquals(authorizerAccessToken, "new authorizer_access_token"); + + boolean expired = this.wxOpenConfigStorage.isAuthorizerAccessTokenExpired(appid); + Assert.assertEquals(expired, false); + + this.wxOpenConfigStorage.expireAuthorizerAccessToken(appid); + expired = this.wxOpenConfigStorage.isAuthorizerAccessTokenExpired(appid); + Assert.assertEquals(expired, true); + } + + + @Test + public void testGetJsapiTicket() { + String appid = "appid1"; + this.wxOpenConfigStorage.updateJsapiTicket(appid, "jsapiTicket", 100000); + String jsapiTicket = this.wxOpenConfigStorage.getJsapiTicket(appid); + Assert.assertEquals(jsapiTicket, "jsapiTicket"); + + boolean expired = this.wxOpenConfigStorage.isJsapiTicketExpired(appid); + Assert.assertEquals(expired, false); + + this.wxOpenConfigStorage.expireJsapiTicket(appid); + jsapiTicket = this.wxOpenConfigStorage.getJsapiTicket(appid); + Assert.assertEquals(jsapiTicket, null); + + expired = this.wxOpenConfigStorage.isJsapiTicketExpired(appid); + Assert.assertEquals(expired, true); + } + + @Test + public void testGetCardApiTicket() { + String appid = "appid1"; + this.wxOpenConfigStorage.updateCardApiTicket(appid, "new CardApiTicket", 10000); + String cardApiTicket = this.wxOpenConfigStorage.getCardApiTicket(appid); + Assert.assertEquals(cardApiTicket, "new CardApiTicket"); + + boolean expired = this.wxOpenConfigStorage.isCardApiTicketExpired(appid); + Assert.assertEquals(expired, false); + + this.wxOpenConfigStorage.expireCardApiTicket(appid); + expired = this.wxOpenConfigStorage.isCardApiTicketExpired(appid); + Assert.assertEquals(expired, true); + } +} diff --git a/weixin-java-open/src/test/java/me/chanjar/weixin/open/api/impl/WxOpenInRedissonConfigStorageTest.java b/weixin-java-open/src/test/java/me/chanjar/weixin/open/api/impl/WxOpenInRedissonConfigStorageTest.java new file mode 100644 index 0000000000..7168d93f1b --- /dev/null +++ b/weixin-java-open/src/test/java/me/chanjar/weixin/open/api/impl/WxOpenInRedissonConfigStorageTest.java @@ -0,0 +1,129 @@ +package me.chanjar.weixin.open.api.impl; + +import me.chanjar.weixin.open.api.WxOpenConfigStorage; +import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken; +import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken; +import org.redisson.Redisson; +import org.redisson.api.RedissonClient; +import org.redisson.config.Config; +import org.redisson.config.TransportMode; +import org.testng.Assert; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +public class WxOpenInRedissonConfigStorageTest { + + private WxOpenConfigStorage wxOpenConfigStorage; + + @BeforeClass + public void setWxOpenConfigStorage(){ + Config config = new Config(); + config.useSingleServer().setAddress("redis://127.0.0.1:6379") + .setDatabase(0); + config.setTransportMode(TransportMode.NIO); + RedissonClient redisson = Redisson.create(config); + this.wxOpenConfigStorage = new WxOpenInRedissonConfigStorage(redisson); + this.wxOpenConfigStorage.setWxOpenInfo("ComponentAppId", "ComponentAppSecret", "ComponentToken","ComponentAesKey"); + this.wxOpenConfigStorage.setComponentVerifyTicket("ComponentVerifyTicket"); + } + + @Test + public void testGetComponentVerifyTicket() { + String componentVerifyTicket = this.wxOpenConfigStorage.getComponentVerifyTicket(); + Assert.assertEquals(componentVerifyTicket, "ComponentVerifyTicket"); + } + + @Test + public void testSetComponentVerifyTicket() { + this.wxOpenConfigStorage.setComponentVerifyTicket("new ComponentVerifyTicket"); + String componentVerifyTicket = this.wxOpenConfigStorage.getComponentVerifyTicket(); + Assert.assertEquals(componentVerifyTicket, "new ComponentVerifyTicket"); + } + + @Test + public void testIsComponentAccessTokenExpired() { + String responseContent = "{\"component_access_token\": \"new componentAccessToken\", \"expires_in\": 10000}"; + WxOpenComponentAccessToken componentAccessToken = WxOpenComponentAccessToken.fromJson(responseContent); + this.wxOpenConfigStorage.updateComponentAccessToken(componentAccessToken); + boolean expired = this.wxOpenConfigStorage.isComponentAccessTokenExpired(); + Assert.assertEquals(expired, false); + + this.wxOpenConfigStorage.expireComponentAccessToken(); + expired = this.wxOpenConfigStorage.isComponentAccessTokenExpired(); + Assert.assertEquals(expired, true); + + } + + @Test + public void testGetAuthorizerRefreshToken() { + String appid = "appid1"; + this.wxOpenConfigStorage.setAuthorizerRefreshToken(appid, "AuthorizerRefreshToken 1"); + String authorizerAccessToken = this.wxOpenConfigStorage.getAuthorizerRefreshToken(appid); + Assert.assertEquals(authorizerAccessToken, "AuthorizerRefreshToken 1"); + + this.wxOpenConfigStorage.setAuthorizerRefreshToken(appid, "AuthorizerRefreshToken 2"); + authorizerAccessToken = this.wxOpenConfigStorage.getAuthorizerRefreshToken(appid); + Assert.assertEquals(authorizerAccessToken, "AuthorizerRefreshToken 2"); + } + + @Test + public void testGetAuthorizerAccessToken() { + String appid = "appid1"; + String responseContent = "{\"authorizer_access_token\": \"new authorizer_access_token\",\"expires_in\": 100000}"; + WxOpenAuthorizerAccessToken wxOpenAuthorizerAccessToken = WxOpenAuthorizerAccessToken.fromJson(responseContent); + this.wxOpenConfigStorage.updateAuthorizerAccessToken(appid, wxOpenAuthorizerAccessToken); + String authorizerAccessToken = this.wxOpenConfigStorage.getAuthorizerAccessToken(appid); + Assert.assertEquals(authorizerAccessToken, "new authorizer_access_token"); + } + + @Test + public void testIsAuthorizerAccessTokenExpired() { + String appid = "appid1"; + String responseContent = "{\"authorizer_access_token\": \"new authorizer_access_token\",\"expires_in\": 100000}"; + WxOpenAuthorizerAccessToken wxOpenAuthorizerAccessToken = WxOpenAuthorizerAccessToken.fromJson(responseContent); + this.wxOpenConfigStorage.updateAuthorizerAccessToken(appid, wxOpenAuthorizerAccessToken); + String authorizerAccessToken = this.wxOpenConfigStorage.getAuthorizerAccessToken(appid); + Assert.assertEquals(authorizerAccessToken, "new authorizer_access_token"); + + boolean expired = this.wxOpenConfigStorage.isAuthorizerAccessTokenExpired(appid); + Assert.assertEquals(expired, false); + + this.wxOpenConfigStorage.expireAuthorizerAccessToken(appid); + expired = this.wxOpenConfigStorage.isAuthorizerAccessTokenExpired(appid); + Assert.assertEquals(expired, true); + } + + + @Test + public void testGetJsapiTicket() { + String appid = "appid1"; + this.wxOpenConfigStorage.updateJsapiTicket(appid, "jsapiTicket", 100000); + String jsapiTicket = this.wxOpenConfigStorage.getJsapiTicket(appid); + Assert.assertEquals(jsapiTicket, "jsapiTicket"); + + boolean expired = this.wxOpenConfigStorage.isJsapiTicketExpired(appid); + Assert.assertEquals(expired, false); + + this.wxOpenConfigStorage.expireJsapiTicket(appid); + jsapiTicket = this.wxOpenConfigStorage.getJsapiTicket(appid); + Assert.assertEquals(jsapiTicket, null); + + expired = this.wxOpenConfigStorage.isJsapiTicketExpired(appid); + Assert.assertEquals(expired, true); + } + + @Test + public void testGetCardApiTicket() { + String appid = "appid1"; + this.wxOpenConfigStorage.updateCardApiTicket(appid, "new CardApiTicket", 10000); + String cardApiTicket = this.wxOpenConfigStorage.getCardApiTicket(appid); + Assert.assertEquals(cardApiTicket, "new CardApiTicket"); + + boolean expired = this.wxOpenConfigStorage.isCardApiTicketExpired(appid); + Assert.assertEquals(expired, false); + + this.wxOpenConfigStorage.expireCardApiTicket(appid); + expired = this.wxOpenConfigStorage.isCardApiTicketExpired(appid); + Assert.assertEquals(expired, true); + } +} From ac935c5c666bfcb25371589d934305b05f2c6efa Mon Sep 17 00:00:00 2001 From: lixuankun <33336766+lixuankun@users.noreply.github.com> Date: Mon, 13 Jan 2020 18:30:06 +0800 Subject: [PATCH 0044/1706] =?UTF-8?q?:bug:=20#1378=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98=E6=9F=A5=E8=AF=A2=E5=88=86?= =?UTF-8?q?=E8=B4=A6=E6=8E=A5=E5=8F=A3=E6=8A=A5=E7=AD=BE=E5=90=8D=E5=A4=B1?= =?UTF-8?q?=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wxpay/bean/profitsharing/ProfitSharingQueryRequest.java | 5 +++++ .../wxpay/service/impl/ProfitSharingServiceImpl.java | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java index 353170b011..583276f3d7 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java @@ -51,4 +51,9 @@ public class ProfitSharingQueryRequest extends BaseWxPayRequest { protected void checkConstraints() throws WxPayException { this.setSignType(WxPayConstants.SignType.HMAC_SHA256); } + + @Override + public boolean ignoreAppid() { + return true; + } } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/ProfitSharingServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/ProfitSharingServiceImpl.java index 114ae023cd..09e305d19a 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/ProfitSharingServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/ProfitSharingServiceImpl.java @@ -76,7 +76,6 @@ public ProfitSharingReceiverResult removeReceiver(ProfitSharingReceiverRequest r @Override public ProfitSharingQueryResult profitSharingQuery(ProfitSharingQueryRequest request) throws WxPayException { - if (true) throw new WxPayException("暂不支持,微信一直返回签名失败"); request.checkAndSign(this.payService.getConfig()); String url = this.payService.getPayBaseUrl() + "/pay/profitsharingquery"; From 6b3a09a925bcc7fa954c5123c53ccd15d48a60a0 Mon Sep 17 00:00:00 2001 From: S Date: Sun, 19 Jan 2020 11:30:35 +0800 Subject: [PATCH 0045/1706] =?UTF-8?q?:art:=20#1384=20=E5=B0=8F=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F=E4=BD=93=E9=AA=8C=E8=80=85=E6=8E=A5=E5=8F=A3=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E9=94=99=E8=AF=AF=E7=A0=81=EF=BC=8C=E5=90=8C=E6=97=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96WxOpenStorageAutoConfiguration=EF=BC=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0keyPrefix=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * :sparkles: 增加自助核销接口 * :bug: 修改接口路径 * :sparkles: 增加错误码 * :sparkles: 优化 * :sparkles: starter config增加keyPrefix * :sparkles: 修改支付返回结果判断 --- .../WxOpenStorageAutoConfiguration.java | 20 +++++++++---------- .../open/properties/WxOpenProperties.java | 2 ++ .../weixin/common/error/WxMaErrorMsgEnum.java | 11 ++++++++++ 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/config/WxOpenStorageAutoConfiguration.java b/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/config/WxOpenStorageAutoConfiguration.java index b7afd53249..a92b3483b9 100644 --- a/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/config/WxOpenStorageAutoConfiguration.java +++ b/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/config/WxOpenStorageAutoConfiguration.java @@ -49,11 +49,11 @@ public WxOpenConfigStorage wxOpenConfigStorage() { return getWxOpenInRedisConfigStorage(); } - if (type == WxOpenProperties.StorageType.jedis){ + if (type == WxOpenProperties.StorageType.jedis) { return getWxOpenInRedisConfigStorage(); } - if (type == WxOpenProperties.StorageType.redisson){ + if (type == WxOpenProperties.StorageType.redisson) { return getWxOpenInRedissonConfigStorage(); } return getWxOpenInMemoryConfigStorage(); @@ -61,7 +61,7 @@ public WxOpenConfigStorage wxOpenConfigStorage() { private WxOpenInMemoryConfigStorage getWxOpenInMemoryConfigStorage() { WxOpenInMemoryConfigStorage config = new WxOpenInMemoryConfigStorage(); - config.setWxOpenInfo(properties.getAppId(),properties.getSecret(), properties.getToken(), properties.getAesKey()); + config.setWxOpenInfo(properties.getAppId(), properties.getSecret(), properties.getToken(), properties.getAesKey()); return config; } @@ -70,18 +70,18 @@ private WxOpenInRedisConfigStorage getWxOpenInRedisConfigStorage() { if (jedisPool == null || StringUtils.isNotEmpty(redisHost)) { poolToUse = getJedisPool(); } - WxOpenInRedisConfigStorage config = new WxOpenInRedisConfigStorage(poolToUse); - config.setWxOpenInfo(properties.getAppId(),properties.getSecret(), properties.getToken(), properties.getAesKey()); + WxOpenInRedisConfigStorage config = new WxOpenInRedisConfigStorage(poolToUse, properties.getConfigStorage().getKeyPrefix()); + config.setWxOpenInfo(properties.getAppId(), properties.getSecret(), properties.getToken(), properties.getAesKey()); return config; } - private WxOpenInRedissonConfigStorage getWxOpenInRedissonConfigStorage(){ + private WxOpenInRedissonConfigStorage getWxOpenInRedissonConfigStorage() { RedissonClient redissonClientToUse = this.redissonClient; - if(redissonClient == null){ + if (redissonClient == null) { redissonClientToUse = getRedissonClient(); } - WxOpenInRedissonConfigStorage config = new WxOpenInRedissonConfigStorage(redissonClientToUse); - config.setWxOpenInfo(properties.getAppId(),properties.getSecret(), properties.getToken(), properties.getAesKey()); + WxOpenInRedissonConfigStorage config = new WxOpenInRedissonConfigStorage(redissonClientToUse, properties.getConfigStorage().getKeyPrefix()); + config.setWxOpenInfo(properties.getAppId(), properties.getSecret(), properties.getToken(), properties.getAesKey()); return config; } @@ -111,7 +111,7 @@ private JedisPool getJedisPool() { return pool; } - private RedissonClient getRedissonClient(){ + private RedissonClient getRedissonClient() { WxOpenProperties.ConfigStorage storage = properties.getConfigStorage(); RedisProperties redis = storage.getRedis(); diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenProperties.java b/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenProperties.java index 03e3427ec5..77aabad54a 100644 --- a/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenProperties.java +++ b/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java/com/binarywang/spring/starter/wxjava/open/properties/WxOpenProperties.java @@ -53,6 +53,8 @@ public static class ConfigStorage implements Serializable { private RedisProperties redis = new RedisProperties(); + private String keyPrefix; + } public enum StorageType { diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMaErrorMsgEnum.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMaErrorMsgEnum.java index f1ced3fd09..a6fbe052e3 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMaErrorMsgEnum.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMaErrorMsgEnum.java @@ -452,6 +452,17 @@ public enum WxMaErrorMsgEnum { CODE_43101(43101, "用户拒绝接受消息,如果用户之前曾经订阅过,则表示用户取消了订阅关系"), CODE_47003(47003, "模板参数不准确,可能为空或者不满足规则,errmsg会提示具体是哪个字段出错"), + + /** + * 小程序绑定体验者 + */ + CODE_85001(85001, "微信号不存在或微信号设置为不可搜索"), + + CODE_85002(85002, "小程序绑定的体验者数量达到上限"), + + CODE_85003(85003, "微信号绑定的小程序体验者达到上限"), + + CODE_85004(85004, "微信号已经绑定"), ; private int code; From 1a136a2403f8f03e1c4a85f5dfaaa58f135b0448 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 19 Jan 2020 18:10:31 +0800 Subject: [PATCH 0046/1706] =?UTF-8?q?:new:=20#1385=20=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E4=BB=98=E6=AC=BE=E7=A0=81=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E5=AF=B9=E8=B1=A1=E6=B7=BB=E5=8A=A0=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=88=86=E8=B4=A6=E7=9A=84=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wxpay/bean/request/WxPayMicropayRequest.java | 14 +++++++++++++- .../binarywang/wxpay/service/WxPayService.java | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java index 8cec4f0bd7..52ca677231 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java @@ -6,7 +6,7 @@ /** *
- *  提交刷卡支付请求对象类
+ *  提交付款码支付请求对象类
  * Created by Binary Wang on 2017-3-23.
  * 
* @@ -211,6 +211,18 @@ public class WxPayMicropayRequest extends BaseWxPayRequest { @XStreamAlias("scene_info") private String sceneInfo; + /** + *
+   * 字段名:是否指定服务商分账.
+   * 变量名:profit_sharing
+   * 是否必填:否
+   * 详情:Y-是,需要分账  N-否,不分账,字母要求大写,不传默认不分账
+   * 详细参考 https://pay.weixin.qq.com/wiki/doc/api/allocation_sl.php?chapter=24_3&index=3
+   * 
+ */ + @XStreamAlias("profit_sharing") + private String profitSharing; + @Override protected void checkConstraints() { //do nothing 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 3d95148d0f..52f99af6c4 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 @@ -490,7 +490,7 @@ WxPayRefundQueryResult refundQuery(String transactionId, String outTradeNo, Stri /** *
-   * 提交刷卡支付.
+   * 提交付款码支付.
    * 文档地址:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1
    * 应用场景:
    * 收银员使用扫码设备读取微信用户刷卡授权码以后,二维码或条码信息传送至商户收银台,由商户收银台或者商户后台调用该接口发起支付。

From b2ea2fe52a96d89d0b77edeaaf9ad310c0cc74bb Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sun, 19 Jan 2020 18:16:16 +0800
Subject: [PATCH 0047/1706] =?UTF-8?q?:new:=20#1352=20=E5=BE=AE=E4=BF=A1?=
 =?UTF-8?q?=E6=94=AF=E4=BB=98=E4=BB=98=E6=AC=BE=E7=A0=81=E6=94=AF=E4=BB=98?=
 =?UTF-8?q?=E8=AF=B7=E6=B1=82=E5=AF=B9=E8=B1=A1=E5=A2=9E=E5=8A=A0=E5=AE=98?=
 =?UTF-8?q?=E6=96=B9=E6=96=87=E6=A1=A3=E6=96=B0=E6=B7=BB=E5=8A=A0=E7=9A=84?=
 =?UTF-8?q?=E4=B8=A4=E4=B8=AA=E5=8F=82=E6=95=B0=E5=AD=97=E6=AE=B5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../bean/request/WxPayMicropayRequest.java    | 27 +++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java
index 52ca677231..4fb27dd8bf 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java
@@ -19,6 +19,19 @@
 @AllArgsConstructor
 @XStreamAlias("xml")
 public class WxPayMicropayRequest extends BaseWxPayRequest {
+  /**
+   * 
+   * 字段名:设备号.
+   * 变量名:device_info
+   * 是否必填:否
+   * 类型:String(32)
+   * 示例值:013467007045764
+   * 描述:终端设备号(商户自定义,如门店编号)
+   * 
+ */ + @XStreamAlias("device_info") + private String deviceInfo; + /** *
    * 字段名:接口版本号.
@@ -180,6 +193,20 @@ public class WxPayMicropayRequest extends BaseWxPayRequest {
   @XStreamAlias("time_expire")
   private String timeExpire;
 
+  /**
+   * 
+   * 字段名:电子发票入口开放标识	.
+   * 变量名:receipt
+   * 是否必填:否
+   * 类型:String(8)
+   * 示例值:Y
+   * 描述:Y,传入Y时,支付成功消息和支付详情页将出现开票入口。需要在微信支付商户平台或微信公众平台开通电子发票功能,传此字段才可生效
+   * 
+ **/ + @Required + @XStreamAlias("receipt") + private String receipt; + /** *
    * 字段名:授权码.

From 15f7de33f9a47ae75bbccbc49a241c2a24f1941a Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sun, 19 Jan 2020 18:36:06 +0800
Subject: [PATCH 0048/1706] =?UTF-8?q?:bookmark:=20=E5=8F=91=E5=B8=833.6.7.?=
 =?UTF-8?q?B=E6=B5=8B=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 +-
 spring-boot-starters/pom.xml                                    | 2 +-
 .../wx-java-miniapp-spring-boot-starter/pom.xml                 | 2 +-
 spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml     | 2 +-
 spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml   | 2 +-
 spring-boot-starters/wx-java-pay-spring-boot-starter/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 +-
 12 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/pom.xml b/pom.xml
index f9d48319b7..0c59ce8784 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
   4.0.0
   com.github.binarywang
   wx-java
-  3.6.6.B
+  3.6.7.B
   pom
   WxJava - Weixin/Wechat Java SDK
   微信开发Java SDK
diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml
index 7989530367..b5952c3516 100644
--- a/spring-boot-starters/pom.xml
+++ b/spring-boot-starters/pom.xml
@@ -6,7 +6,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.6.B
+    3.6.7.B
   
   pom
   wx-java-spring-boot-starters
diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml
index 93dd68f2a2..fe7e70f2e4 100644
--- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
   
     wx-java-spring-boot-starters
     com.github.binarywang
-    3.6.6.B
+    3.6.7.B
   
   4.0.0
 
diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml
index 10ae964974..811ca73ef7 100644
--- a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
   
     wx-java-spring-boot-starters
     com.github.binarywang
-    3.6.6.B
+    3.6.7.B
   
   4.0.0
 
diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml
index 55c23378c8..a56def678f 100644
--- a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
   
     wx-java-spring-boot-starters
     com.github.binarywang
-    3.6.6.B
+    3.6.7.B
   
   4.0.0
 
diff --git a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml
index 135115478a..89c2a6d73e 100644
--- a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml
+++ b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml
@@ -5,7 +5,7 @@
   
     wx-java-spring-boot-starters
     com.github.binarywang
-    3.6.6.B
+    3.6.7.B
   
   4.0.0
 
diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml
index 5fdb62f720..e67c4ac84d 100644
--- a/weixin-java-common/pom.xml
+++ b/weixin-java-common/pom.xml
@@ -6,7 +6,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.6.B
+    3.6.7.B
   
 
   weixin-java-common
diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml
index 13c1498790..0ea2cfb523 100644
--- a/weixin-java-cp/pom.xml
+++ b/weixin-java-cp/pom.xml
@@ -7,7 +7,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.6.B
+    3.6.7.B
   
 
   weixin-java-cp
diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml
index 50d9bfcb01..9c555a58dd 100644
--- a/weixin-java-miniapp/pom.xml
+++ b/weixin-java-miniapp/pom.xml
@@ -7,7 +7,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.6.B
+    3.6.7.B
   
 
   weixin-java-miniapp
diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml
index cd96531e0a..2cbf9967ed 100644
--- a/weixin-java-mp/pom.xml
+++ b/weixin-java-mp/pom.xml
@@ -7,7 +7,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.6.B
+    3.6.7.B
   
 
   weixin-java-mp
diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml
index 2d40676b6e..150cb7b38a 100644
--- a/weixin-java-open/pom.xml
+++ b/weixin-java-open/pom.xml
@@ -7,7 +7,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.6.B
+    3.6.7.B
   
 
   weixin-java-open
diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml
index cc860e9366..2b28f5c24b 100644
--- a/weixin-java-pay/pom.xml
+++ b/weixin-java-pay/pom.xml
@@ -5,7 +5,7 @@
   
     com.github.binarywang
     wx-java
-    3.6.6.B
+    3.6.7.B
   
   4.0.0
 

From ccb25345ff650eda20cb155e67f9356287cb2d08 Mon Sep 17 00:00:00 2001
From: outersky 
Date: Tue, 28 Jan 2020 20:21:06 +0800
Subject: [PATCH 0049/1706] =?UTF-8?q?:art:=20#1390=20=E5=BE=AE=E4=BF=A1?=
 =?UTF-8?q?=E6=94=AF=E4=BB=98=E5=A2=9E=E5=8A=A0XML=E8=BD=AC=E6=8D=A2?=
 =?UTF-8?q?=E7=9A=84=E5=BF=AB=E9=80=9F=E6=A8=A1=E5=BC=8F=EF=BC=8C=E5=8F=91?=
 =?UTF-8?q?=E9=80=81=E8=AF=B7=E6=B1=82=E4=BB=A5=E5=8F=8A=E7=BB=84=E8=A3=85?=
 =?UTF-8?q?=E5=93=8D=E5=BA=94=E5=AF=B9=E8=B1=A1=E7=9A=84=E6=97=B6=E5=80=99?=
 =?UTF-8?q?=E4=B8=8D=E5=86=8D=E4=BE=9D=E8=B5=96=E5=8F=8D=E5=B0=84=E6=9C=BA?=
 =?UTF-8?q?=E5=88=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* 增加XML的快速模式,发送请求以及组装响应对象的时候,不再依赖java的反射机制。
1:提升性能
2:可以通过 graalvm 生成native image.

本次完成:全部BaseWxPayRequest的改造,部分BaseWxPayResult子类的改造。

* clean code

* 标记 xmlDoc 为 transient 否则toString()方法中Gson可能会堆栈溢出

* 完成大多数BaseWxPayResult子类的改造。还有 notify.*Result下面留了两个TODO需要处理。

* toXML时遗漏了sign参数

* 使用dom4j简化了toXML,同时根据本版本构建native-image的demo已经提交: https://github.com/outersky/wx-micronaut-graal.git 供参考。

* 完成了最后两个Result的xml解析。
---
 .../coupon/WxPayCouponInfoQueryRequest.java   | 13 +++
 .../coupon/WxPayCouponInfoQueryResult.java    | 20 ++++
 .../bean/coupon/WxPayCouponSendRequest.java   | 14 +++
 .../bean/coupon/WxPayCouponSendResult.java    | 13 +++
 .../coupon/WxPayCouponStockQueryRequest.java  | 11 +++
 .../coupon/WxPayCouponStockQueryResult.java   | 17 ++++
 .../bean/entpay/EntPayBankQueryResult.java    | 14 +++
 .../wxpay/bean/entpay/EntPayBankRequest.java  | 12 +++
 .../wxpay/bean/entpay/EntPayBankResult.java   |  8 ++
 .../wxpay/bean/entpay/EntPayQueryRequest.java |  7 ++
 .../wxpay/bean/entpay/EntPayQueryResult.java  | 14 +++
 .../entpay/EntPayRedpackQueryRequest.java     |  8 ++
 .../bean/entpay/EntPayRedpackQueryResult.java | 21 ++++
 .../bean/entpay/EntPayRedpackRequest.java     | 18 ++++
 .../bean/entpay/EntPayRedpackResult.java      | 13 +++
 .../wxpay/bean/entpay/EntPayRequest.java      | 16 ++++
 .../wxpay/bean/entpay/EntPayResult.java       | 10 ++
 .../wxpay/bean/entpay/GetPublicKeyResult.java |  7 ++
 .../bean/notify/WxPayOrderNotifyResult.java   | 47 +++++++++
 .../bean/notify/WxPayRefundNotifyResult.java  | 57 +++++++++++
 .../bean/notify/WxScanPayNotifyResult.java    |  8 ++
 .../ProfitSharingFinishRequest.java           |  9 ++
 .../ProfitSharingQueryRequest.java            |  8 ++
 .../ProfitSharingQueryResult.java             | 13 +++
 .../ProfitSharingReceiverRequest.java         |  7 ++
 .../ProfitSharingReceiverResult.java          |  6 ++
 .../profitsharing/ProfitSharingRequest.java   |  9 ++
 .../profitsharing/ProfitSharingResult.java    |  8 ++
 .../ProfitSharingReturnQueryRequest.java      |  9 ++
 .../ProfitSharingReturnRequest.java           | 13 +++
 .../ProfitSharingReturnResult.java            | 16 ++++
 .../wxpay/bean/request/BaseWxPayRequest.java  | 76 ++++++++++++++-
 .../request/WxPayAuthcode2OpenidRequest.java  |  8 ++
 .../bean/request/WxPayDefaultRequest.java     |  6 ++
 .../request/WxPayDownloadBillRequest.java     | 10 ++
 .../request/WxPayDownloadFundFlowRequest.java |  8 ++
 .../request/WxPayFaceAuthInfoRequest.java     | 13 +++
 .../bean/request/WxPayFacepayRequest.java     | 17 ++++
 .../bean/request/WxPayMicropayRequest.java    | 20 ++++
 .../bean/request/WxPayOrderCloseRequest.java  |  8 ++
 .../bean/request/WxPayOrderQueryRequest.java  | 10 ++
 .../request/WxPayOrderReverseRequest.java     |  8 ++
 .../request/WxPayQueryCommentRequest.java     | 12 +++
 .../request/WxPayRedpackQueryRequest.java     | 11 ++-
 .../bean/request/WxPayRefundQueryRequest.java | 11 +++
 .../bean/request/WxPayRefundRequest.java      | 18 +++-
 .../bean/request/WxPayReportRequest.java      | 17 ++++
 .../WxPaySendMiniProgramRedpackRequest.java   | 17 ++++
 .../bean/request/WxPaySendRedpackRequest.java | 16 ++++
 .../bean/request/WxPayShorturlRequest.java    |  7 ++
 .../request/WxPayUnifiedOrderRequest.java     | 28 ++++++
 .../wxpay/bean/result/BaseWxPayResult.java    | 95 +++++++++++++++++--
 .../result/WxPayAuthcode2OpenidResult.java    | 11 +++
 .../wxpay/bean/result/WxPayCommonResult.java  |  4 +
 .../bean/result/WxPayFaceAuthInfoResult.java  | 12 +++
 .../wxpay/bean/result/WxPayFacepayResult.java | 27 ++++++
 .../bean/result/WxPayMicropayResult.java      | 25 +++++
 .../bean/result/WxPayOrderCloseResult.java    | 11 +++
 .../bean/result/WxPayOrderQueryResult.java    | 27 +++++-
 .../bean/result/WxPayOrderReverseResult.java  | 11 +++
 .../bean/result/WxPayRedpackQueryResult.java  | 41 ++++++++
 .../bean/result/WxPayRefundQueryResult.java   | 18 ++++
 .../wxpay/bean/result/WxPayRefundResult.java  | 29 +++++-
 .../result/WxPaySandboxSignKeyResult.java     | 11 +++
 .../WxPaySendMiniProgramRedpackResult.java    | 10 ++
 .../bean/result/WxPaySendRedpackResult.java   | 16 ++++
 .../bean/result/WxPayShorturlResult.java      | 11 +++
 .../bean/result/WxPayUnifiedOrderResult.java  | 14 +++
 .../service/impl/BaseWxPayServiceImpl.java    | 12 ++-
 .../binarywang/wxpay/util/SignUtils.java      | 36 ++++---
 .../binarywang/wxpay/util/XmlConfig.java      | 23 +++++
 .../notify/WxPayOrderNotifyResultTest.java    | 23 +++++
 .../notify/WxPayRefundNotifyResultTest.java   | 48 ++++++++++
 .../notify/WxScanPayNotifyResultTest.java     | 35 +++++++
 .../result/WxPayRedpackQueryResultTest.java   | 66 ++++++++++++-
 .../bean/result/WxPayRefundResultTest.java    | 61 +++++++++++-
 .../impl/BaseWxPayServiceImplTest.java        | 13 ++-
 77 files changed, 1420 insertions(+), 37 deletions(-)
 create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/XmlConfig.java

diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryRequest.java
index 61726e0405..539ad988b9 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryRequest.java
@@ -5,6 +5,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 
  * 查询代金券信息请求对象类
@@ -120,4 +122,15 @@ protected void checkConstraints() {
     //do nothing
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("coupon_id", couponId);
+    map.put("stock_id", stockId);
+    map.put("openid", openid);
+    map.put("op_user_id", opUserId);
+    map.put("device_info", deviceInfo);
+    map.put("version", version);
+    map.put("type", type);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryResult.java
index cab25062af..9001541b7a 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponInfoQueryResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -227,4 +228,23 @@ public class WxPayCouponInfoQueryResult extends BaseWxPayResult {
   @XStreamAlias("is_partial_use")
   private String isPartialUse;
 
+  @Override
+  protected void loadXML(Document d) {
+    deviceInfo = readXMLString(d, "device_info");
+    couponStockId = readXMLString(d, "coupon_stock_id");
+    couponId = readXMLString(d, "coupon_id");
+    couponValue = readXMLInteger(d, "coupon_value");
+    couponMinimum = readXMLInteger(d, "coupon_minimum");
+    couponName = readXMLString(d, "coupon_name");
+    couponState = readXMLString(d, "coupon_state");
+    couponDesc = readXMLString(d, "coupon_desc");
+    couponUseValue = readXMLInteger(d, "coupon_use_value");
+    couponRemainValue = readXMLInteger(d, "coupon_remain_value");
+    beginTime = readXMLString(d, "begin_time");
+    endTime = readXMLString(d, "end_time");
+    sendTime = readXMLString(d, "send_time");
+    consumerMchId = readXMLString(d, "consumer_mch_id");
+    sendSource = readXMLString(d, "send_source");
+    isPartialUse = readXMLString(d, "is_partial_use");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendRequest.java
index 5fa6da7de2..a43ce51d99 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendRequest.java
@@ -5,6 +5,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 
  * 发送代金券请求对象类
@@ -132,4 +134,16 @@ public class WxPayCouponSendRequest extends BaseWxPayRequest {
   protected void checkConstraints() {
     //do nothing
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("coupon_stock_id", couponStockId);
+    map.put("openid_count", openidCount.toString());
+    map.put("partner_trade_no", partnerTradeNo);
+    map.put("openid", openid);
+    map.put("op_user_id", opUserId);
+    map.put("device_info", deviceInfo);
+    map.put("version", version);
+    map.put("type", type);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendResult.java
index 314845e46e..9350e58847 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponSendResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -136,4 +137,16 @@ public class WxPayCouponSendResult extends BaseWxPayResult {
   @XStreamAlias("ret_msg")
   private String retMsg;
 
+  @Override
+  protected void loadXML(Document d) {
+    deviceInfo = readXMLString(d, "device_info");
+    couponStockId = readXMLString(d, "coupon_stock_id");
+    respCount = readXMLInteger(d, "resp_count");
+    successCount = readXMLInteger(d, "success_count");
+    failedCount = readXMLInteger(d, "failed_count");
+    openid = readXMLString(d, "openid");
+    retCode = readXMLString(d, "ret_code");
+    couponId = readXMLString(d, "coupon_id");
+    retMsg = readXMLString(d, "ret_msg");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryRequest.java
index b8a78b40bf..bae6a563ea 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryRequest.java
@@ -5,6 +5,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 
  * 查询代金券批次请求对象类
@@ -91,4 +93,13 @@ protected void checkConstraints() {
     //do nothing
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("coupon_stock_id", couponStockId);
+    map.put("op_user_id", opUserId);
+    map.put("device_info", deviceInfo);
+    map.put("version", version);
+    map.put("type", type);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryResult.java
index f3e91d030b..b338f4081b 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/coupon/WxPayCouponStockQueryResult.java
@@ -6,6 +6,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -191,4 +192,20 @@ public class WxPayCouponStockQueryResult extends BaseWxPayResult {
   @XStreamAlias("coupon_budget")
   private Integer couponBudget;
 
+  @Override
+  protected void loadXML(Document d) {
+    deviceInfo = readXMLString(d, "device_info");
+    couponStockId = readXMLString(d, "coupon_stock_id");
+    couponName = readXMLString(d, "coupon_name");
+    couponValue = readXMLInteger(d, "coupon_value");
+    couponMinimum = readXMLInteger(d, "coupon_mininumn");
+    couponStockStatus = readXMLInteger(d, "coupon_stock_status");
+    couponTotal = readXMLInteger(d, "coupon_total");
+    maxQuota = readXMLInteger(d, "max_quota");
+    isSendNum = readXMLInteger(d, "is_send_num");
+    beginTime = readXMLString(d, "begin_time");
+    endTime = readXMLString(d, "end_time");
+    createTime = readXMLString(d, "create_time");
+    couponBudget = readXMLInteger(d, "coupon_budget");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankQueryResult.java
index 6020dbed77..72adc1c9aa 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankQueryResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -93,4 +94,17 @@ public class EntPayBankQueryResult extends BaseWxPayResult {
   @XStreamAlias("reason")
   private String failReason;
 
+  @Override
+  protected void loadXML(Document d) {
+    partnerTradeNo = readXMLString(d, "partner_trade_no");
+    paymentNo = readXMLString(d, "payment_no");
+    bankNoMd5 = readXMLString(d, "bank_no_md5");
+    trueNameMd5 = readXMLString(d, "true_name_md5");
+    amount = readXMLInteger(d, "amount");
+    status = readXMLString(d, "status");
+    cmmsAmount = readXMLInteger(d, "cmms_amt");
+    createTime = readXMLString(d, "create_time");
+    paySuccessTime = readXMLString(d, "pay_succ_time");
+    failReason = readXMLString(d, "reason");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankRequest.java
index 05ccebc23c..04c26403c2 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankRequest.java
@@ -10,6 +10,8 @@
 import lombok.NoArgsConstructor;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 
  *  企业付款到银行卡的请求对象类
@@ -121,6 +123,16 @@ protected String[] getIgnoredParamsForSign() {
     return new String[]{"sign_type"};
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("partner_trade_no", partnerTradeNo);
+    map.put("enc_bank_no", encBankNo);
+    map.put("enc_true_name", encTrueName);
+    map.put("bank_code", bankCode);
+    map.put("amount", amount.toString());
+    map.put("desc", description);
+  }
+
   @Override
   protected boolean ignoreAppid() {
     return true;
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankResult.java
index 078e27e849..0d38645afe 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayBankResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -48,4 +49,11 @@ public class EntPayBankResult extends BaseWxPayResult {
   @XStreamAlias("cmms_amt")
   private Integer cmmsAmount;
 
+  @Override
+  protected void loadXML(Document d) {
+    amount = readXMLInteger(d, "amount");
+    partnerTradeNo = readXMLString(d, "partner_trade_no");
+    paymentNo = readXMLString(d, "payment_no");
+    cmmsAmount = readXMLInteger(d, "cmms_amt");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryRequest.java
index 21de8fca35..779d59823b 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryRequest.java
@@ -10,6 +10,8 @@
 import me.chanjar.weixin.common.annotation.Required;
 import me.chanjar.weixin.common.util.json.WxGsonBuilder;
 
+import java.util.Map;
+
 /**
  * 
  * 企业付款请求对象.
@@ -55,4 +57,9 @@ public String toString() {
   protected String[] getIgnoredParamsForSign() {
     return new String[]{"sign_type"};
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("partner_trade_no", partnerTradeNo);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryResult.java
index e9f6d2213f..6dee1d0911 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayQueryResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -81,4 +82,17 @@ public class EntPayQueryResult extends BaseWxPayResult {
   @XStreamAlias("desc")
   private String desc;
 
+  @Override
+  protected void loadXML(Document d) {
+    partnerTradeNo = readXMLString(d, "partner_trade_no");
+    detailId = readXMLString(d, "detail_id");
+    status = readXMLString(d, "status");
+    reason = readXMLString(d, "reason");
+    openid = readXMLString(d, "openid");
+    transferName = readXMLString(d, "transfer_name");
+    paymentAmount = readXMLInteger(d, "payment_amount");
+    transferTime = readXMLString(d, "transfer_time");
+    paymentTime = readXMLString(d, "payment_time");
+    desc = readXMLString(d, "desc");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryRequest.java
index 29fc517f00..74e5b4b1a0 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryRequest.java
@@ -5,8 +5,11 @@
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.*;
 
+import java.util.Map;
+
 /**
  * 红包发送记录查询请求
+ *
  * @author wuyong
  * @date 2019-12-01 17:19
  */
@@ -30,4 +33,9 @@ public class EntPayRedpackQueryRequest extends BaseWxPayRequest {
   protected void checkConstraints() throws WxPayException {
 
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("mch_billno", mchBillNo);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryResult.java
index 1235fe1bd4..000498519f 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackQueryResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 红包发送记录查询返回
@@ -130,4 +131,24 @@ public class EntPayRedpackQueryResult extends BaseWxPayResult {
   @XStreamAlias("sender_header_media_id")
   private Integer senderHeaderMediaId;
 
+  @Override
+  protected void loadXML(Document d) {
+    mchBillNo = readXMLString(d, "mch_billno");
+    detailId = readXMLString(d, "detailId");
+    status = readXMLString(d, "status");
+    sendType = readXMLString(d, "send_type");
+    totalAmount = readXMLInteger(d, "total_amount");
+    reason = readXMLInteger(d, "reason");
+    sendTime = readXMLString(d, "send_time");
+    refundTime = readXMLString(d, "refund_time");
+    refundAmount = readXMLInteger(d, "refund_amount");
+    wishing = readXMLString(d, "wishing");
+    remark = readXMLString(d, "remark");
+    actName = readXMLString(d, "act_name");
+    openid = readXMLString(d, "openid");
+    amount = readXMLInteger(d, "amount");
+    rcvTime = readXMLInteger(d, "rcv_time");
+    senderName = readXMLInteger(d, "sender_name");
+    senderHeaderMediaId = readXMLInteger(d, "sender_header_media_id");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackRequest.java
index 0ab8bddab5..762499e693 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackRequest.java
@@ -6,8 +6,11 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 发送企业红包
+ *
  * @author wuyong
  * @date 2019-12-1
  */
@@ -144,4 +147,19 @@ protected boolean ignoreSubMchId() {
   protected boolean isWxWorkSign() {
     return true;
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("mch_billno", mchBillNo);
+    map.put("wxappid", wxAppId);
+    map.put("sender_name", senderName);
+    map.put("agentid", agentId);
+    map.put("sender_header_media_id", senderHeaderMediaId);
+    map.put("re_openid", reOpenid);
+    map.put("total_amount", totalAmount.toString());
+    map.put("wishing", wishing);
+    map.put("act_name", actName);
+    map.put("remark", remark);
+    map.put("scene_id", sceneId);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackResult.java
index 677ac88f89..98cce357c9 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRedpackResult.java
@@ -5,11 +5,13 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 import java.io.Serializable;
 
 /**
  * 企业微信红包返回
+ *
  * @author wuyong
  * @date 2019-12-01 11:31
  */
@@ -77,4 +79,15 @@ public class EntPayRedpackResult extends BaseWxPayResult implements Serializable
   @XStreamAlias("sender_header_media_id")
   private String senderHeaderMediaId;
 
+  @Override
+  protected void loadXML(Document d) {
+    mchBillNo = readXMLString(d, "mch_billno");
+    mchId = readXMLString(d, "mch_id");
+    wxAppId = readXMLString(d, "wxappid");
+    reOpenid = readXMLString(d, "re_openid");
+    totalAmount = readXMLString(d, "totalAmount");
+    sendListId = readXMLString(d, "sendListid");
+    senderName = readXMLString(d, "sender_name");
+    senderHeaderMediaId = readXMLString(d, "sender_header_media_id");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRequest.java
index 24c1c185ac..6f89254714 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayRequest.java
@@ -10,6 +10,8 @@
 import me.chanjar.weixin.common.annotation.Required;
 import me.chanjar.weixin.common.util.json.WxGsonBuilder;
 
+import java.util.Map;
+
 /**
  * 
  * 企业付款请求对象.
@@ -195,4 +197,18 @@ public void setMchId(String mchId) {
   protected String[] getIgnoredParamsForSign() {
     return new String[]{"sign_type"};
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("mch_appid", mchAppid);
+    map.put("mchid", mchId);
+    map.put("device_info", deviceInfo);
+    map.put("partner_trade_no", partnerTradeNo);
+    map.put("openid", openid);
+    map.put("check_name", checkName);
+    map.put("re_user_name", reUserName);
+    map.put("amount", amount.toString());
+    map.put("desc", description);
+    map.put("spbill_create_ip", spbillCreateIp);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayResult.java
index 223c196395..9863e83bcc 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -56,4 +57,13 @@ public class EntPayResult extends BaseWxPayResult {
   @XStreamAlias("payment_time")
   private String paymentTime;
 
+  @Override
+  protected void loadXML(Document d) {
+    mchId = readXMLString(d, "mchid");
+    mchAppid = readXMLString(d, "mch_appid");
+    deviceInfo = readXMLString(d, "device_info");
+    partnerTradeNo = readXMLString(d, "partner_trade_no");
+    paymentNo = readXMLString(d, "payment_no");
+    paymentTime = readXMLString(d, "payment_time");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/GetPublicKeyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/GetPublicKeyResult.java
index f7f62afb7e..2a9cc8c6ad 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/GetPublicKeyResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/GetPublicKeyResult.java
@@ -4,6 +4,7 @@
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -28,4 +29,10 @@ public class GetPublicKeyResult extends BaseWxPayResult {
    */
   @XStreamAlias("pub_key")
   private String pubKey;
+
+  @Override
+  protected void loadXML(Document d) {
+    mchId = readXMLString(d, "mch_id");
+    pubKey = readXMLString(d, "pub_key");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResult.java
index 93fb4b2705..b1a8fe9d2d 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResult.java
@@ -13,7 +13,9 @@
 import lombok.NoArgsConstructor;
 import me.chanjar.weixin.common.util.json.WxGsonBuilder;
 import me.chanjar.weixin.common.util.xml.XStreamInitializer;
+import org.w3c.dom.Document;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
@@ -349,6 +351,51 @@ public Map toMap() {
     return resultMap;
   }
 
+  @Override
+  protected void loadXML(Document d) {
+    promotionDetail = readXMLString(d, "promotion_detail");
+    deviceInfo = readXMLString(d, "device_info");
+    openid = readXMLString(d, "openid");
+    isSubscribe = readXMLString(d, "is_subscribe");
+    subOpenid = readXMLString(d, "sub_openid");
+    subIsSubscribe = readXMLString(d, "sub_is_subscribe");
+    tradeType = readXMLString(d, "trade_type");
+    bankType = readXMLString(d, "bank_type");
+    totalFee = readXMLInteger(d, "total_fee");
+    settlementTotalFee = readXMLInteger(d, "settlement_total_fee");
+    feeType = readXMLString(d, "fee_type");
+    cashFee = readXMLInteger(d, "cash_fee");
+    cashFeeType = readXMLString(d, "cash_fee_type");
+    couponFee = readXMLInteger(d, "coupon_fee");
+    couponCount = readXMLInteger(d, "coupon_count");
+    transactionId = readXMLString(d, "transaction_id");
+    outTradeNo = readXMLString(d, "out_trade_no");
+    attach = readXMLString(d, "attach");
+    timeEnd = readXMLString(d, "time_end");
+    version = readXMLString(d, "version");
+    rateValue = readXMLString(d, "rate_value");
+    signType = readXMLString(d, "sign_type");
+
+    composeCoupons();
+  }
+
+  /**
+   * 通过xml组装couponList属性内容.
+   */
+  protected void composeCoupons() {
+    if (this.couponCount == null || this.couponCount == 0) {
+      return;
+    }
+    this.couponList = new ArrayList(couponCount);
+    for (int i = 0; i < this.couponCount; i++) {
+      WxPayOrderNotifyCoupon coupon = new WxPayOrderNotifyCoupon();
+      coupon.setCouponId(this.getXmlValue("xml/coupon_id_" + i));
+      coupon.setCouponType(this.getXmlValue("xml/coupon_type_" + i));
+      coupon.setCouponFee(this.getXmlValueAsInt("xml/coupon_fee_" + i));
+      couponList.add(coupon);
+    }
+  }
+
   @Override
   public String toString() {
     return WxGsonBuilder.create().toJson(this);
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 ad56852824..d9f4cbd5f8 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
@@ -19,6 +19,7 @@
 import lombok.NoArgsConstructor;
 import me.chanjar.weixin.common.util.json.WxGsonBuilder;
 import me.chanjar.weixin.common.util.xml.XStreamInitializer;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -80,6 +81,45 @@ public static WxPayRefundNotifyResult fromXML(String xmlString, String mchKey) t
 
   private ReqInfo reqInfo;
 
+  // 解密后的reqInfo 字符串
+  private transient String decryptedReqInfo;
+
+  @Override
+  protected void loadXML(Document d) {
+    reqInfoString = readXMLString(d, "req_info");
+  }
+
+  /**
+   * 解密并解析reqInfo
+   *
+   * @param mchKey
+   * @throws WxPayException
+   */
+  public void decryptReqInfo(String mchKey) throws WxPayException {
+    //如果是失败,直接返回,不用解析
+    if (WxPayConstants.ResultCode.FAIL.equals(getReturnCode())) {
+      return;
+    }
+    try {
+      final String keyMd5String = DigestUtils.md5Hex(mchKey).toLowerCase();
+      SecretKeySpec key = new SecretKeySpec(keyMd5String.getBytes(StandardCharsets.UTF_8), "AES");
+
+      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+      cipher.init(Cipher.DECRYPT_MODE, key);
+      decryptedReqInfo = new String(cipher.doFinal(Base64.decodeBase64(reqInfoString)), StandardCharsets.UTF_8);
+      loadReqInfo(decryptedReqInfo);
+    } catch (Exception e) {
+      throw new WxPayException("解密退款通知加密信息时出错", e);
+    }
+  }
+
+  // 本方法独立出来方便测试
+  protected void loadReqInfo(String decryptedReqInfo) {
+    Document document = openXML(decryptedReqInfo);
+    reqInfo = new ReqInfo();
+    reqInfo.loadXML(document);
+  }
+
   /**
    * 加密信息字段解密后的内容.
    */
@@ -272,6 +312,23 @@ public static ReqInfo fromXML(String xmlString) {
       xstream.processAnnotations(ReqInfo.class);
       return (ReqInfo) xstream.fromXML(xmlString);
     }
+
+    public void loadXML(Document d) {
+      transactionId = readXMLString(d, "transaction_id");
+      outTradeNo = readXMLString(d, "out_trade_no");
+      refundId = readXMLString(d, "refund_id");
+      outRefundNo = readXMLString(d, "out_refund_no");
+      totalFee = readXMLInteger(d, "total_fee");
+      settlementTotalFee = readXMLInteger(d, "settlement_total_fee");
+      refundFee = readXMLInteger(d, "refund_fee");
+      settlementRefundFee = readXMLInteger(d, "settlement_refund_fee");
+      refundStatus = readXMLString(d, "refund_status");
+      successTime = readXMLString(d, "success_time");
+      refundRecvAccout = readXMLString(d, "refund_recv_accout");
+      refundAccount = readXMLString(d, "refund_account");
+      refundRequestSource = readXMLString(d, "refund_request_source");
+    }
   }
 
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResult.java
index a87adabedd..9c9c451372 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -45,4 +46,11 @@ public class WxScanPayNotifyResult extends BaseWxPayResult {
   @XStreamAlias("product_id")
   private String productId;
 
+  @Override
+  protected void loadXML(Document d) {
+    openid = readXMLString(d, "openid");
+    isSubscribe = readXMLString(d, "is_subscribe");
+    productId = readXMLString(d, "product_id");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingFinishRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingFinishRequest.java
index 22cd545083..3a0ee93648 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingFinishRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingFinishRequest.java
@@ -7,6 +7,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * @author Wang GuangXin 2019/10/23 14:02
  * @version 1.0
@@ -67,4 +69,11 @@ public class ProfitSharingFinishRequest extends BaseWxPayRequest {
   protected void checkConstraints() throws WxPayException {
     this.setSignType(WxPayConstants.SignType.HMAC_SHA256);
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("transaction_id", transactionId);
+    map.put("out_order_no", outOrderNo);
+    map.put("description", description);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java
index 583276f3d7..c4009858cb 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java
@@ -7,6 +7,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * @author Wang GuangXin 2019/10/22 15:44
  * @version 1.0
@@ -56,4 +58,10 @@ protected void checkConstraints() throws WxPayException {
   public boolean ignoreAppid() {
     return true;
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("transaction_id", transactionId);
+    map.put("out_order_no", outOrderNo);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryResult.java
index 6affffe670..49fdf74552 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryResult.java
@@ -8,6 +8,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * @author Wang GuangXin 2019/10/22 15:51
@@ -67,6 +68,18 @@ public ProfitSharingQueryResult.Receivers formatReceivers() {
     return gson.fromJson(receivers, Receivers.class);
   }
 
+  @Override
+  protected void loadXML(Document d) {
+    transactionId = readXMLString(d, "transaction_id");
+    outOrderNo = readXMLString(d, "out_order_no");
+    orderId = readXMLString(d, "orderId");
+    status = readXMLString(d, "status");
+    closeReason = readXMLString(d, "close_reason");
+    receivers = readXMLString(d, "receivers");
+    amount = readXMLInteger(d, "amount");
+    description = readXMLString(d, "description");
+  }
+
   @Data
   public class Receivers {
     /**
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverRequest.java
index 3d00d5dd7c..db64854395 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverRequest.java
@@ -7,6 +7,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 添加/删除分账接受方请求对象
  *
@@ -44,4 +46,9 @@ public class ProfitSharingReceiverRequest extends BaseWxPayRequest {
   protected void checkConstraints() throws WxPayException {
     this.setSignType(WxPayConstants.SignType.HMAC_SHA256);
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("receiver", receiver);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverResult.java
index 0b9f53881c..806632fe54 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverResult.java
@@ -6,6 +6,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * @author Wang GuangXin 2019/10/22 14:54
@@ -22,4 +23,9 @@ public class ProfitSharingReceiverResult extends BaseWxPayResult {
    */
   @XStreamAlias("receiver")
   private String receiver;
+
+  @Override
+  protected void loadXML(Document d) {
+    receiver = readXMLString(d, "receiver");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingRequest.java
index 6e6c2a3147..e3b1f5690c 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingRequest.java
@@ -7,6 +7,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * @author Wang GuangXin 2019/10/21 17:57
  * @version 1.0
@@ -81,4 +83,11 @@ protected void checkConstraints() throws WxPayException {
     // 目前仅支持HMAC-SHA256.
     this.setSignType(WxPayConstants.SignType.HMAC_SHA256);
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("transaction_id", transactionId);
+    map.put("out_order_no", outOrderNo);
+    map.put("receivers", receivers);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingResult.java
index 122821cf91..daea0e64db 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * @author Wang GuangXin 2019/10/22 10:06
@@ -30,4 +31,11 @@ public class ProfitSharingResult extends BaseWxPayResult {
    */
   @XStreamAlias("order_id")
   private String orderId;
+
+  @Override
+  protected void loadXML(Document d) {
+    transactionId = readXMLString(d, "transaction_id");
+    outOrderNo = readXMLString(d, "out_order_no");
+    orderId = readXMLString(d, "order_id");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnQueryRequest.java
index e2a2da4739..734c805401 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnQueryRequest.java
@@ -8,6 +8,8 @@
 import me.chanjar.weixin.common.annotation.Required;
 import org.apache.commons.lang3.StringUtils;
 
+import java.util.Map;
+
 /**
  * @author Wang GuangXin 2019/10/23 15:32
  * @version 1.0
@@ -69,4 +71,11 @@ protected void checkConstraints() throws WxPayException {
     }
     this.setSignType(WxPayConstants.SignType.HMAC_SHA256);
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("order_id", orderId);
+    map.put("out_order_no", outOrderNo);
+    map.put("out_return_no", outReturnNo);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnRequest.java
index 6bdc73aa62..3e389a467a 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnRequest.java
@@ -8,6 +8,8 @@
 import me.chanjar.weixin.common.annotation.Required;
 import org.apache.commons.lang3.StringUtils;
 
+import java.util.Map;
+
 /**
  * @author Wang GuangXin 2019/10/23 14:27
  * @version 1.0
@@ -130,4 +132,15 @@ protected void checkConstraints() throws WxPayException {
     }
     this.setSignType(WxPayConstants.SignType.HMAC_SHA256);
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("order_id", orderId);
+    map.put("out_order_no", outOrderNo);
+    map.put("out_return_no", outReturnNo);
+    map.put("return_account_type", returnAccountType);
+    map.put("return_account", returnAccount);
+    map.put("return_amount", returnAmount.toString());
+    map.put("description", description);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnResult.java
index 814bcf2d58..2828d4ab82 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnResult.java
@@ -5,6 +5,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * @author Wang GuangXin 2019/10/23 14:41
@@ -71,4 +72,19 @@ public class ProfitSharingReturnResult extends BaseWxPayResult {
    */
   @XStreamAlias("finish_time")
   private String finishTime;
+
+  @Override
+  protected void loadXML(Document d) {
+    orderId = readXMLString(d, "order_id");
+    outOrderNo = readXMLString(d, "out_order_no");
+    outReturnNo = readXMLString(d, "out_return_no");
+    returnNo = readXMLString(d, "return_no");
+    returnAccountType = readXMLString(d, "return_account_type");
+    returnAccount = readXMLString(d, "return_account");
+    returnAmount = readXMLInteger(d, "return_amount");
+    description = readXMLString(d, "description");
+    result = readXMLString(d, "result");
+    failReason = readXMLString(d, "fail_reason");
+    finishTime = readXMLString(d, "finish_time");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java
index 0b85f41e93..d60e56893b 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/BaseWxPayRequest.java
@@ -3,6 +3,7 @@
 import com.github.binarywang.wxpay.config.WxPayConfig;
 import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.util.SignUtils;
+import com.github.binarywang.wxpay.util.XmlConfig;
 import com.thoughtworks.xstream.XStream;
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.Data;
@@ -12,9 +13,14 @@
 import me.chanjar.weixin.common.util.json.WxGsonBuilder;
 import me.chanjar.weixin.common.util.xml.XStreamInitializer;
 import org.apache.commons.lang3.StringUtils;
+import org.dom4j.Document;
+import org.dom4j.DocumentHelper;
+import org.dom4j.Element;
 
 import java.io.Serializable;
 import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
 
 import static com.github.binarywang.wxpay.constant.WxPayConstants.SignType.ALL_SIGN_TYPES;
 
@@ -202,14 +208,52 @@ public String toString() {
    * @return the string
    */
   public String toXML() {
-    XStream xstream = XStreamInitializer.getInstance();
     //涉及到服务商模式的两个参数,在为空值时置为null,以免在请求时将空值传给微信服务器
     this.setSubAppId(StringUtils.trimToNull(this.getSubAppId()));
     this.setSubMchId(StringUtils.trimToNull(this.getSubMchId()));
+    if (XmlConfig.fastMode) {
+      return toFastXml();
+    }
+    XStream xstream = XStreamInitializer.getInstance();
     xstream.processAnnotations(this.getClass());
     return xstream.toXML(this);
   }
 
+  /**
+   * 使用快速算法组装xml
+   *
+   * @return
+   */
+  private String toFastXml() {
+    try {
+      Document document = DocumentHelper.createDocument();
+      Element root = document.addElement(xmlRootTagName());
+
+      Map signParams = getSignParams();
+      signParams.put("sign", sign);
+      for (Map.Entry entry : signParams.entrySet()) {
+        if (entry.getValue() == null) {
+          continue;
+        }
+        Element elm = root.addElement(entry.getKey());
+        elm.addText(entry.getValue());
+      }
+
+      return document.asXML();
+    } catch (Exception e) {
+      throw new RuntimeException("generate xml error", e);
+    }
+  }
+
+  /**
+   * 返回xml结构的根节点名称
+   *
+   * @return 默认返回"xml", 特殊情况可以在子类中覆盖
+   */
+  protected String xmlRootTagName() {
+    return "xml";
+  }
+
   /**
    * 签名时,是否忽略appid.
    *
@@ -228,14 +272,14 @@ protected boolean ignoreSubAppId() {
     return false;
   }
 
-  protected boolean ignoreSubMchId(){
+  protected boolean ignoreSubMchId() {
     return false;
   }
 
   /**
    * 是否是企业微信字段
    */
-  protected boolean isWxWorkSign(){
+  protected boolean isWxWorkSign() {
     return false;
   }
 
@@ -248,6 +292,32 @@ protected String[] getIgnoredParamsForSign() {
     return new String[0];
   }
 
+  /**
+   * 获取签名时需要的参数.
+   * 注意:不含sign属性
+   */
+  public Map getSignParams() {
+    Map map = new HashMap<>();
+    map.put("appid", appid);
+    map.put("mch_id", mchId);
+    map.put("sub_appid", subAppId);
+    map.put("sub_mch_id", subMchId);
+    map.put("nonce_str", nonceStr);
+    map.put("sign_type", signType);
+
+    storeMap(map);
+    return map;
+  }
+
+  /**
+   * 将属性组装到一个Map中,供签名和最终发送XML时使用.
+   * 这里需要将所有的属性全部保存进来,签名的时候会自动调用getIgnoredParamsForSign进行忽略,
+   * 不用担心。否则最终生成的XML会缺失。
+   *
+   * @param map 传入的属性Map
+   */
+  abstract protected void storeMap(Map map);
+
   /**
    * 
    * 检查参数,并设置签名.
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayAuthcode2OpenidRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayAuthcode2OpenidRequest.java
index 3b156407db..c9d5505b36 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayAuthcode2OpenidRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayAuthcode2OpenidRequest.java
@@ -3,6 +3,8 @@
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.*;
 
+import java.util.Map;
+
 /**
  * 
  * 授权码查询openid接口请求对象类
@@ -35,4 +37,10 @@ public class WxPayAuthcode2OpenidRequest extends BaseWxPayRequest {
   protected void checkConstraints() {
     // nothing to do
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("auth_code", authCode);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDefaultRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDefaultRequest.java
index e44a6111e7..34a707bed7 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDefaultRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDefaultRequest.java
@@ -2,6 +2,8 @@
 
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 
+import java.util.Map;
+
 /**
  * 
  *  支付请求默认对象类
@@ -21,4 +23,8 @@ protected void checkConstraints() {
   protected boolean ignoreAppid() {
     return true;
   }
+
+  @Override
+  protected void storeMap(Map map) {
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java
index e616224db7..383dbe5b7c 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadBillRequest.java
@@ -9,6 +9,7 @@
 import org.apache.commons.lang3.StringUtils;
 
 import java.util.Arrays;
+import java.util.Map;
 
 /**
  * 
@@ -95,4 +96,13 @@ protected void checkConstraints() throws WxPayException {
         Arrays.toString(BILL_TYPES), this.getBillType()));
     }
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("device_info", deviceInfo);
+    map.put("bill_type", billType);
+    map.put("bill_date", billDate);
+    map.put("tar_type", tarType);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadFundFlowRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadFundFlowRequest.java
index 8ce06238e6..efb14fc7c0 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadFundFlowRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayDownloadFundFlowRequest.java
@@ -9,6 +9,7 @@
 import org.apache.commons.lang3.StringUtils;
 
 import java.util.Arrays;
+import java.util.Map;
 
 /**
  * 
@@ -87,4 +88,11 @@ protected void checkConstraints() throws WxPayException {
      */
     this.setSignType(SIGN_TYPE_HMAC_SHA256);
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("bill_date", billDate);
+    map.put("account_type", accountType);
+    map.put("tar_type", tarType);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayFaceAuthInfoRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayFaceAuthInfoRequest.java
index eb53e38c6a..cef831a3d6 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayFaceAuthInfoRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayFaceAuthInfoRequest.java
@@ -4,6 +4,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 
  *  获取微信刷脸调用凭证请求对象类
@@ -123,4 +125,15 @@ protected void checkConstraints() {
     //do nothing
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("store_id", storeId);
+    map.put("store_name", storeName);
+    map.put("device_id", deviceId);
+    map.put("attach", attach);
+    map.put("rawdata", rawdata);
+    map.put("now", now);
+    map.put("version", version);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayFacepayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayFacepayRequest.java
index 2c70a8945c..e9821c506c 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayFacepayRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayFacepayRequest.java
@@ -4,6 +4,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 
  *  提交刷脸支付请求对象类
@@ -174,4 +176,19 @@ protected void checkConstraints() {
     //do nothing
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("device_info", deviceInfo);
+    map.put("body", body);
+    map.put("detail", detail);
+    map.put("attach", attach);
+    map.put("out_trade_no", outTradeNo);
+    map.put("total_fee", totalFee.toString());
+    map.put("fee_type", feeType);
+    map.put("spbill_create_ip", spbillCreateIp);
+    map.put("goods_tag", goodsTag);
+    map.put("openid", openid);
+    map.put("face_code", faceCode);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java
index 4fb27dd8bf..cdded3110d 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayMicropayRequest.java
@@ -4,6 +4,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 
  *  提交付款码支付请求对象类
@@ -255,4 +257,22 @@ protected void checkConstraints() {
     //do nothing
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("version", version);
+    map.put("body", body);
+    map.put("detail", detail);
+    map.put("attach", attach);
+    map.put("out_trade_no", outTradeNo);
+    map.put("total_fee", totalFee.toString());
+    map.put("fee_type", feeType);
+    map.put("spbill_create_ip", spbillCreateIp);
+    map.put("goods_tag", goodsTag);
+    map.put("limit_pay", limitPay);
+    map.put("time_start", timeStart);
+    map.put("time_expire", timeExpire);
+    map.put("auth_code", authCode);
+    map.put("scene_info", sceneInfo);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java
index e430460e39..3758653a03 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderCloseRequest.java
@@ -3,6 +3,8 @@
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.*;
 
+import java.util.Map;
+
 /**
  * 
  *  关闭订单请求对象类
@@ -36,4 +38,10 @@ public class WxPayOrderCloseRequest extends BaseWxPayRequest {
   protected void checkConstraints() {
 
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("out_trade_no", outTradeNo);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java
index 221b04f172..ffcd52d171 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderQueryRequest.java
@@ -5,6 +5,8 @@
 import lombok.*;
 import org.apache.commons.lang3.StringUtils;
 
+import java.util.Map;
+
 /**
  * 
  * 订单查询请求对象
@@ -76,4 +78,12 @@ protected void checkConstraints() throws WxPayException {
       throw new WxPayException("transaction_id 和 out_trade_no 不能同时存在或同时为空,必须二选一");
     }
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("version", version);
+    map.put("transaction_id", transactionId);
+    map.put("out_trade_no", outTradeNo);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderReverseRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderReverseRequest.java
index 5394631b3c..73c5034696 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderReverseRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayOrderReverseRequest.java
@@ -5,6 +5,8 @@
 import lombok.*;
 import org.apache.commons.lang3.StringUtils;
 
+import java.util.Map;
+
 /**
  * 
  * 撤销订单请求类
@@ -53,4 +55,10 @@ protected void checkConstraints() throws WxPayException {
     }
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("transaction_id", transactionId);
+    map.put("out_trade_no", outTradeNo);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayQueryCommentRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayQueryCommentRequest.java
index 5ff1c76a04..5c4a9fe2ff 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayQueryCommentRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayQueryCommentRequest.java
@@ -5,6 +5,8 @@
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.util.Map;
+
 /**
  * 
  *  拉取订单评价数据接口的请求参数封装类.
@@ -84,4 +86,14 @@ public class WxPayQueryCommentRequest extends BaseWxPayRequest {
   protected void checkConstraints() throws WxPayException {
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("begin_time", beginTime);
+    map.put("end_time", endTime);
+    map.put("offset", offset.toString());
+    if (limit != null) {
+      map.put("limit", limit.toString());
+    }
+  }
+
 }
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 9303810753..01ca5cafd4 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
@@ -3,6 +3,8 @@
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.*;
 
+import java.util.Map;
+
 /**
  * 
  *   注释中各行对应含义:
@@ -27,8 +29,9 @@ public class WxPayRedpackQueryRequest extends BaseWxPayRequest {
 
   @Override
   protected String[] getIgnoredParamsForSign() {
-    return new String[]{"sub_appid","sub_mch_id","sign_type"};
+    return new String[]{"sub_appid", "sub_mch_id", "sign_type"};
   }
+
   /**
    * 商户订单号
    * mch_billno
@@ -55,4 +58,10 @@ protected String[] getIgnoredParamsForSign() {
   protected void checkConstraints() {
 
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("mch_billno", mchBillNo);
+    map.put("bill_type", billType);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java
index 4df8a63db9..d9befee6f6 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundQueryRequest.java
@@ -5,6 +5,8 @@
 import lombok.*;
 import org.apache.commons.lang3.StringUtils;
 
+import java.util.Map;
+
 /**
  * 
  * Created by Binary Wang on 2016-11-24.
@@ -91,4 +93,13 @@ protected void checkConstraints() throws WxPayException {
     }
 
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("device_info", deviceInfo);
+    map.put("transaction_id", transactionId);
+    map.put("out_trade_no", outTradeNo);
+    map.put("out_refund_no", outRefundNo);
+    map.put("refund_id", refundId);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java
index 1383e4f5b1..924d46ffdd 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayRefundRequest.java
@@ -10,6 +10,7 @@
 import org.apache.commons.lang3.StringUtils;
 
 import java.util.Arrays;
+import java.util.Map;
 
 /**
  * 
@@ -165,7 +166,7 @@ public class WxPayRefundRequest extends BaseWxPayRequest {
    * 类型:String(256)
    * 示例值:https://weixin.qq.com/notify/
    * 描述:	异步接收微信支付退款结果通知的回调地址,通知URL必须为外网可访问的url,不允许带参数
-   如果参数中传了notify_url,则商户平台上配置的回调地址将不会生效。
+   * 如果参数中传了notify_url,则商户平台上配置的回调地址将不会生效。
    * 
*/ @XStreamAlias("notify_url") @@ -194,4 +195,19 @@ protected void checkConstraints() throws WxPayException { } } + @Override + protected void storeMap(Map map) { + map.put("device_info", deviceInfo); + map.put("transaction_id", transactionId); + map.put("out_trade_no", outTradeNo); + map.put("out_refund_no", outRefundNo); + map.put("total_fee", totalFee.toString()); + map.put("refund_fee", refundFee.toString()); + map.put("refund_fee_type", refundFeeType); + map.put("op_user_id", opUserId); + map.put("refund_account", refundAccount); + map.put("refund_desc", refundDesc); + map.put("notify_url", notifyUrl); + } + } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java index 3e5364c5ce..56cd490a55 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayReportRequest.java @@ -4,6 +4,8 @@ import lombok.*; import me.chanjar.weixin.common.annotation.Required; +import java.util.Map; + /** *
  * 微信支付-交易保障请求参数
@@ -174,4 +176,19 @@ public class WxPayReportRequest extends BaseWxPayRequest {
   protected void checkConstraints() {
     //do nothing
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("device_info", deviceInfo);
+    map.put("interface_url", interfaceUrl);
+    map.put("execute_time_", executeTime.toString());
+    map.put("return_code", returnCode);
+    map.put("return_msg", returnMsg);
+    map.put("result_code", resultCode);
+    map.put("err_code", errCode);
+    map.put("err_code_des", errCodeDes);
+    map.put("out_trade_no", outTradeNo);
+    map.put("user_ip", userIp);
+    map.put("time", time);
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendMiniProgramRedpackRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendMiniProgramRedpackRequest.java
index 62cfe490a7..fd727ab6aa 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendMiniProgramRedpackRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendMiniProgramRedpackRequest.java
@@ -4,6 +4,8 @@
 import lombok.*;
 import lombok.experimental.Accessors;
 
+import java.util.Map;
+
 /**
  * 发送小程序红包请求参数对象.
  *
@@ -119,6 +121,21 @@ protected void checkConstraints() {
 
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("mch_billno", mchBillNo);
+    map.put("send_name", sendName);
+    map.put("re_openid", reOpenid);
+    map.put("total_amount", totalAmount.toString());
+    map.put("total_num", totalNum.toString());
+    map.put("wishing", wishing);
+    map.put("act_name", actName);
+    map.put("remark", remark);
+    map.put("notify_way", notifyWay);
+    map.put("scene_id", sceneId);
+    map.put("wxappid", wxAppid);
+  }
+
   @Override
   public String getAppid() {
     return this.wxAppid;
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 977f363f6a..4a8bae4f57 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
@@ -3,6 +3,8 @@
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.*;
 
+import java.util.Map;
+
 /**
  * 发送红包请求参数对象.
  * Created by Binary Wang on 2016/9/24.
@@ -181,4 +183,18 @@ public void setAppid(String appid) {
     this.wxAppid = appid;
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("mch_billno", mchBillNo);
+    map.put("send_name", sendName);
+    map.put("re_openid", reOpenid);
+    map.put("total_amount", totalAmount.toString());
+    map.put("total_num", totalNum.toString());
+    map.put("amt_type", amtType);
+    map.put("wishing", wishing);
+    map.put("client_ip", clientIp);
+    map.put("act_name", actName);
+    map.put("remark", remark);
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayShorturlRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayShorturlRequest.java
index 87ac41054b..8602740bb8 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayShorturlRequest.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPayShorturlRequest.java
@@ -3,6 +3,8 @@
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.*;
 
+import java.util.Map;
+
 /**
  * 
  * 转换短链接请求对象类
@@ -35,4 +37,9 @@ public class WxPayShorturlRequest extends BaseWxPayRequest {
   protected void checkConstraints() {
     //do nothing
   }
+
+  @Override
+  protected void storeMap(Map map) {
+    map.put("long_url", longUrl);
+  }
 }
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 54d443881d..fc5949dfdf 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
@@ -9,6 +9,8 @@
 import me.chanjar.weixin.common.annotation.Required;
 import org.apache.commons.lang3.StringUtils;
 
+import java.util.Map;
+
 /**
  * 
  * 统一下单请求参数对象.
@@ -396,4 +398,30 @@ public void checkAndSign(WxPayConfig config) throws WxPayException {
     super.checkAndSign(config);
   }
 
+  @Override
+  protected void storeMap(Map map) {
+    map.put("version", version);
+    map.put("device_info", deviceInfo);
+    map.put("body", body);
+    map.put("detail", detail);
+    map.put("attach", attach);
+    map.put("out_trade_no", outTradeNo);
+    map.put("fee_type", feeType);
+    map.put("total_fee", totalFee.toString());
+    map.put("spbill_create_ip", spbillCreateIp);
+    map.put("time_start", timeStart);
+    map.put("time_expire", timeExpire);
+    map.put("goods_tag", goodsTag);
+    map.put("notify_url", notifyUrl);
+    map.put("trade_type", tradeType);
+    map.put("product_id", productId);
+    map.put("limit_pay", limitPay);
+    map.put("openid", openid);
+    map.put("sub_openid", subOpenid);
+    map.put("receipt", receipt);
+    map.put("scene_info", sceneInfo);
+    map.put("fingerprint", fingerprint);
+    map.put("profit_sharing", profitSharing);
+  }
+
 }
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 5a1ea64e83..d58f20fb18 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
@@ -11,6 +11,7 @@
 import javax.xml.xpath.XPathExpressionException;
 import javax.xml.xpath.XPathFactory;
 
+import com.github.binarywang.wxpay.util.XmlConfig;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -30,6 +31,8 @@
 import me.chanjar.weixin.common.util.json.WxGsonBuilder;
 import me.chanjar.weixin.common.util.xml.XStreamInitializer;
 
+import org.w3c.dom.*;
+
 /**
  * 
  * 微信支付结果共用属性类.
@@ -107,8 +110,9 @@ public abstract class BaseWxPayResult implements Serializable {
 
   /**
    * xml的Document对象,用于解析xml文本.
+   * make xmlDoc transient to ensure toString() can work.
    */
-  private Document xmlDoc;
+  private transient Document xmlDoc;
 
   /**
    * 将单位分转换成单位圆.
@@ -129,6 +133,18 @@ public static String fenToYuan(Integer fen) {
    * @return the t
    */
   public static  T fromXML(String xmlString, Class clz) {
+    if (XmlConfig.fastMode) {
+      try {
+        BaseWxPayResult t = clz.newInstance();
+        t.setXmlString(xmlString);
+        Document doc = t.getXmlDoc();
+        t.loadBasicXML(doc);
+        t.loadXML(doc);
+        return (T) t;
+      } catch (Exception e) {
+        throw new RuntimeException("parse xml error", e);
+      }
+    }
     XStream xstream = XStreamInitializer.getInstance();
     xstream.processAnnotations(clz);
     T result = (T) xstream.fromXML(xmlString);
@@ -136,6 +152,70 @@ public static  T fromXML(String xmlString, Class c
     return result;
   }
 
+  /**
+   * 从XML文档中加载属性,供子类覆盖加载额外的属性
+   *
+   * @param d Document
+   */
+  protected abstract void loadXML(Document d);
+
+  /**
+   * 从XML文档中加载基础属性
+   *
+   * @param d Document
+   */
+  private void loadBasicXML(Document d) {
+    returnCode = readXMLString(d, "return_code");
+    returnMsg = readXMLString(d, "return_msg");
+    resultCode = readXMLString(d, "result_code");
+    errCode = readXMLString(d, "err_code");
+    errCodeDes = readXMLString(d, "err_code_des");
+    appid = readXMLString(d, "appid");
+    mchId = readXMLString(d, "mch_id");
+    subAppId = readXMLString(d, "sub_appid");
+    subMchId = readXMLString(d, "sub_mch_id");
+    nonceStr = readXMLString(d, "nonce_str");
+    sign = readXMLString(d, "sign");
+  }
+
+  public static Integer readXMLInteger(Node d, String tagName) {
+    String content = readXMLString(d, tagName);
+    if (content == null || content.trim().length() == 0) return null;
+    return Integer.parseInt(content);
+  }
+
+  public static String readXMLString(Node d, String tagName) {
+    if (!d.hasChildNodes()) return null;
+    NodeList childNodes = d.getChildNodes();
+    for (int i = 0, j = childNodes.getLength(); i < j; i++) {
+      Node node = childNodes.item(i);
+      if (tagName.equals(node.getNodeName())) {
+        if (!node.hasChildNodes()) return null;
+        return node.getFirstChild().getNodeValue();
+      }
+    }
+    return null;
+  }
+
+  public static String readXMLString(Document d, String tagName) {
+    NodeList elements = d.getElementsByTagName(tagName);
+    if (elements == null || elements.getLength() == 0) {
+      return null;
+    }
+
+    Node node = elements.item(0).getFirstChild();
+    if (node == null) {
+      return null;
+    }
+    return node.getNodeValue();
+  }
+
+  public static Integer readXMLInteger(Document d, String tagName) {
+    String content = readXMLString(d, tagName);
+    if (content == null || content.trim().length() == 0) return null;
+    return Integer.parseInt(content);
+  }
+
   /**
    * Gets logger.
    *
@@ -185,18 +265,19 @@ private Document getXmlDoc() {
     if (this.xmlDoc != null) {
       return this.xmlDoc;
     }
+    xmlDoc = openXML(xmlString);
+    return xmlDoc;
+  }
 
+  protected Document openXML(String content) {
     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;
+      return factory.newDocumentBuilder().parse(new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)));
     } catch (Exception e) {
       throw new RuntimeException("非法的xml文本内容:\n" + this.xmlString, e);
     }
-
   }
 
   /**
@@ -205,7 +286,7 @@ private Document getXmlDoc() {
    * @param path the path
    * @return the xml value
    */
-  String getXmlValue(String... path) {
+  protected String getXmlValue(String... path) {
     Document doc = this.getXmlDoc();
     String expression = String.format("/%s//text()", Joiner.on("/").join(path));
     try {
@@ -225,7 +306,7 @@ String getXmlValue(String... path) {
    * @param path the path
    * @return the xml value as int
    */
-  Integer getXmlValueAsInt(String... path) {
+  protected Integer getXmlValueAsInt(String... path) {
     String result = this.getXmlValue(path);
     if (StringUtils.isBlank(result)) {
       return null;
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayAuthcode2OpenidResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayAuthcode2OpenidResult.java
index 2c36d32f03..76526ff685 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayAuthcode2OpenidResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayAuthcode2OpenidResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -30,4 +31,14 @@ public class WxPayAuthcode2OpenidResult extends BaseWxPayResult {
   @XStreamAlias("openid")
   private String openid;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    openid = readXMLString(d, "openid");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayCommonResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayCommonResult.java
index cc0a3a6edc..1dda6483b4 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayCommonResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayCommonResult.java
@@ -1,6 +1,7 @@
 package com.github.binarywang.wxpay.bean.result;
 
 import com.thoughtworks.xstream.annotations.XStreamAlias;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -12,4 +13,7 @@
  */
 @XStreamAlias("xml")
 public class WxPayCommonResult extends BaseWxPayResult {
+  @Override
+  protected void loadXML(Document d) {
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFaceAuthInfoResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFaceAuthInfoResult.java
index 95dcf71eb4..5c357c560f 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFaceAuthInfoResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFaceAuthInfoResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 import java.io.Serializable;
 
@@ -35,4 +36,15 @@ public class WxPayFaceAuthInfoResult extends BaseWxPayResult implements Serializ
   @XStreamAlias("expires_in")
   private String expiresIn;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    authinfo = readXMLString(d, "authinfo");
+    expiresIn = readXMLString(d, "expires_in");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFacepayResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFacepayResult.java
index 27e33d7bfc..c19a92c488 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFacepayResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayFacepayResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -242,4 +243,30 @@ public class WxPayFacepayResult extends BaseWxPayResult {
   @XStreamAlias("time_end")
   private String timeEnd;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    deviceInfo = readXMLString(d, "device_info");
+    openid = readXMLString(d, "openid");
+    isSubscribe = readXMLString(d, "is_subscribe");
+    subOpenid = readXMLString(d, "sub_openid");
+    subsSubscribe = readXMLString(d, "sub_is_subscribe");
+    tradeType = readXMLString(d, "trade_type");
+    bankType = readXMLString(d, "bank_type");
+    feeType = readXMLString(d, "fee_type");
+    totalFee = readXMLInteger(d, "total_fee");
+    cashFeeType = readXMLString(d, "cash_fee_type");
+    cashFee = readXMLInteger(d, "cash_fee");
+    transactionId = readXMLString(d, "transaction_id");
+    outTradeNo = readXMLString(d, "out_trade_no");
+    detail = readXMLString(d, "detail");
+    attach = readXMLString(d, "attach");
+    promotionDetail = readXMLString(d, "promotion_detail");
+    timeEnd = readXMLString(d, "time_end");
+  }
+
 }
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 36f910be63..b7de7ffec1 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
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -215,4 +216,28 @@ public class WxPayMicropayResult extends BaseWxPayResult {
   @XStreamAlias("promotion_detail")
   private String promotionDetail;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    openid = readXMLString(d, "openid");
+    isSubscribe = readXMLString(d, "is_subscribe");
+    tradeType = readXMLString(d, "trade_type");
+    bankType = readXMLString(d, "bank_type");
+    feeType = readXMLString(d, "fee_type");
+    totalFee = readXMLInteger(d, "total_fee");
+    settlementTotalFee = readXMLInteger(d, "settlement_total_fee");
+    couponFee = readXMLInteger(d, "coupon_fee");
+    cashFeeType = readXMLString(d, "cash_fee_type");
+    cashFee = readXMLInteger(d, "cash_fee");
+    transactionId = readXMLString(d, "transaction_id");
+    outTradeNo = readXMLString(d, "out_trade_no");
+    attach = readXMLString(d, "attach");
+    timeEnd = readXMLString(d, "time_end");
+    promotionDetail = readXMLString(d, "promotion_detail");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderCloseResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderCloseResult.java
index a71c8ab7ed..a098cbb5fc 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderCloseResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderCloseResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -25,4 +26,14 @@ public class WxPayOrderCloseResult extends BaseWxPayResult {
   @XStreamAlias("result_msg")
   private String resultMsg;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    resultMsg = readXMLString(d, "result_msg");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java
index c7534b79c5..906a8cf12f 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderQueryResult.java
@@ -10,6 +10,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -32,7 +33,7 @@
 @XStreamAlias("xml")
 public class WxPayOrderQueryResult extends BaseWxPayResult {
   private static final long serialVersionUID = 8241891654782412789L;
-  
+
   /**
    * 
    * 字段名:营销详情.
@@ -290,6 +291,29 @@ public void composeCoupons() {
     }
   }
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    promotionDetail = readXMLString(d, "promotion_detail");
+    deviceInfo = readXMLString(d, "device_info");
+    openid = readXMLString(d, "openid");
+    isSubscribe = readXMLString(d, "is_subscribe");
+    tradeType = readXMLString(d, "trade_type");
+    tradeState = readXMLString(d, "trade_state");
+    bankType = readXMLString(d, "bank_type");
+    totalFee = readXMLInteger(d, "total_fee");
+    settlementTotalFee = readXMLInteger(d, "settlement_total_fee");
+    feeType = readXMLString(d, "fee_type");
+    cashFee = readXMLInteger(d, "cash_fee");
+    cashFeeType = readXMLString(d, "cash_fee_type");
+    couponFee = readXMLInteger(d, "coupon_fee");
+    couponCount = readXMLInteger(d, "coupon_count");
+  }
+
   /**
    * The type Coupon.
    */
@@ -338,4 +362,5 @@ public static class Coupon implements Serializable {
     private Integer couponFee;
 
   }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java
index 578139929e..210e9e4aab 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayOrderReverseResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -32,4 +33,14 @@ public class WxPayOrderReverseResult extends BaseWxPayResult {
   @XStreamAlias("recall")
   private String isRecall;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    isRecall = readXMLString(d, "recall");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResult.java
index 4f05bfde68..91c6eb7f22 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResult.java
@@ -1,12 +1,16 @@
 package com.github.binarywang.wxpay.bean.result;
 
 import java.io.Serializable;
+import java.util.ArrayList;
 import java.util.List;
 
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 
 /**
  * 
@@ -223,6 +227,43 @@ public class WxPayRedpackQueryResult extends BaseWxPayResult {
   @XStreamAlias("hblist")
   private List redpackList;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    mchBillNo = readXMLString(d, "mch_billno");
+    detailId = readXMLString(d, "detail_id");
+    status = readXMLString(d, "status");
+    sendType = readXMLString(d, "send_type");
+    hbType = readXMLString(d, "hb_type");
+    totalNum = readXMLInteger(d, "total_num");
+    totalAmount = readXMLInteger(d, "total_amount");
+    sendTime = readXMLString(d, "send_time");
+    refundTime = readXMLString(d, "refund_time");
+    refundAmount = readXMLInteger(d, "refund_amount");
+    wishing = readXMLString(d, "wishing");
+    remark = readXMLString(d, "remark");
+    actName = readXMLString(d, "act_name");
+
+    NodeList nodeList = d.getElementsByTagName("hbinfo");
+    List list = new ArrayList<>(nodeList.getLength());
+
+    for (int i = 0, j = nodeList.getLength(); i < j; i++) {
+      Node node = nodeList.item(i);
+      RedpackInfo rp = new RedpackInfo();
+      rp.amount = readXMLInteger(node, "amount");
+      rp.openid = readXMLString(node, "openid");
+      rp.receiveTime = readXMLString(node, "rcv_time");
+      list.add(rp);
+    }
+
+    redpackList = list;
+
+  }
+
   /**
    * The type Redpack info.
    */
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java
index 3bc6a2b4b6..ecdf933b6b 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayRefundQueryResult.java
@@ -9,6 +9,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -172,6 +173,23 @@ public void composeRefundRecords() {
     }
   }
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    deviceInfo = readXMLString(d, "device_info");
+    transactionId = readXMLString(d, "transaction_id");
+    outTradeNo = readXMLString(d, "out_trade_no");
+    totalFee = readXMLInteger(d, "total_fee");
+    settlementTotalFee = readXMLInteger(d, "settlement_total_fee");
+    feeType = readXMLString(d, "fee_type");
+    cashFee = readXMLInteger(d, "cash_fee");
+    refundCount = readXMLInteger(d, "refund_count");
+  }
+
   /**
    * The type Refund record.
    */
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 9b971123aa..57fb333595 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
@@ -8,6 +8,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -119,7 +120,7 @@ public class WxPayRefundResult extends BaseWxPayResult implements Serializable {
   /**
    * 组装生成退款代金券信息.
    */
-  private void composeRefundCoupons() {
+  public void composeRefundCoupons() {
     List coupons = Lists.newArrayList();
     Integer refundCount = this.getCouponRefundCount();
     if (refundCount == null) {
@@ -140,9 +141,27 @@ private void composeRefundCoupons() {
     this.setRefundCoupons(coupons);
   }
 
-  public static WxPayRefundResult fromXML(String xml) {
-    WxPayRefundResult result = BaseWxPayResult.fromXML(xml, WxPayRefundResult.class);
-    result.composeRefundCoupons();
-    return result;
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    transactionId = readXMLString(d, "transaction_id");
+    outTradeNo = readXMLString(d, "out_trade_no");
+    outRefundNo = readXMLString(d, "out_refund_no");
+    refundId = readXMLString(d, "refund_id");
+    refundFee = readXMLInteger(d, "refund_fee");
+    settlementRefundFee = readXMLInteger(d, "settlement_refund_fee");
+    totalFee = readXMLInteger(d, "total_fee");
+    settlementTotalFee = readXMLInteger(d, "settlement_total_fee");
+    feeType = readXMLString(d, "fee_type");
+    cashFee = readXMLInteger(d, "cash_fee");
+    cashFeeType = readXMLString(d, "cash_fee_type");
+    cashRefundFee = readXMLInteger(d, "cash_refund_fee");
+    couponRefundCount = readXMLInteger(d, "coupon_refund_count");
+    couponRefundFee = readXMLInteger(d, "coupon_refund_fee");
   }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySandboxSignKeyResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySandboxSignKeyResult.java
index cf3f9355db..b1af69c6b0 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySandboxSignKeyResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySandboxSignKeyResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -31,4 +32,14 @@ public class WxPaySandboxSignKeyResult extends BaseWxPayResult {
   @XStreamAlias("sandbox_signkey")
   private String sandboxSignKey;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    sandboxSignKey = readXMLString(d, "sandbox_signkey");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendMiniProgramRedpackResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendMiniProgramRedpackResult.java
index bb9bfee8a1..c707fee7f1 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendMiniProgramRedpackResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendMiniProgramRedpackResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 import java.io.Serializable;
 
@@ -53,4 +54,13 @@ public class WxPaySendMiniProgramRedpackResult extends BaseWxPayResult implement
   @XStreamAlias("send_listid")
   private String sendListId;
 
+  @Override
+  protected void loadXML(Document d) {
+    mchBillNo = readXMLString(d, "mch_billno");
+    wxAppid = readXMLString(d, "wxappid");
+    reOpenid = readXMLString(d, "re_openid");
+    totalAmount = readXMLInteger(d, "total_amount");
+    packageName = readXMLString(d, "package");
+    sendListId = readXMLString(d, "send_listid");
+  }
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResult.java
index 2855daef79..adc6a688fc 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPaySendRedpackResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 import java.io.Serializable;
 
@@ -38,4 +39,19 @@ public class WxPaySendRedpackResult extends BaseWxPayResult implements Serializa
   @XStreamAlias("send_listid")
   private String sendListid;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    mchBillno = readXMLString(d, "mch_billno");
+    wxappid = readXMLString(d, "wxappid");
+    reOpenid = readXMLString(d, "re_openid");
+    totalAmount = readXMLInteger(d, "total_amount");
+    sendTime = readXMLString(d, "send_time");
+    sendListid = readXMLString(d, "send_listid");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayShorturlResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayShorturlResult.java
index 1937004f47..b213024edc 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayShorturlResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayShorturlResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -31,4 +32,14 @@ public class WxPayShorturlResult extends BaseWxPayResult {
   @XStreamAlias("short_url")
   private String shortUrl;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    shortUrl = readXMLString(d, "short_url");
+  }
+
 }
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderResult.java
index cf97f75abc..3345f0c0fb 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderResult.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/result/WxPayUnifiedOrderResult.java
@@ -4,6 +4,7 @@
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
 
 /**
  * 
@@ -43,4 +44,17 @@ public class WxPayUnifiedOrderResult extends BaseWxPayResult {
   @XStreamAlias("code_url")
   private String codeURL;
 
+  /**
+   * 从XML结构中加载额外的熟悉
+   *
+   * @param d Document
+   */
+  @Override
+  protected void loadXML(Document d) {
+    prepayId = readXMLString(d, "prepay_id");
+    tradeType = readXMLString(d, "trade_type");
+    mwebUrl = readXMLString(d, "mweb_url");
+    codeURL = readXMLString(d, "code_url");
+  }
+
 }
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 9f363eaf25..c0782f90d0 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
@@ -21,6 +21,7 @@
 import com.github.binarywang.wxpay.service.RedpackService;
 import com.github.binarywang.wxpay.service.WxPayService;
 import com.github.binarywang.wxpay.util.SignUtils;
+import com.github.binarywang.wxpay.util.XmlConfig;
 import com.google.common.base.Joiner;
 import com.google.common.collect.Maps;
 import jodd.io.ZipUtil;
@@ -117,7 +118,8 @@ public WxPayRefundResult refund(WxPayRefundRequest request) throws WxPayExceptio
     }
 
     String responseContent = this.post(url, request.toXML(), true);
-    WxPayRefundResult result = WxPayRefundResult.fromXML(responseContent);
+    WxPayRefundResult result = BaseWxPayResult.fromXML(responseContent, WxPayRefundResult.class);
+    result.composeRefundCoupons();
     result.checkResult(this, request.getSignType(), true);
     return result;
   }
@@ -165,7 +167,13 @@ public WxPayOrderNotifyResult parseOrderNotifyResult(String xmlData) throws WxPa
   public WxPayRefundNotifyResult parseRefundNotifyResult(String xmlData) throws WxPayException {
     try {
       log.debug("微信支付退款异步通知参数:{}", xmlData);
-      WxPayRefundNotifyResult result = WxPayRefundNotifyResult.fromXML(xmlData, this.getConfig().getMchKey());
+      WxPayRefundNotifyResult result;
+      if (XmlConfig.fastMode) {
+        result = BaseWxPayResult.fromXML(xmlData, WxPayRefundNotifyResult.class);
+        result.decryptReqInfo(this.getConfig().getMchKey());
+      } else {
+        result = WxPayRefundNotifyResult.fromXML(xmlData, this.getConfig().getMchKey());
+      }
       log.debug("微信支付退款异步通知解析后的对象:{}", result);
       return result;
     } catch (Exception e) {
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java
index 8490e00993..0d1962ff43 100644
--- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/SignUtils.java
@@ -65,7 +65,18 @@ public static String createSign(Map params, String signKey) {
    * @return 签名字符串 string
    */
   public static String createSign(Object xmlBean, String signType, String signKey, String[] ignoredParams) {
-    return createSign(xmlBean2Map(xmlBean), signType, signKey, ignoredParams);
+    Map map = null;
+
+    if (XmlConfig.fastMode) {
+      if (xmlBean instanceof BaseWxPayRequest) {
+        map = ((BaseWxPayRequest) xmlBean).getSignParams();
+      }
+    }
+    if (map == null) {
+      map = xmlBean2Map(xmlBean);
+    }
+
+    return createSign(map, signType, signKey, ignoredParams);
   }
 
   /**
@@ -91,7 +102,7 @@ public static String createSign(Map params, String signType, Str
 
       if (shouldSign) {
         toSign.append(key).append("=").append(value).append("&");
-    }
+      }
     }
 
     toSign.append("key=").append(signKey);
@@ -104,25 +115,26 @@ public static String createSign(Map params, String signType, Str
 
   /**
    * 企业微信签名
+   *
    * @param signType md5 目前接口要求使用的加密类型
    */
-  public static String createEntSign(String actName,String mchBillNo,String mchId,String nonceStr,
-                                     String reOpenid,Integer totalAmount,String wxAppId,String signKey,
-                                     String signType){
+  public static String createEntSign(String actName, String mchBillNo, String mchId, String nonceStr,
+                                     String reOpenid, Integer totalAmount, String wxAppId, String signKey,
+                                     String signType) {
     Map sortedMap = new HashMap<>();
-    sortedMap.put("act_name",actName);
-    sortedMap.put("mch_billno",mchBillNo);
-    sortedMap.put("mch_id",mchId);
-    sortedMap.put("nonce_str",nonceStr);
-    sortedMap.put("re_openid",reOpenid);
+    sortedMap.put("act_name", actName);
+    sortedMap.put("mch_billno", mchBillNo);
+    sortedMap.put("mch_id", mchId);
+    sortedMap.put("nonce_str", nonceStr);
+    sortedMap.put("re_openid", reOpenid);
     sortedMap.put("total_amount", totalAmount + "");
-    sortedMap.put("wxappid",wxAppId);
+    sortedMap.put("wxappid", wxAppId);
 
     Map sortParams = new TreeMap<>(sortedMap);
     Set> entries = sortParams.entrySet();
     Iterator> iterator = entries.iterator();
     StringBuilder toSign = new StringBuilder();
-    while(iterator.hasNext()){
+    while (iterator.hasNext()) {
       Map.Entry entry = iterator.next();
       String key = String.valueOf(entry.getKey());
       String value = String.valueOf(entry.getValue());
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/XmlConfig.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/XmlConfig.java
new file mode 100644
index 0000000000..3cd776841d
--- /dev/null
+++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/util/XmlConfig.java
@@ -0,0 +1,23 @@
+package com.github.binarywang.wxpay.util;
+
+public class XmlConfig {
+
+  /**
+   * 是否使用快速模式
+   *
+   * 如果设置为true,将会影响下面的方法,不再使用反射的方法来进行xml转换。
+   * 1: BaseWxPayRequest的toXML方法
+   * 2: BaseWxPayResult的fromXML方法
+   * @see com.github.binarywang.wxpay.bean.request.BaseWxPayRequest#toXML
+   * @see com.github.binarywang.wxpay.bean.result.BaseWxPayResult#fromXML
+   *
+   * 启用快速模式后,将能:
+   * 1:性能提升约 10 ~ 15倍
+   * 2:可以通过 graalvm 生成native image,大大减少系统开销(CPU,RAM),加快应用启动速度(亚秒级),加快系统部署速度(脱离JRE).
+   *
+   * 参考测试案例: com.github.binarywang.wxpay.bean.result.WxPayRedpackQueryResultTest#benchmark
+   * 参考网址: https://www.graalvm.org/
+   */
+  public static boolean fastMode = false;
+
+}
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResultTest.java
index a22916dea7..f79e0859f0 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResultTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayOrderNotifyResultTest.java
@@ -1,5 +1,7 @@
 package com.github.binarywang.wxpay.bean.notify;
 
+import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
+import com.github.binarywang.wxpay.util.XmlConfig;
 import org.testng.*;
 import org.testng.annotations.*;
 
@@ -57,6 +59,27 @@ public void testFromXML() {
 
     Assert.assertEquals(result.getCouponList().get(0).getCouponId(), "10000");
     Assert.assertEquals(result.getCouponList().get(1).getCouponId(), "10001");
+
+    //fast mode test
+    XmlConfig.fastMode = true;
+    try {
+      result = BaseWxPayResult.fromXML(xmlString, WxPayOrderNotifyResult.class);
+
+      Assert.assertEquals(result.getCouponCount().intValue(), 2);
+      Assert.assertNotNull(result.getCouponList());
+      Assert.assertEquals(result.getCouponList().size(), 2);
+
+      Assert.assertEquals(result.getCouponList().get(0).getCouponFee().intValue(), 100);
+      Assert.assertEquals(result.getCouponList().get(1).getCouponFee().intValue(), 200);
+
+      Assert.assertEquals(result.getCouponList().get(0).getCouponType(), "CASH");
+      Assert.assertEquals(result.getCouponList().get(1).getCouponType(), "NO_CASH");
+
+      Assert.assertEquals(result.getCouponList().get(0).getCouponId(), "10000");
+      Assert.assertEquals(result.getCouponList().get(1).getCouponId(), "10001");
+    } finally {
+      XmlConfig.fastMode = false;
+    }
   }
 
 }
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResultTest.java
index ba7ed54501..963afb2618 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResultTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxPayRefundNotifyResultTest.java
@@ -7,6 +7,8 @@
 import javax.crypto.spec.SecretKeySpec;
 import javax.inject.Inject;
 
+import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
+import com.github.binarywang.wxpay.util.XmlConfig;
 import org.apache.commons.codec.binary.Base64;
 import org.testng.annotations.*;
 
@@ -78,4 +80,50 @@ public void encodeReqInfo() throws Exception {
     cipher.init(Cipher.ENCRYPT_MODE, key);
     System.out.println(Base64.encodeBase64String(cipher.doFinal(xml.getBytes(StandardCharsets.UTF_8))));
   }
+
+  /**
+   * Test from xml.
+   * fast mode
+   *
+   * @throws WxPayException the wx pay exception
+   */
+  public void testFromXMLFastMode() throws WxPayException {
+    String xmlString = "" +
+      "SUCCESS" +
+      "" +
+      "" +
+      "" +
+      "";
+
+    String xmlDecryptedReqInfo = "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "";
+
+    XmlConfig.fastMode = true;
+    try {
+      WxPayRefundNotifyResult refundNotifyResult = BaseWxPayResult.fromXML(xmlString, WxPayRefundNotifyResult.class);
+      System.out.println(refundNotifyResult.getReqInfoString());
+
+      refundNotifyResult.loadReqInfo(xmlDecryptedReqInfo);
+      assertEquals(refundNotifyResult.getReqInfo().getRefundFee().intValue(), 15);
+      assertEquals(refundNotifyResult.getReqInfo().getRefundStatus(), "SUCCESS");
+      assertEquals(refundNotifyResult.getReqInfo().getRefundRecvAccout(), "用户零钱");
+      System.out.println(refundNotifyResult);
+    } finally {
+      XmlConfig.fastMode = false;
+    }
+  }
+
 }
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResultTest.java
index 04853e15a2..3d77eb34ae 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResultTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/notify/WxScanPayNotifyResultTest.java
@@ -1,5 +1,6 @@
 package com.github.binarywang.wxpay.bean.notify;
 
+import com.github.binarywang.wxpay.util.XmlConfig;
 import org.testng.annotations.*;
 
 import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
@@ -50,4 +51,38 @@ public void testFromXML() {
     assertThat(result.getSign()).isEqualTo("C380BEC2BFD727A4B6845133519F3AD6");
   }
 
+
+  /**
+   * Test from xml.
+   * fast mode.
+   */
+  @Test
+  public void testFromXMLFastMode() {
+    String xmlString = "\n" +
+      "  \n" +
+      "  \n" +
+      "  \n" +
+      "  \n" +
+      "  \n" +
+      "  \n" +
+      "  \n" +
+      "";
+
+    XmlConfig.fastMode = true;
+    try {
+      WxScanPayNotifyResult result = BaseWxPayResult.fromXML(xmlString, WxScanPayNotifyResult.class);
+
+      assertThat(result).isNotNull();
+
+      assertThat(result.getAppid()).isEqualTo("wx8888888888888888");
+      assertThat(result.getOpenid()).isEqualTo("o8GeHuLAsgefS_80exEr1cTqekUs");
+      assertThat(result.getMchId()).isEqualTo("1900000109");
+      assertThat(result.getNonceStr()).isEqualTo("5K8264ILTKCH16CQ2502SI8ZNMTM67VS");
+      assertThat(result.getProductId()).isEqualTo("88888");
+      assertThat(result.getSign()).isEqualTo("C380BEC2BFD727A4B6845133519F3AD6");
+    } finally {
+      XmlConfig.fastMode = false;
+    }
+  }
+
 }
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResultTest.java
index b771cbb1d5..617e2afdf4 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResultTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRedpackQueryResultTest.java
@@ -1,5 +1,6 @@
 package com.github.binarywang.wxpay.bean.result;
 
+import com.github.binarywang.wxpay.util.XmlConfig;
 import org.testng.annotations.*;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -42,8 +43,8 @@ public void testFromXML() {
       "\n" +
       "";
 
-    WxPayRedpackQueryResult orderQueryResult = WxPayRedpackQueryResult.fromXML(xmlString, WxPayRedpackQueryResult.class);
-    System.out.println(orderQueryResult);
+    WxPayRedpackQueryResult orderQueryResult = BaseWxPayResult.fromXML(xmlString, WxPayRedpackQueryResult.class);
+//    System.out.println(orderQueryResult);
     assertThat(orderQueryResult).isNotNull();
 
     assertThat(orderQueryResult.getRedpackList()).isNotEmpty();
@@ -51,4 +52,65 @@ public void testFromXML() {
     assertThat(orderQueryResult.getRedpackList().get(0).getOpenid()).isEqualTo("o3yHF0uHuckI3yE6lwWiFQBQdVDI");
     assertThat(orderQueryResult.getRedpackList().get(0).getReceiveTime()).isEqualTo("2018-01-23 13:45:31");
   }
+
+  /**
+   * Test from xml.
+   * FastMode
+   */
+  @Test
+  public void testFromXMLFastMode() {
+    XmlConfig.fastMode = true;
+    String xmlString = "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "1\n" +
+      "100\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "100\n" +
+      "\n" +
+      "\n" +
+      "\n" +
+      "";
+
+    try {
+      WxPayRedpackQueryResult orderQueryResult = BaseWxPayResult.fromXML(xmlString, WxPayRedpackQueryResult.class);
+//      System.out.println(orderQueryResult);
+      assertThat(orderQueryResult).isNotNull();
+
+      assertThat(orderQueryResult.getRedpackList()).isNotEmpty();
+      assertThat(orderQueryResult.getRedpackList().get(0).getAmount()).isEqualTo(100);
+      assertThat(orderQueryResult.getRedpackList().get(0).getOpenid()).isEqualTo("o3yHF0uHuckI3yE6lwWiFQBQdVDI");
+      assertThat(orderQueryResult.getRedpackList().get(0).getReceiveTime()).isEqualTo("2018-01-23 13:45:31");
+    } finally {
+      XmlConfig.fastMode = false;
+    }
+  }
+
+  @Test
+  void benchmark() {
+    long now = System.currentTimeMillis();
+    int loops = 10000;
+    for (int i = 0; i < loops; i++) {
+      testFromXML();
+    }
+    System.out.println(" reflect mode:\t" + (System.currentTimeMillis() - now) + " (ms) ");
+
+    now = System.currentTimeMillis();
+    for (int i = 0; i < loops; i++) {
+      testFromXMLFastMode();
+    }
+    System.out.println(" fast    mode:\t" + (System.currentTimeMillis() - now) + " (ms) ");
+  }
 }
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResultTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResultTest.java
index 730bd37a09..e03028ad42 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResultTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/result/WxPayRefundResultTest.java
@@ -1,5 +1,6 @@
 package com.github.binarywang.wxpay.bean.result;
 
+import com.github.binarywang.wxpay.util.XmlConfig;
 import org.testng.annotations.Test;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -40,11 +41,67 @@ public void testFromXML() {
       "   2 \n" +
       "";
 
-    WxPayRefundResult result = WxPayRefundResult.fromXML(xmlString);
-
+    WxPayRefundResult result = BaseWxPayResult.fromXML(xmlString, WxPayRefundResult.class);
+    result.composeRefundCoupons();
     assertThat(result.getRefundCoupons()).isNotEmpty();
     assertThat(result.getRefundCoupons().get(0).getCouponRefundId()).isEqualTo("123");
     assertThat(result.getRefundCoupons().get(0).getCouponType()).isEqualTo("CASH");
     assertThat(result.getRefundCoupons().get(0).getCouponRefundFee()).isEqualTo(1);
   }
+
+  @Test
+  public void testFromXMLFastMode() {
+    /*
+      该xml字符串来自于官方文档示例,稍加改造,加上代金卷
+      refund_channel 是个什么鬼,官方文档只字不提
+     */
+    String xmlString = "\n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   \n" +
+      "   1\n" +
+      "   1\n" +
+      "   123\n" +
+      "   1\n" +
+      "   \n" +
+      "   2 \n" +
+      "";
+    XmlConfig.fastMode = true;
+    try {
+      WxPayRefundResult result = BaseWxPayResult.fromXML(xmlString, WxPayRefundResult.class);
+      result.composeRefundCoupons();
+      assertThat(result.getRefundCoupons()).isNotEmpty();
+      assertThat(result.getRefundCoupons().get(0).getCouponRefundId()).isEqualTo("123");
+      assertThat(result.getRefundCoupons().get(0).getCouponType()).isEqualTo("CASH");
+      assertThat(result.getRefundCoupons().get(0).getCouponRefundFee()).isEqualTo(1);
+    } finally {
+      XmlConfig.fastMode = false;
+    }
+  }
+
+  @Test
+  void benchmark() {
+    long now = System.currentTimeMillis();
+    int loops = 10000;
+    for (int i = 0; i < loops; i++) {
+      testFromXML();
+    }
+    System.out.println(" reflect mode:\t" + (System.currentTimeMillis() - now) + " (ms) ");
+
+    now = System.currentTimeMillis();
+    for (int i = 0; i < loops; i++) {
+      testFromXMLFastMode();
+    }
+    System.out.println(" fast    mode:\t" + (System.currentTimeMillis() - now) + " (ms) ");
+  }
+
 }
diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java
index d6e688cf50..ab850d0b5b 100644
--- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java
+++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java
@@ -17,6 +17,7 @@
 import com.github.binarywang.wxpay.service.WxPayService;
 import com.github.binarywang.wxpay.testbase.ApiTestModule;
 import com.github.binarywang.wxpay.testbase.XmlWxPayConfig;
+import com.github.binarywang.wxpay.util.XmlConfig;
 import com.google.inject.Inject;
 import lombok.extern.slf4j.Slf4j;
 import org.slf4j.Logger;
@@ -566,8 +567,18 @@ public void testParseOrderNotifyResult() throws Exception {
       "   200\n" +
       "";
 
-    WxPayOrderNotifyResult result = this.payService.parseOrderNotifyResult(xmlString);
+    XmlConfig.fastMode = true;
+    WxPayOrderNotifyResult result;
+    try {
+      result = BaseWxPayResult.fromXML(xmlString, WxPayOrderNotifyResult.class);
+      System.out.println(result);
+    } finally {
+      XmlConfig.fastMode = false;
+    }
+
+    result = this.payService.parseOrderNotifyResult(xmlString);
     System.out.println(result);
+
   }
 
   /**

From e9efa900a906823e99d3e499545b7a1026844507 Mon Sep 17 00:00:00 2001
From: outersky 
Date: Fri, 31 Jan 2020 21:27:02 +0800
Subject: [PATCH 0050/1706] =?UTF-8?q?:new:=20#1392=20=E5=A2=9E=E5=8A=A0wei?=
 =?UTF-8?q?xin-graal=E6=A8=A1=E5=9D=97=EF=BC=8C=E9=85=8D=E5=90=88graal?=
 =?UTF-8?q?=E4=BB=A5=E4=BA=A7=E7=94=9Fnative-image=E9=85=8D=E7=BD=AE?=
 =?UTF-8?q?=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

目的:解决native-image中gson功能无效的问题。

可以通过项目的 native-image Profile 来启用:
mvn -P native-image -Dmaven.test.skip=true clean source:jar install

编译时会在各包中增加2个文件:
META-INF/native-image/.../reflection-config.json
META-INF/native-image/.../native-image.properties
---
 pom.xml                                       |   9 +
 weixin-graal/pom.xml                          |  40 +++++
 .../binarywang/wx/graal/GraalProcessor.java   | 167 ++++++++++++++++++
 .../javax.annotation.processing.Processor     |   1 +
 weixin-java-common/pom.xml                    |  38 +++-
 weixin-java-cp/pom.xml                        |  32 ++++
 weixin-java-miniapp/pom.xml                   |  43 ++++-
 weixin-java-mp/pom.xml                        |  31 ++++
 weixin-java-open/pom.xml                      |  30 ++++
 weixin-java-pay/pom.xml                       |  31 ++++
 10 files changed, 413 insertions(+), 9 deletions(-)
 create mode 100644 weixin-graal/pom.xml
 create mode 100644 weixin-graal/src/main/java/cn/binarywang/wx/graal/GraalProcessor.java
 create mode 100644 weixin-graal/src/main/resources/META-INF/services/javax.annotation.processing.Processor

diff --git a/pom.xml b/pom.xml
index 0c59ce8784..cf41040dce 100644
--- a/pom.xml
+++ b/pom.xml
@@ -99,6 +99,7 @@
   
 
   
+    weixin-graal
     weixin-java-common
     weixin-java-cp
     weixin-java-mp
@@ -331,6 +332,14 @@
         
       
     
+
+    
+      native-image
+      
+        false
+      
+    
+
   
 
   
diff --git a/weixin-graal/pom.xml b/weixin-graal/pom.xml
new file mode 100644
index 0000000000..07f03ddd71
--- /dev/null
+++ b/weixin-graal/pom.xml
@@ -0,0 +1,40 @@
+
+
+  4.0.0
+  
+    com.github.binarywang
+    wx-java
+    3.6.7.B
+  
+
+  weixin-graal
+  WxJava - Graal
+  微信开发Java内部配合graal以产生native-image配置的辅助工具, 可以通过项目的 native-image Profile 来启用: mvn -P native-image ...
+  
+
+  
+
+    
+      org.projectlombok
+      lombok
+      compile
+    
+
+  
+
+  
+    
+      
+        org.apache.maven.plugins
+        maven-compiler-plugin
+        3.5.1
+        
+          none
+        
+      
+    
+  
+
+
diff --git a/weixin-graal/src/main/java/cn/binarywang/wx/graal/GraalProcessor.java b/weixin-graal/src/main/java/cn/binarywang/wx/graal/GraalProcessor.java
new file mode 100644
index 0000000000..c09190c3c5
--- /dev/null
+++ b/weixin-graal/src/main/java/cn/binarywang/wx/graal/GraalProcessor.java
@@ -0,0 +1,167 @@
+package cn.binarywang.wx.graal;
+
+import lombok.Data;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.tools.FileObject;
+import javax.tools.StandardLocation;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+// 目前仅仅处理@Data,且必须在lombok自己的processor之前执行,千万注意!!!!!
+@SupportedAnnotationTypes("lombok.Data")
+@SupportedSourceVersion(SourceVersion.RELEASE_7)
+public class GraalProcessor extends AbstractProcessor {
+
+  private static final String REFLECTION_CONFIG_JSON = "reflection-config.json";
+  private static final String NATIVE_IMAGE_PROPERTIES = "native-image.properties";
+
+  private SortedSet classSet = new TreeSet<>();
+  private String shortestPackageName = null;
+
+  @Override
+  public boolean process(Set annotations, RoundEnvironment roundEnv) {
+    for (TypeElement annotatedClass : ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(Data.class))) {
+
+      registerClass(annotatedClass.getQualifiedName().toString());
+      handleSuperClass(annotatedClass);
+    }
+
+    //只有最后一轮才可以写文件,否则文件会被重复打开,报错!
+    if (!roundEnv.processingOver()) return false;
+
+    // 如果没有文件要写,跳过
+    if (classSet.isEmpty()) return false;
+
+    writeFiles();
+
+    //必须返回false,以便让lombok能继续处理。
+    return false;
+  }
+
+  /**
+   * 设置当前最短的package名称
+   *
+   * @param packageName 包名
+   */
+  private void setShortestPackageName(String packageName) {
+    if (shortestPackageName == null) {
+      shortestPackageName = packageName;
+    } else if (packageName.length() < shortestPackageName.length()) {
+      shortestPackageName = packageName;
+    }
+  }
+
+  /**
+   * 更加完整的类名来获取package名称
+   *
+   * @param fullClassName 完整的类名
+   * @return package name
+   */
+  private String getPackageName(String fullClassName) {
+    int last = fullClassName.lastIndexOf('.');
+    if (last == -1) return fullClassName;
+    return fullClassName.substring(0, last);
+  }
+
+  /**
+   * 保存文件
+   * META-INF/native-image/.../reflection-config.json
+   * META-INF/native-image/.../native-image.properties
+   */
+  private void writeFiles() {
+    String basePackage = shortestPackageName;
+
+    String module;
+    if (basePackage.contains(".")) {
+      final int i = basePackage.lastIndexOf('.');
+      module = basePackage.substring(i + 1);
+      basePackage = basePackage.substring(0, i);
+    } else {
+      module = basePackage;
+    }
+
+    String path = "META-INF/native-image/" + basePackage + "/" + module + "/";
+    String reflectFile = path + REFLECTION_CONFIG_JSON;
+    String propsFile = path + NATIVE_IMAGE_PROPERTIES;
+    try {
+      FileObject fileObject = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", propsFile);
+      Writer writer = fileObject.openWriter();
+      writer.append("Args = -H:ReflectionConfigurationResources=${.}/" + REFLECTION_CONFIG_JSON);
+      writer.close();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+
+    try {
+      FileObject fileObject = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", reflectFile);
+      Writer writer = fileObject.openWriter();
+      writer.write("[\n");
+      boolean first = true;
+      for (String name : classSet) {
+        if (first) {
+          first = false;
+        } else {
+          writer.write(",");
+        }
+        writer.write(assetGraalJsonElement(name));
+        writer.append('\n');
+      }
+      writer.write("]");
+      writer.close();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+
+  }
+
+  private String assetGraalJsonElement(String className) {
+    return "{\n" +
+      "  \"name\" : \"" + className + "\",\n" +
+      "  \"allDeclaredFields\":true,\n" +
+      "  \"allDeclaredMethods\":true,\n" +
+      "  \"allDeclaredConstructors\":true,\n" +
+      "  \"allPublicMethods\" : true\n" +
+      "}";
+  }
+
+  /**
+   * 登记一个class
+   *
+   * @param className 完整的类名
+   */
+  private void registerClass(String className) {
+    classSet.add(className);
+    setShortestPackageName(getPackageName(className));
+  }
+
+  /**
+   * 获取一个类型的所有的父类,并登记
+   *
+   * @param typeElement 类型元素
+   */
+  private void handleSuperClass(TypeElement typeElement) {
+    TypeMirror superclass = typeElement.getSuperclass();
+    if (superclass.getKind() == TypeKind.DECLARED) {
+      TypeElement s = (TypeElement) ((DeclaredType) superclass).asElement();
+      String sName = s.toString();
+      // ignore java.**/javax.**
+      if (sName.startsWith("java.") || sName.startsWith("javax.")) return;
+      registerClass(sName);
+      handleSuperClass(s);
+    }
+  }
+
+}
diff --git a/weixin-graal/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/weixin-graal/src/main/resources/META-INF/services/javax.annotation.processing.Processor
new file mode 100644
index 0000000000..fed7c4d9cd
--- /dev/null
+++ b/weixin-graal/src/main/resources/META-INF/services/javax.annotation.processing.Processor
@@ -0,0 +1 @@
+cn.binarywang.wx.graal.GraalProcessor
diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml
index e67c4ac84d..5ddd463e03 100644
--- a/weixin-java-common/pom.xml
+++ b/weixin-java-common/pom.xml
@@ -1,7 +1,7 @@
 
-
+
   4.0.0
   
     com.github.binarywang
@@ -134,4 +134,36 @@
     
   
 
+  
+    
+      native-image
+      
+        false
+      
+
+      
+        
+          
+            org.apache.maven.plugins
+            maven-compiler-plugin
+            3.5.1
+            
+              
+                cn.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor
+              
+              
+                
+                  com.github.binarywang
+                  weixin-graal
+                  ${project.version}
+                
+              
+            
+          
+        
+      
+
+    
+  
+
 
diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml
index 0ea2cfb523..01dadb3207 100644
--- a/weixin-java-cp/pom.xml
+++ b/weixin-java-cp/pom.xml
@@ -95,4 +95,36 @@
     
   
 
+  
+    
+      native-image
+      
+        false
+      
+
+      
+        
+          
+            org.apache.maven.plugins
+            maven-compiler-plugin
+            3.5.1
+            
+              
+                cn.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor
+              
+              
+                
+                  com.github.binarywang
+                  weixin-graal
+                  ${project.version}
+                
+              
+            
+          
+        
+      
+
+    
+  
+
 
diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml
index 9c555a58dd..7bbe8e2392 100644
--- a/weixin-java-miniapp/pom.xml
+++ b/weixin-java-miniapp/pom.xml
@@ -80,12 +80,12 @@
       org.projectlombok
       lombok
     
- 	
-	  com.github.jedis-lock
-	  jedis-lock
-	  1.0.0
-	  true
-	
+    
+      com.github.jedis-lock
+      jedis-lock
+      1.0.0
+      true
+    
   
 
   
@@ -102,4 +102,35 @@
     
   
 
+  
+    
+      native-image
+      
+        false
+      
+
+      
+        
+          
+            org.apache.maven.plugins
+            maven-compiler-plugin
+            3.5.1
+            
+              
+                cn.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor
+              
+              
+                
+                  com.github.binarywang
+                  weixin-graal
+                  ${project.version}
+                
+              
+            
+          
+        
+      
+    
+  
+
 
diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml
index 2cbf9967ed..a4b1eee7e0 100644
--- a/weixin-java-mp/pom.xml
+++ b/weixin-java-mp/pom.xml
@@ -96,4 +96,35 @@
     
   
 
+  
+    
+      native-image
+      
+        false
+      
+
+      
+        
+          
+            org.apache.maven.plugins
+            maven-compiler-plugin
+            3.5.1
+            
+              
+                cn.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor
+              
+              
+                
+                  com.github.binarywang
+                  weixin-graal
+                  ${project.version}
+                
+              
+            
+          
+        
+      
+    
+  
+
 
diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml
index 150cb7b38a..9800e53ec4 100644
--- a/weixin-java-open/pom.xml
+++ b/weixin-java-open/pom.xml
@@ -107,5 +107,35 @@
     
   
 
+  
+    
+      native-image
+      
+        false
+      
+
+      
+        
+          
+            org.apache.maven.plugins
+            maven-compiler-plugin
+            3.5.1
+            
+              
+                cn.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor
+              
+              
+                
+                  com.github.binarywang
+                  weixin-graal
+                  ${project.version}
+                
+              
+            
+          
+        
+      
+    
+  
 
 
diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml
index 2b28f5c24b..2fd3745ffa 100644
--- a/weixin-java-pay/pom.xml
+++ b/weixin-java-pay/pom.xml
@@ -72,4 +72,35 @@
     
   
 
+  
+    
+      native-image
+      
+        false
+      
+
+      
+        
+          
+            org.apache.maven.plugins
+            maven-compiler-plugin
+            3.5.1
+            
+              
+                cn.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor
+              
+              
+                
+                  com.github.binarywang
+                  weixin-graal
+                  ${project.version}
+                
+              
+            
+          
+        
+      
+    
+  
+
 

From 438f8e5fb0cd140853149fa1abda6d39299d75ad Mon Sep 17 00:00:00 2001
From: Binary Wang 
Date: Sat, 1 Feb 2020 18:01:46 +0800
Subject: [PATCH 0051/1706] =?UTF-8?q?:new:=20#1214=20=E5=B0=8F=E7=A8=8B?=
 =?UTF-8?q?=E5=BA=8F=E6=A8=A1=E5=9D=97=E5=AE=9E=E7=8E=B0=E4=BA=91=E5=BC=80?=
 =?UTF-8?q?=E5=8F=91=E7=9A=84=E6=89=80=E6=9C=89=E7=9B=B8=E5=85=B3=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/common/error/WxMaErrorMsgEnum.java |   2 +
 .../wx/miniapp/api/WxMaCloudService.java      | 317 ++++++++++++++++++
 .../wx/miniapp/api/WxMaService.java           |   5 +
 .../api/impl/WxMaCloudServiceImpl.java        | 178 ++++++++++
 .../wx/miniapp/api/impl/WxMaServiceImpl.java  |   6 +
 .../cloud/WxCloudBatchDeleteFileResult.java   |  44 +++
 .../cloud/WxCloudBatchDownloadFileResult.java |  50 +++
 ...udCloudDatabaseMigrateQueryInfoResult.java |  47 +++
 .../WxCloudDatabaseCollectionGetResult.java   |  86 +++++
 .../WxCloudDatabaseCreateIndexRequest.java    |  59 ++++
 .../cloud/WxCloudDatabaseQueryResult.java     |  51 +++
 .../cloud/WxCloudDatabaseUpdateResult.java    |  32 ++
 .../cloud/WxCloudGetQcloudTokenResult.java    |  41 +++
 .../bean/cloud/WxCloudUploadFileResult.java   |  47 +++
 .../api/impl/WxMaCloudServiceImplTest.java    | 224 +++++++++++++
 15 files changed, 1189 insertions(+)
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaCloudService.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaCloudServiceImpl.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudBatchDeleteFileResult.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudBatchDownloadFileResult.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudCloudDatabaseMigrateQueryInfoResult.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudDatabaseCollectionGetResult.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudDatabaseCreateIndexRequest.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudDatabaseQueryResult.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudDatabaseUpdateResult.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudGetQcloudTokenResult.java
 create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudUploadFileResult.java
 create mode 100644 weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaCloudServiceImplTest.java

diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMaErrorMsgEnum.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMaErrorMsgEnum.java
index a6fbe052e3..eced6027e9 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMaErrorMsgEnum.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/error/WxMaErrorMsgEnum.java
@@ -463,6 +463,8 @@ public enum WxMaErrorMsgEnum {
   CODE_85003(85003, "微信号绑定的小程序体验者达到上限"),
 
   CODE_85004(85004, "微信号已经绑定"),
+
+//  CODE_504002(-504002, "云函数未找到 Function not found"),
   ;
 
   private int code;
diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaCloudService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaCloudService.java
new file mode 100644
index 0000000000..7e59e6ec6f
--- /dev/null
+++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaCloudService.java
@@ -0,0 +1,317 @@
+package cn.binarywang.wx.miniapp.api;
+
+import cn.binarywang.wx.miniapp.bean.cloud.*;
+import com.google.gson.JsonArray;
+import me.chanjar.weixin.common.error.WxErrorException;
+
+import java.util.List;
+
+/**
+ * 云开发相关接口.
+ *
+ * @author Binary Wang
+ * @date 2020-01-22
+ */
+public interface WxMaCloudService {
+  String INVOKE_CLOUD_FUNCTION_URL = "https://api.weixin.qq.com/tcb/invokecloudfunction?env=%s&name=%s";
+  String DATABASE_COLLECTION_GET_URL = "https://api.weixin.qq.com/tcb/databasecollectionget";
+  String DATABASE_COLLECTION_DELETE_URL = "https://api.weixin.qq.com/tcb/databasecollectiondelete";
+  String DATABASE_COLLECTION_ADD_URL = "https://api.weixin.qq.com/tcb/databasecollectionadd";
+  String GET_QCLOUD_TOKEN_URL = "https://api.weixin.qq.com/tcb/getqcloudtoken";
+  String BATCH_DELETE_FILE_URL = "https://api.weixin.qq.com/tcb/batchdeletefile";
+  String UPLOAD_FILE_URL = "https://api.weixin.qq.com/tcb/uploadfile";
+  String DATABASE_MIGRATE_QUERY_INFO_URL = "https://api.weixin.qq.com/tcb/databasemigratequeryinfo";
+  String DATABASE_MIGRATE_EXPORT_URL = "https://api.weixin.qq.com/tcb/databasemigrateexport";
+  String DATABASE_MIGRATE_IMPORT_URL = "https://api.weixin.qq.com/tcb/databasemigrateimport";
+  String UPDATE_INDEX_URL = "https://api.weixin.qq.com/tcb/updateindex";
+  String DATABASE_COUNT_URL = "https://api.weixin.qq.com/tcb/databasecount";
+  String DATABASE_AGGREGATE_URL = "https://api.weixin.qq.com/tcb/databaseaggregate";
+  String DATABASE_QUERY_URL = "https://api.weixin.qq.com/tcb/databasequery";
+  String DATABASE_UPDATE_URL = "https://api.weixin.qq.com/tcb/databaseupdate";
+  String DATABASE_DELETE_URL = "https://api.weixin.qq.com/tcb/databasedelete";
+  String DATABASE_ADD_URL = "https://api.weixin.qq.com/tcb/databaseadd";
+
+  /**
+   * 
+   * 触发云函数。注意:HTTP API 途径触发云函数不包含用户信息。
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/functions/invokeCloudFunction.html
+   *
+   * 请求地址
+   * POST https://api.weixin.qq.com/tcb/invokecloudfunction?access_token=ACCESS_TOKEN&env=ENV&name=FUNCTION_NAME
+   *
+   * 
+ * + * @param env string 是 云开发环境ID + * @param name string 是 云函数名称 + * @param body string 是 云函数的传入参数,具体结构由开发者定义。 + * @return resp_data string 云函数返回的buffer + * @throws WxErrorException . + */ + String invokeCloudFunction(String env, String name, String body) throws WxErrorException; + + /** + *
+   * 数据库插入记录
+   *
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseAdd.html
+   * 请求地址:POST https://api.weixin.qq.com/tcb/databaseadd?access_token=ACCESS_TOKEN
+   * 
+ * + * @param env 云环境ID + * @param query 数据库操作语句 + * @return 插入成功的数据集合主键_id + * @throws WxErrorException . + */ + JsonArray databaseAdd(String env, String query) throws WxErrorException; + + /** + *
+   * 数据库删除记录
+   *
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseDelete.html
+   * 请求地址:POST https://api.weixin.qq.com/tcb/databasedelete?access_token=ACCESS_TOKEN
+   * 
+ * + * @param env 云环境ID + * @param query 数据库操作语句 + * @return 删除记录数量 + * @throws WxErrorException . + */ + int databaseDelete(String env, String query) throws WxErrorException; + + /** + *
+   * 数据库更新记录
+   *
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseUpdate.html
+   * 请求地址:POST https://api.weixin.qq.com/tcb/databaseupdate?access_token=ACCESS_TOKEN
+   * 
+ * + * @param env 云环境ID + * @param query 数据库操作语句 + * @return . + * @throws WxErrorException . + */ + WxCloudDatabaseUpdateResult databaseUpdate(String env, String query) throws WxErrorException; + + /** + *
+   * 数据库查询记录
+   *
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseQuery.html
+   * 请求地址:POST https://api.weixin.qq.com/tcb/databasequery?access_token=ACCESS_TOKEN
+   * 
+ * + * @param env 云环境ID + * @param query 数据库操作语句 + * @return . + * @throws WxErrorException . + */ + WxCloudDatabaseQueryResult databaseQuery(String env, String query) throws WxErrorException; + + /** + *
+   * 数据库聚合记录
+   *
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseAggregate.html
+   * 请求地址:POST https://api.weixin.qq.com/tcb/databaseaggregate?access_token=ACCESS_TOKEN
+   * 
+ * + * @param env 云环境ID + * @param query 数据库操作语句 + * @return . + * @throws WxErrorException . + */ + JsonArray databaseAggregate(String env, String query) throws WxErrorException; + + /** + *
+   * 统计集合记录数或统计查询语句对应的结果记录数
+   *
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseCount.html
+   * 请求地址:POST https://api.weixin.qq.com/tcb/databasecount?access_token=ACCESS_TOKEN
+   * 
+ * + * @param env 云环境ID + * @param query 数据库操作语句 + * @return 记录数量 + * @throws WxErrorException . + */ + Long databaseCount(String env, String query) throws WxErrorException; + + /** + *
+   * 变更数据库索引
+   *
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/updateIndex.html
+   * 请求地址:POST https://api.weixin.qq.com/tcb/updateindex?access_token=ACCESS_TOKEN
+   * 
+ * + * @param env 云环境ID + * @param collectionName 集合名称 + * @param createIndexes 新增索引对象 + * @param dropIndexNames 要删除的索引的名字 + * @throws WxErrorException . + */ + void updateIndex(String env, String collectionName, List createIndexes, + List dropIndexNames) throws WxErrorException; + + /** + *
+   * 数据库导入
+   *
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseMigrateImport.html
+   * 请求地址: POST https://api.weixin.qq.com/tcb/databasemigrateimport?access_token=ACCESS_TOKEN
+   * 
+ * + * @param env 云环境ID + * @param collectionName 导入collection名 + * @param filePath 导入文件路径(导入文件需先上传到同环境的存储中,可使用开发者工具或 HTTP API的上传文件 API上传) + * @param fileType 导入文件类型, 1 JSON, 2 CSV + * @param stopOnError 是否在遇到错误时停止导入 + * @param conflictMode 冲突处理模式 : 1 INSERT , 2 UPSERT + * @return jobId + * @throws WxErrorException . + */ + Long databaseMigrateImport(String env, String collectionName, String filePath, int fileType, boolean stopOnError, + int conflictMode) throws WxErrorException; + + /** + *
+   * 数据库导出
+   *
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseMigrateExport.html
+   * 请求地址: POST https://api.weixin.qq.com/tcb/databasemigrateexport?access_token=ACCESS_TOKEN
+   * 
+ * + * @param env 云环境ID + * @param filePath 导出文件路径(文件会导出到同环境的云存储中,可使用获取下载链接 API 获取下载链接) + * @param fileType 导出文件类型, 1 JSON, 2 CSV + * @param query 导出条件 + * @return jobId + * @throws WxErrorException . + */ + Long databaseMigrateExport(String env, String filePath, int fileType, String query) throws WxErrorException; + + /** + *
+   *   数据库迁移状态查询
+   *
+   *  文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseMigrateQueryInfo.html
+   *  请求地址:POST https://api.weixin.qq.com/tcb/databasemigratequeryinfo?access_token=ACCESS_TOKEN
+   * 
+ * + * @param env 云环境ID + * @param jobId 迁移任务ID + * @return . + * @throws WxErrorException . + */ + WxCloudCloudDatabaseMigrateQueryInfoResult databaseMigrateQueryInfo(String env, Long jobId) throws WxErrorException; + + /** + *
+   * 获取文件上传链接
+   *
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/storage/uploadFile.html
+   * 请求地址:POST https://api.weixin.qq.com/tcb/uploadfile?access_token=ACCESS_TOKEN
+   *
+   * 
+ * + * @param env 云环境ID + * @param path 上传路径 + * @return 上传结果 + * @throws WxErrorException . + */ + WxCloudUploadFileResult uploadFile(String env, String path) throws WxErrorException; + + /** + *
+   * 获取文件下载链接
+   *
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/storage/batchDownloadFile.html
+   * 请求地址:POST https://api.weixin.qq.com/tcb/batchdownloadfile?access_token=ACCESS_TOKEN
+   *
+   * 
+ * + * @param env 云环境ID + * @param fileIds 文件ID列表 + * @param maxAges 下载链接有效期列表,对应文件id列表 + * @return 下载链接信息 + * @throws WxErrorException . + */ + WxCloudBatchDownloadFileResult batchDownloadFile(String env, String[] fileIds, long[] maxAges) throws WxErrorException; + + /** + *
+   * 删除文件
+   *
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/storage/batchDeleteFile.html
+   * 请求地址:POST https://api.weixin.qq.com/tcb/batchdeletefile?access_token=ACCESS_TOKEN
+   *
+   * 
+ * + * @param env 云环境ID + * @param fileIds 文件ID列表 + * @return 下载链接信息 + * @throws WxErrorException . + */ + WxCloudBatchDeleteFileResult batchDeleteFile(String env, String[] fileIds) throws WxErrorException; + + /** + *
+   *  获取腾讯云API调用凭证
+   *
+   *  文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/utils/getQcloudToken.html
+   *  请求地址:POST https://api.weixin.qq.com/tcb/getqcloudtoken?access_token=ACCESS_TOKEN
+   * 
+ * + * @param lifeSpan 有效期(单位为秒,最大7200) + * @return . + * @throws WxErrorException . + */ + WxCloudGetQcloudTokenResult getQcloudToken(long lifeSpan) throws WxErrorException; + + /** + *
+   * 新增集合
+   *
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseCollectionAdd.html
+   * 请求地址:POST https://api.weixin.qq.com/tcb/databasecollectionadd?access_token=ACCESS_TOKEN
+   * 
+ * + * @param env 云环境ID + * @param collectionName 集合名称 + * @throws WxErrorException . + */ + void databaseCollectionAdd(String env, String collectionName) throws WxErrorException; + + /** + *
+   * 删除集合
+   *
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseCollectionDelete.html
+   * 请求地址:POST https://api.weixin.qq.com/tcb/databasecollectionadd?access_token=ACCESS_TOKEN
+   * 
+ * + * @param env 云环境ID + * @param collectionName 集合名称 + * @throws WxErrorException . + */ + void databaseCollectionDelete(String env, String collectionName) throws WxErrorException; + + /** + *
+   * 获取特定云环境下集合信息
+   *
+   * 文档地址:https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-http-api/database/databaseCollectionGet.html
+   * 请求地址:POST https://api.weixin.qq.com/tcb/databasecollectionget?access_token=ACCESS_TOKEN
+   * 
+ * + * @param env 云环境ID + * @param limit 获取数量限制,默认值:10 + * @param offset 偏移量,默认值:0 + * @return . + * @throws WxErrorException . + */ + WxCloudDatabaseCollectionGetResult databaseCollectionGet(String env, Long limit, Long offset) throws WxErrorException; +} 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 d4f74683e0..80150968dc 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 @@ -242,4 +242,9 @@ public interface WxMaService { * @return */ WxMaExpressService getExpressService(); + + /** + * 获取云开发接口服务对象 + */ + WxMaCloudService getCloudService(); } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaCloudServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaCloudServiceImpl.java new file mode 100644 index 0000000000..984185649c --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaCloudServiceImpl.java @@ -0,0 +1,178 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaCloudService; +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.cloud.*; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Lists; +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.error.WxErrorException; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 云开发相关接口实现类. + * + * @author Binary Wang + * @date 2020-01-22 + */ +@Slf4j +@RequiredArgsConstructor +public class WxMaCloudServiceImpl implements WxMaCloudService { + private static final JsonParser JSON_PARSER = new JsonParser(); + private final WxMaService wxMaService; + + @Override + public String invokeCloudFunction(String env, String name, String body) throws WxErrorException { + final String response = this.wxMaService.post(String.format(INVOKE_CLOUD_FUNCTION_URL, env, name), body); + return JSON_PARSER.parse(response).getAsJsonObject().get("resp_data").getAsString(); + } + + @Override + public JsonArray databaseAdd(String env, String query) throws WxErrorException { + String response = this.wxMaService.post(DATABASE_ADD_URL, ImmutableMap.of("env", env, "query", query)); + return JSON_PARSER.parse(response).getAsJsonObject().get("id_list").getAsJsonArray(); + } + + @Override + public int databaseDelete(String env, String query) throws WxErrorException { + String response = this.wxMaService.post(DATABASE_DELETE_URL, ImmutableMap.of("env", env, "query", query)); + return JSON_PARSER.parse(response).getAsJsonObject().get("deleted").getAsInt(); + } + + @Override + public WxCloudDatabaseUpdateResult databaseUpdate(String env, String query) throws WxErrorException { + String response = this.wxMaService.post(DATABASE_UPDATE_URL, ImmutableMap.of("env", env, "query", query)); + return WxGsonBuilder.create().fromJson(response, WxCloudDatabaseUpdateResult.class); + } + + @Override + public WxCloudDatabaseQueryResult databaseQuery(String env, String query) throws WxErrorException { + String response = this.wxMaService.post(DATABASE_QUERY_URL, ImmutableMap.of("env", env, "query", query)); + return WxGsonBuilder.create().fromJson(response, WxCloudDatabaseQueryResult.class); + } + + @Override + public JsonArray databaseAggregate(String env, String query) throws WxErrorException { + String response = this.wxMaService.post(DATABASE_AGGREGATE_URL, ImmutableMap.of("env", env, "query", query)); + return JSON_PARSER.parse(response).getAsJsonObject().get("data").getAsJsonArray(); + } + + @Override + public Long databaseCount(String env, String query) throws WxErrorException { + String response = this.wxMaService.post(DATABASE_COUNT_URL, ImmutableMap.of("env", env, "query", query)); + return JSON_PARSER.parse(response).getAsJsonObject().get("count").getAsLong(); + } + + @Override + public void updateIndex(String env, String collectionName, List createIndexes, + List dropIndexNames) throws WxErrorException { + List> dropIndexes = Lists.newArrayList(); + if (dropIndexNames != null) { + for (String index : dropIndexNames) { + dropIndexes.add(ImmutableMap.of("name", index)); + } + } + + this.wxMaService.post(UPDATE_INDEX_URL, ImmutableMap.of("env", env, + "collection_name", collectionName, "create_indexes", createIndexes, "drop_indexes", dropIndexes)); + } + + @Override + public Long databaseMigrateImport(String env, String collectionName, String filePath, int fileType, + boolean stopOnError, int conflictMode) throws WxErrorException { + JsonObject params = new JsonObject(); + params.addProperty("env", env); + params.addProperty("collection_name", collectionName); + params.addProperty("file_path", filePath); + params.addProperty("file_type", fileType); + params.addProperty("stop_on_error", stopOnError); + params.addProperty("conflict_mode", conflictMode); + + String response = this.wxMaService.post(DATABASE_MIGRATE_IMPORT_URL, params.toString()); + return JSON_PARSER.parse(response).getAsJsonObject().get("job_id").getAsLong(); + } + + @Override + public Long databaseMigrateExport(String env, String filePath, int fileType, String query) throws WxErrorException { + JsonObject params = new JsonObject(); + params.addProperty("env", env); + params.addProperty("file_path", filePath); + params.addProperty("file_type", fileType); + params.addProperty("query", query); + + String response = this.wxMaService.post(DATABASE_MIGRATE_EXPORT_URL, params.toString()); + return JSON_PARSER.parse(response).getAsJsonObject().get("job_id").getAsLong(); + } + + @Override + public WxCloudCloudDatabaseMigrateQueryInfoResult databaseMigrateQueryInfo(String env, Long jobId) throws WxErrorException { + String response = this.wxMaService.post(DATABASE_MIGRATE_QUERY_INFO_URL, ImmutableMap.of("env", env, "job_id", jobId)); + return WxGsonBuilder.create().fromJson(response, WxCloudCloudDatabaseMigrateQueryInfoResult.class); + } + + @Override + public WxCloudUploadFileResult uploadFile(String env, String path) throws WxErrorException { + String response = this.wxMaService.post(UPLOAD_FILE_URL, ImmutableMap.of("env", env, "path", path)); + return WxGsonBuilder.create().fromJson(response, WxCloudUploadFileResult.class); + } + + @Override + public WxCloudBatchDownloadFileResult batchDownloadFile(String env, String[] fileIds, long[] maxAges) throws WxErrorException { + List> fileList = Lists.newArrayList(); + int i = 0; + for (String fileId : fileIds) { + fileList.add(ImmutableMap.of("fileid", fileId, "max_age", (Serializable) maxAges[i++])); + } + + String response = this.wxMaService.post(GET_QCLOUD_TOKEN_URL, ImmutableMap.of("env", env, "file_list", fileList)); + return WxGsonBuilder.create().fromJson(response, WxCloudBatchDownloadFileResult.class); + } + + @Override + public WxCloudBatchDeleteFileResult batchDeleteFile(String env, String[] fileIds) throws WxErrorException { + String response = this.wxMaService.post(BATCH_DELETE_FILE_URL, ImmutableMap.of("env", env, "fileid_list", fileIds)); + return WxGsonBuilder.create().fromJson(response, WxCloudBatchDeleteFileResult.class); + } + + @Override + public WxCloudGetQcloudTokenResult getQcloudToken(long lifeSpan) throws WxErrorException { + String response = this.wxMaService.post(GET_QCLOUD_TOKEN_URL, ImmutableMap.of("lifespan", lifeSpan)); + return WxGsonBuilder.create().fromJson(response, WxCloudGetQcloudTokenResult.class); + } + + @Override + public void databaseCollectionAdd(String env, String collectionName) throws WxErrorException { + this.wxMaService.post(DATABASE_COLLECTION_ADD_URL, ImmutableMap.of("env", env, "collection_name", collectionName)); + } + + @Override + public void databaseCollectionDelete(String env, String collectionName) throws WxErrorException { + this.wxMaService.post(DATABASE_COLLECTION_DELETE_URL, ImmutableMap.of("env", env, "collection_name", collectionName)); + } + + @Override + public WxCloudDatabaseCollectionGetResult databaseCollectionGet(String env, Long limit, Long offset) throws WxErrorException { + Map params = new HashMap<>(2); + params.put("env", env); + if (limit != null) { + params.put("limit", limit); + } + + if (offset != null) { + params.put("offset", offset); + } + + String response = this.wxMaService.post(DATABASE_COLLECTION_GET_URL, params); + return WxGsonBuilder.create().fromJson(response, WxCloudDatabaseCollectionGetResult.class); + } + +} 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 38ce9cc4a3..537364f288 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 @@ -57,6 +57,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttpBinary Wang + * @date 2020-01-27 + */ +@Data +public class WxCloudBatchDeleteFileResult implements Serializable { + private static final long serialVersionUID = -1133274298839868115L; + + @SerializedName("delete_list") + private List fileList; + + @Data + public static class FileDownloadInfo implements Serializable { + private static final long serialVersionUID = 5812969045277862211L; + + /** + * fileid string 文件ID + */ + @SerializedName("fileid") + private String fileId; + + /** + * status number 状态码 + */ + @SerializedName("status") + private Integer status; + + /** + * errmsg string 该文件错误信息 + */ + @SerializedName("errmsg") + private String errMsg; + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudBatchDownloadFileResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudBatchDownloadFileResult.java new file mode 100644 index 0000000000..1519e72318 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudBatchDownloadFileResult.java @@ -0,0 +1,50 @@ +package cn.binarywang.wx.miniapp.bean.cloud; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 获取文件下载链接结果. + * + * @author Binary Wang + * @date 2020-01-27 + */ +@Data +public class WxCloudBatchDownloadFileResult implements Serializable { + private static final long serialVersionUID = 646423661372964402L; + + @SerializedName("file_list") + private List fileList; + + @Data + public static class FileDownloadInfo implements Serializable { + private static final long serialVersionUID = 5812969045277862211L; + + /** + * fileid string 文件ID + */ + @SerializedName("fileid") + private String fileId; + + /** + * download_url string 下载链接 + */ + @SerializedName("download_url") + private String downloadUrl; + + /** + * status number 状态码 + */ + @SerializedName("status") + private Integer status; + + /** + * errmsg string 该文件错误信息 + */ + @SerializedName("errmsg") + private String errMsg; + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudCloudDatabaseMigrateQueryInfoResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudCloudDatabaseMigrateQueryInfoResult.java new file mode 100644 index 0000000000..b2639c5545 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudCloudDatabaseMigrateQueryInfoResult.java @@ -0,0 +1,47 @@ +package cn.binarywang.wx.miniapp.bean.cloud; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 云开发数据库迁移状态查询结果. + * + * @author Binary Wang + * @date 2020-01-26 + */ +@Data +public class WxCloudCloudDatabaseMigrateQueryInfoResult implements Serializable { + private static final long serialVersionUID = 2014197503355968243L; + + /** + * status string 导出状态 + */ + private String status; + + /** + * record_success number 导出成功记录数 + */ + @SerializedName("record_success") + private Integer recordSuccess; + + /** + * record_fail number 导出失败记录数 + */ + @SerializedName("record_fail") + private Integer recordFail; + + /** + * err_msg string 导出错误信息 + */ + @SerializedName("err_msg") + private String errMsg; + + /** + * file_url string 导出文件下载地址 + */ + @SerializedName("file_url") + private String fileUrl; + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudDatabaseCollectionGetResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudDatabaseCollectionGetResult.java new file mode 100644 index 0000000000..347762b4c1 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudDatabaseCollectionGetResult.java @@ -0,0 +1,86 @@ +package cn.binarywang.wx.miniapp.bean.cloud; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 云开发获取集合接口的结果. + * + * @author Binary Wang + * @date 2020-01-28 + */ +@Data +public class WxCloudDatabaseCollectionGetResult implements Serializable { + private static final long serialVersionUID = 3702855196387039823L; + + /** + * 分页信息 + */ + private WxCloudDatabaseQueryResult.Pager pager; + + /** + * 查询结果 + */ + private CollectionInfo[] collections; + + @Data + public static class CollectionInfo implements Serializable { + private static final long serialVersionUID = -3280126948752330438L; + + /** + * name string 集合名 + */ + @SerializedName("name") + private String name; + + /** + * count number 表中文档数量 + */ + @SerializedName("count") + private Long count; + + /** + * size number 表的大小(即表中文档总大小),单位:字节 + */ + @SerializedName("size") + private Long size; + + /** + * index_count number 索引数量 + */ + @SerializedName("index_count") + private Long indexCount; + + /** + * index_size number 索引占用大小,单位:字节 + */ + @SerializedName("index_size") + private Long indexSize; + } + + @Data + public static class Pager implements Serializable { + private static final long serialVersionUID = 5045727687673687839L; + + /** + * Offset number 偏移 + */ + @SerializedName("Offset") + private Long offset; + + /** + * Limit number 单次查询限制 + */ + @SerializedName("Limit") + private Long limit; + + /** + * Total number 符合查询条件的记录总数 + */ + @SerializedName("Total") + private Long total; + + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudDatabaseCreateIndexRequest.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudDatabaseCreateIndexRequest.java new file mode 100644 index 0000000000..fbdba099f7 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudDatabaseCreateIndexRequest.java @@ -0,0 +1,59 @@ +package cn.binarywang.wx.miniapp.bean.cloud; + +import lombok.Builder; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.List; + +/** + * 云开发新增索引的请求对象. + * + * @author Binary Wang + * @date 2020-01-26 + */ +@Accessors(chain = true) +@Data +public class WxCloudDatabaseCreateIndexRequest implements Serializable { + private static final long serialVersionUID = -8308393731157121109L; + + /** + * name string 是 索引名 + */ + private String name; + + /** + * unique boolean 是 是否唯一 + */ + private boolean unique; + + /** + * keys Array. 是 索引字段 + */ + private List keys; + + @Data + @Accessors(chain = true) + public static class IndexKey implements Serializable { + private static final long serialVersionUID = -252641130547960325L; + + /** + * name string 是 字段名 + */ + private String name; + + /** + * direction string 是 字段排序 + *
+     *   direction 的合法值
+     * 值	说明
+     * "1"	升序
+     * "-1"	降序
+     * "2dsphere"	地理位置
+     *
+     * 
+ */ + private String direction; + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudDatabaseQueryResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudDatabaseQueryResult.java new file mode 100644 index 0000000000..19ca4dce1f --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudDatabaseQueryResult.java @@ -0,0 +1,51 @@ +package cn.binarywang.wx.miniapp.bean.cloud; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 云开发数据库查询记录接口请求结果. + * + * @author Binary Wang + * @date 2020-01-26 + */ +@Data +public class WxCloudDatabaseQueryResult implements Serializable { + private static final long serialVersionUID = 8291820029137872536L; + + /** + * 分页信息 + */ + private Pager pager; + + /** + * 查询结果 + */ + private String[] data; + + @Data + public static class Pager implements Serializable{ + private static final long serialVersionUID = 8556239063823985674L; + + /** + * Offset number 偏移 + */ + @SerializedName("Offset") + private Long offset; + + /** + * Limit number 单次查询限制 + */ + @SerializedName("Limit") + private Long limit; + + /** + * Total number 符合查询条件的记录总数 + */ + @SerializedName("Total") + private Long total; + + } +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudDatabaseUpdateResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudDatabaseUpdateResult.java new file mode 100644 index 0000000000..000774132f --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudDatabaseUpdateResult.java @@ -0,0 +1,32 @@ +package cn.binarywang.wx.miniapp.bean.cloud; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 云开发数据库更新记录接口请求结果. + * + * @author Binary Wang + * @date 2020-01-26 + */ +@Data +public class WxCloudDatabaseUpdateResult implements Serializable { + private static final long serialVersionUID = -3905429931117999004L; + + /** + * matched number 更新条件匹配到的结果数 + */ + private Long matched; + + /** + * modified number 修改的记录数,注意:使用set操作新插入的数据不计入修改数目 + */ + private Long modified; + + /** + * id string 新插入记录的id,注意:只有使用set操作新插入数据时这个字段会有值 + */ + private String id; + +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudGetQcloudTokenResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudGetQcloudTokenResult.java new file mode 100644 index 0000000000..f2b8bf0a1d --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudGetQcloudTokenResult.java @@ -0,0 +1,41 @@ +package cn.binarywang.wx.miniapp.bean.cloud; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 获取腾讯云API调用凭证结果. + * + * @author Binary Wang + * @date 2020-01-27 + */ +@Data +public class WxCloudGetQcloudTokenResult implements Serializable { + private static final long serialVersionUID = -1505786395531138286L; + + /** + * secretid + */ + @SerializedName("secretid") + private String secretId; + + /** + * secretkey + */ + @SerializedName("secretkey") + private String secretKey; + + /** + * token + */ + @SerializedName("token") + private String token; + + /** + * 过期时间戳 + */ + @SerializedName("expired_time") + private Long expiredTime; +} diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudUploadFileResult.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudUploadFileResult.java new file mode 100644 index 0000000000..300ae86200 --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/cloud/WxCloudUploadFileResult.java @@ -0,0 +1,47 @@ +package cn.binarywang.wx.miniapp.bean.cloud; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +import java.io.Serializable; + +/** + * 云开发文件上传接口响应结果. + * + * @author Binary Wang + * @date 2020-01-27 + */ +@Data +public class WxCloudUploadFileResult implements Serializable { + private static final long serialVersionUID = 787346474470048318L; + + /** + * 上传url + */ + @SerializedName("url") + private String url; + + /** + * token + */ + @SerializedName("token") + private String token; + + /** + * authorization + */ + @SerializedName("authorization") + private String authorization; + + /** + * 文件ID + */ + @SerializedName("file_id") + private String fileId; + + /** + * cos文件ID + */ + @SerializedName("cos_file_id") + private String cosFileId; +} diff --git a/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaCloudServiceImplTest.java b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaCloudServiceImplTest.java new file mode 100644 index 0000000000..c3e008fe8d --- /dev/null +++ b/weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaCloudServiceImplTest.java @@ -0,0 +1,224 @@ +package cn.binarywang.wx.miniapp.api.impl; + +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.cloud.*; +import cn.binarywang.wx.miniapp.test.ApiTestModule; +import com.google.common.collect.Lists; +import com.google.gson.JsonArray; +import com.google.inject.Inject; +import me.chanjar.weixin.common.error.WxErrorException; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * 测试类. + * + * @author Binary Wang + * @date 2020-01-22 + */ +@Guice(modules = ApiTestModule.class) +public class WxMaCloudServiceImplTest { + @Inject + private WxMaService wxMaService; + + @Test + public void testInvokeCloudFunction() throws WxErrorException { + final String result = this.wxMaService.getCloudService().invokeCloudFunction("rcn", "login", "{}"); + assertThat(result).isNotNull(); + } + + @Test + public void testDatabaseAdd() throws WxErrorException { + JsonArray array = this.wxMaService.getCloudService().databaseAdd("rcn", "db.collection(\"geo\").add({\n" + + " data: [{\n" + + " description: \"item1\",\n" + + " due:\n" + + " new Date(\"2019-09-09\"),\n" + + " tags: [\n" + + " \"cloud\",\n" + + " \"database\"\n" + + " ],\n" + + " location:\n" + + " new db.Geo.Point(113, 23),\n" + + " done:false\n" + + " },\n" + + " {\n" + + " description: \"item2\",\n" + + " due:\n" + + " new Date(\"2019-09-09\"),\n" + + " tags: [\n" + + " \"cloud\",\n" + + " \"database\"\n" + + " ],\n" + + " location:\n" + + " new db.Geo.Point(113, 23),\n" + + " done:false\n" + + " }\n" + + " ]\n" + + " })"); + + System.out.println(array); + assertThat(array).isNotEmpty(); + } + + @Test + public void testDatabaseDelete() throws WxErrorException { + final int result = this.wxMaService.getCloudService().databaseDelete("rcn", + "db.collection(\"geo\").doc(\"056120a7-c89e-4616-95bf-dfc9a11daa3b\").remove()"); + assertThat(result).isEqualTo(0); + } + + @Test + public void testDatabaseUpdate() throws WxErrorException { + final WxCloudDatabaseUpdateResult result = this.wxMaService.getCloudService().databaseUpdate("rcn", + "db.collection(\"geo\").where({description:\"item1\"}).update({data:{age: _.inc(1)}})"); + assertThat(result).isNotNull(); + assertThat(result.getMatched()).isGreaterThan(0); + assertThat(result.getId()).isEmpty(); + assertThat(result.getModified()).isGreaterThan(0); + } + + @Test + public void testDatabaseQuery() throws WxErrorException { + final WxCloudDatabaseQueryResult result = this.wxMaService.getCloudService().databaseQuery("rcn", + "db.collection(\"geo\").where({done:false}).limit(10).skip(1).get()"); + assertThat(result).isNotNull(); + assertThat(result.getPager()).isNotNull(); + assertThat(result.getPager().getLimit()).isEqualTo(10); + assertThat(result.getPager().getOffset()).isEqualTo(1); + assertThat(result.getPager().getTotal()).isGreaterThan(0); + assertThat(result.getData().length).isGreaterThan(0); + } + + @Test + public void testDatabaseAggregate() throws WxErrorException { + final JsonArray result = this.wxMaService.getCloudService().databaseAggregate("rcn", + "db.collection(\"geo\").aggregate().match({tags:\"cloud\"}).limit(10).end()"); + assertThat(result).isNotNull(); + } + + @Test + public void testDatabaseCount() throws WxErrorException { + final Long result = this.wxMaService.getCloudService().databaseCount("rcn", + "db.collection(\"geo\").where({done:false}).count()"); + assertThat(result).isGreaterThan(0); + } + + @Test + public void testUpdateIndex() throws WxErrorException { + this.wxMaService.getCloudService().updateIndex("rcn", "geo", + Lists.newArrayList(new WxCloudDatabaseCreateIndexRequest() + .setName("drop_index") + .setUnique(true) + .setKeys(Lists.newArrayList(new WxCloudDatabaseCreateIndexRequest.IndexKey().setDirection("2dsphere").setName("test")) + )), + Lists.newArrayList("add_index2")); + } + + @Test + public void testDatabaseMigrateImport() throws WxErrorException { + final Long result = this.wxMaService.getCloudService().databaseMigrateImport("rcn", "geo", "test.json", + 1, true, 1); + assertThat(result).isGreaterThan(0); + } + + @Test + public void testDatabaseMigrateExport() throws WxErrorException { + final Long result = this.wxMaService.getCloudService().databaseMigrateExport("rcn", "test.json", 1, + "const Point = db.Geo.Point;db.collection('geo').where({age: _.gt(1)}).limit(10).skip(1).orderBy('age','asc').orderBy('name', 'desc')" + + ".field({ name: true }).get()"); + assertThat(result).isGreaterThan(0); + } + + @Test + public void testDatabaseMigrateQueryInfo() throws WxErrorException { + final WxCloudCloudDatabaseMigrateQueryInfoResult result = this.wxMaService.getCloudService() + .databaseMigrateQueryInfo("rcn", 476629L); + assertThat(result).isNotNull(); + System.out.println(result.getFileUrl()); + } + + @Test + public void testUploadFile() throws WxErrorException { + final WxCloudUploadFileResult result = this.wxMaService.getCloudService().uploadFile("rcn", "E:\\MyDocs\\Desktop\\test.json"); + + assertThat(result).isNotNull(); + assertThat(result.getAuthorization()).isNotNull(); + assertThat(result.getToken()).isNotNull(); + assertThat(result.getUrl()).isNotNull(); + assertThat(result.getFileId()).isNotNull(); + assertThat(result.getCosFileId()).isNotNull(); + + } + + @Test + public void testBatchDownloadFile() throws WxErrorException { + final WxCloudBatchDownloadFileResult result = this.wxMaService.getCloudService().batchDownloadFile("rcn", + new String[]{"cloud://rcn.7263-rcn-1258788140/Snipaste_2019-11-13_00-21-27.png", "cloud://rcn.7263-rcn-1258788140/avatar.jpg"}, + new long[]{7200, 6800}); + + assertThat(result).isNotNull(); + assertThat(result.getFileList()).isNotNull(); + assertThat(result.getFileList().size()).isGreaterThan(0); + assertThat(result.getFileList().get(0).getDownloadUrl()).isNotNull(); + assertThat(result.getFileList().get(0).getErrMsg()).isEqualTo("ok"); + assertThat(result.getFileList().get(0).getStatus()).isEqualTo(0); + assertThat(result.getFileList().get(0).getFileId()).isNotNull(); + + } + + @Test + public void testBatchDeleteFile() throws WxErrorException { + final WxCloudBatchDeleteFileResult result = this.wxMaService.getCloudService().batchDeleteFile("rcn", + new String[]{"cloud://rcn.7263-rcn-1258788140/test.json"}); + + assertThat(result).isNotNull(); + assertThat(result.getFileList()).isNotNull(); + assertThat(result.getFileList().size()).isGreaterThan(0); + assertThat(result.getFileList().get(0).getErrMsg()).isEqualTo("ok"); + assertThat(result.getFileList().get(0).getStatus()).isEqualTo(0); + assertThat(result.getFileList().get(0).getFileId()).isNotNull(); + } + + @Test + public void testGetQcloudToken() throws WxErrorException { + final WxCloudGetQcloudTokenResult result = this.wxMaService.getCloudService().getQcloudToken(1800); + + assertThat(result).isNotNull(); + assertThat(result.getSecretId()).isNotNull(); + assertThat(result.getSecretKey()).isNotNull(); + assertThat(result.getToken()).isNotNull(); + assertThat(result.getExpiredTime()).isNotNull(); + } + + @Test + public void testDatabaseCollectionAdd() throws WxErrorException { + this.wxMaService.getCloudService().databaseCollectionAdd("rcn","test_add_collection"); + } + + @Test + public void testDatabaseCollectionDelete() throws WxErrorException { + this.wxMaService.getCloudService().databaseCollectionAdd("rcn","test_delete_collection"); + this.wxMaService.getCloudService().databaseCollectionDelete("rcn","test_delete_collection"); + } + + @Test + public void testDatabaseCollectionGet() throws WxErrorException { + final WxCloudDatabaseCollectionGetResult result = this.wxMaService.getCloudService().databaseCollectionGet("rcn", null, null); + + assertThat(result).isNotNull(); + assertThat(result.getPager()).isNotNull(); + assertThat(result.getPager().getLimit()).isEqualTo(10); + assertThat(result.getPager().getOffset()).isEqualTo(0); + assertThat(result.getPager().getTotal()).isGreaterThan(0); + + assertThat(result.getCollections().length).isGreaterThan(0); + assertThat(result.getCollections()[0].getCount()).isGreaterThan(0); + assertThat(result.getCollections()[0].getName()).isNotNull(); + assertThat(result.getCollections()[0].getSize()).isGreaterThan(0); + assertThat(result.getCollections()[0].getIndexCount()).isGreaterThan(0); + assertThat(result.getCollections()[0].getIndexSize()).isGreaterThan(0); + } +} From 47061bde2b6e99d46608fc8c9637ecd918485bfd Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 1 Feb 2020 19:45:43 +0800 Subject: [PATCH 0052/1706] =?UTF-8?q?:bookmark:=20=E5=8F=91=E5=B8=833.6.8.?= =?UTF-8?q?B=E6=B5=8B=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 +- spring-boot-starters/pom.xml | 2 +- .../wx-java-miniapp-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml | 2 +- weixin-graal/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 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index cf41040dce..0ae8aacc1b 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.github.binarywang wx-java - 3.6.7.B + 3.6.8.B pom WxJava - Weixin/Wechat Java SDK 微信开发Java SDK diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml index b5952c3516..2a3b61d117 100644 --- a/spring-boot-starters/pom.xml +++ b/spring-boot-starters/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 3.6.7.B + 3.6.8.B pom wx-java-spring-boot-starters diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml index fe7e70f2e4..f43fd4c122 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.7.B + 3.6.8.B 4.0.0 diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml index 811ca73ef7..7cc34343e0 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.7.B + 3.6.8.B 4.0.0 diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml index a56def678f..dfeb28ebdf 100644 --- a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.7.B + 3.6.8.B 4.0.0 diff --git a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml index 89c2a6d73e..5cb1c82ce2 100644 --- a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.7.B + 3.6.8.B 4.0.0 diff --git a/weixin-graal/pom.xml b/weixin-graal/pom.xml index 07f03ddd71..bb17bb7073 100644 --- a/weixin-graal/pom.xml +++ b/weixin-graal/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 3.6.7.B + 3.6.8.B weixin-graal diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 5ddd463e03..82f0989346 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 3.6.7.B + 3.6.8.B weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 01dadb3207..ab505995b1 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.7.B + 3.6.8.B weixin-java-cp diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index 7bbe8e2392..938438f214 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.7.B + 3.6.8.B weixin-java-miniapp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index a4b1eee7e0..29eaf3be9d 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.7.B + 3.6.8.B weixin-java-mp diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index 9800e53ec4..bfcfc05090 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.7.B + 3.6.8.B weixin-java-open diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index 2fd3745ffa..9d496a7d7c 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ com.github.binarywang wx-java - 3.6.7.B + 3.6.8.B 4.0.0 From 94064752abfed263f2d329dc01a245a3cc30162a Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Thu, 13 Feb 2020 17:51:59 +0800 Subject: [PATCH 0053/1706] =?UTF-8?q?:new:=20#1397=20=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E9=80=9A=E8=AE=AF=E5=BD=95=E6=88=90=E5=91=98?= =?UTF-8?q?=E7=B1=BBWxCpUser=E5=A2=9E=E5=8A=A0alias=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/me/chanjar/weixin/cp/bean/WxCpUser.java | 13 +++++++++---- .../weixin/cp/util/json/WxCpUserGsonAdapter.java | 4 ++++ .../cp/util/json/WxCpUserGsonAdapterTest.java | 2 ++ 3 files changed, 15 insertions(+), 4 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 a47d2a2a0f..90354154a6 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 @@ -1,15 +1,15 @@ package me.chanjar.weixin.cp.bean; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; - import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + /** * 微信用户信息. * @@ -28,6 +28,7 @@ public class WxCpUser implements Serializable { private String email; private String avatar; private String thumbAvatar; + /** * 地址。长度最大128个字符 */ @@ -35,6 +36,10 @@ public class WxCpUser implements Serializable { private String avatarMediaId; private Integer status; private Integer enable; + /** + * 别名;第三方仅通讯录应用可获取 + */ + private String alias; private Integer isLeader; /** * is_leader_in_dept. 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 8dfeb1d752..5128405a47 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 @@ -71,6 +71,7 @@ public WxCpUser deserialize(JsonElement json, Type typeOfT, JsonDeserializationC user.setAvatarMediaId(GsonHelper.getString(o, "avatar_mediaid")); user.setStatus(GsonHelper.getInteger(o, "status")); user.setEnable(GsonHelper.getInteger(o, "enable")); + user.setAlias(GsonHelper.getString(o, "alias")); user.setIsLeader(GsonHelper.getInteger(o, "isleader")); user.setIsLeaderInDept(GsonHelper.getIntArray(o, "is_leader_in_dept")); user.setHideMobile(GsonHelper.getInteger(o, "hide_mobile")); @@ -203,6 +204,9 @@ public JsonElement serialize(WxCpUser user, Type typeOfSrc, JsonSerializationCon if (user.getEnable() != null) { o.addProperty("enable", user.getEnable()); } + if (user.getAlias() != null) { + o.addProperty("alias", user.getAlias()); + } if (user.getIsLeader() != null) { o.addProperty("isleader", user.getIsLeader()); } 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 d17700220d..abfb8a4617 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 @@ -83,6 +83,7 @@ public void testDeserialize() { assertThat(user.getOrders()[1]).isEqualTo(2); assertThat(user.getAddress()).isEqualTo("广州市海珠区新港中路"); + assertThat(user.getAlias()).isEqualTo("jackzhang"); assertThat(user.getExternalAttrs()).isNotEmpty(); final WxCpUser.ExternalAttribute externalAttr1 = user.getExternalAttrs().get(0); @@ -102,6 +103,7 @@ public void testDeserialize() { assertThat(externalAttr3.getAppid()).isEqualTo("wx8bd80126147df384"); assertThat(externalAttr3.getPagePath()).isEqualTo("/index"); assertThat(externalAttr3.getTitle()).isEqualTo("my miniprogram"); + } @Test From f90f4540d7e10ca8dca26b3999f618871782d132 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 16 Feb 2020 16:02:36 +0800 Subject: [PATCH 0054/1706] =?UTF-8?q?:new:=20#252=20=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=9B=BE=E6=96=87=E6=B6=88=E6=81=AF=E7=95=99=E8=A8=80=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=9A=84=E4=BA=94=E4=B8=AA=E6=8E=A5=E5=8F=A3=EF=BC=8C?= =?UTF-8?q?=E5=8C=85=E6=8B=AC=E6=A0=87=E8=AE=B0=E5=8F=8A=E5=8F=96=E6=B6=88?= =?UTF-8?q?=E8=AF=84=E8=AE=BA=E4=B8=BA=E7=B2=BE=E9=80=89=E3=80=81=E5=88=A0?= =?UTF-8?q?=E9=99=A4=E8=AF=84=E8=AE=BA=E3=80=81=E6=B7=BB=E5=8A=A0=E5=8F=8A?= =?UTF-8?q?=E5=88=A0=E9=99=A4=E5=9B=9E=E5=A4=8D=E7=AD=89=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/mp/api/WxMpCommentService.java | 56 +++++++++++++++++++ .../mp/api/impl/WxMpCommentServiceImpl.java | 43 ++++++++++++++ .../chanjar/weixin/mp/enums/WxMpApiUrl.java | 27 ++++++++- .../api/impl/WxMpCommentServiceImplTest.java | 27 ++++++++- 4 files changed, 150 insertions(+), 3 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCommentService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCommentService.java index 1d96c968ae..c4ba7ca326 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCommentService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCommentService.java @@ -44,4 +44,60 @@ public interface WxMpCommentService { * @throws WxErrorException 异常 */ WxMpCommentListVo list(String msgDataId, Integer index, int begin, int count, int type) throws WxErrorException; + + /** + * 2.4 将评论标记精选. + * 接口调用请求: POST https://api.weixin.qq.com/cgi-bin/comment/markelect?access_token=ACCESS_TOKEN + * + * @param msgDataId 群发返回的msg_data_id + * @param index 多图文时,用来指定第几篇图文,从0开始,不带默认操作该msg_data_id的第一篇图文 + * @param userCommentId 用户评论id + * @throws WxErrorException 异常 + */ + void markElect(String msgDataId, Integer index, Long userCommentId) throws WxErrorException; + + /** + * 2.5 将评论取消精选. + * 接口调用请求: POST https://api.weixin.qq.com/cgi-bin/comment/unmarkelect?access_token=ACCESS_TOKEN + * + * @param msgDataId 群发返回的msg_data_id + * @param index 多图文时,用来指定第几篇图文,从0开始,不带默认操作该msg_data_id的第一篇图文 + * @param userCommentId 用户评论id + * @throws WxErrorException 异常 + */ + void unmarkElect(String msgDataId, Integer index, Long userCommentId) throws WxErrorException; + + /** + * 2.6 删除评论. + * 接口调用请求: POST https://api.weixin.qq.com/cgi-bin/comment/delete?access_token=ACCESS_TOKEN + * + * @param msgDataId 群发返回的msg_data_id + * @param index 多图文时,用来指定第几篇图文,从0开始,不带默认操作该msg_data_id的第一篇图文 + * @param userCommentId 用户评论id + * @throws WxErrorException 异常 + */ + void delete(String msgDataId, Integer index, Long userCommentId) throws WxErrorException; + + /** + * 2.7 回复评论. + * 接口调用请求: POST https://api.weixin.qq.com/cgi-bin/comment/reply/add?access_token=ACCESS_TOKEN + * + * @param msgDataId 群发返回的msg_data_id + * @param index 多图文时,用来指定第几篇图文,从0开始,不带默认操作该msg_data_id的第一篇图文 + * @param userCommentId 用户评论id + * @param content 回复内容 + * @throws WxErrorException 异常 + */ + void replyAdd(String msgDataId, Integer index, Long userCommentId, String content) throws WxErrorException; + + /** + * 2.8 删除回复. + * 接口调用请求: POST https://api.weixin.qq.com/cgi-bin/comment/reply/delete?access_token=ACCESS_TOKEN + * + * @param msgDataId 群发返回的msg_data_id + * @param index 多图文时,用来指定第几篇图文,从0开始,不带默认操作该msg_data_id的第一篇图文 + * @param userCommentId 用户评论id + * @throws WxErrorException 异常 + */ + void replyDelete(String msgDataId, Integer index, Long userCommentId) throws WxErrorException; } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImpl.java index 02315cc206..8f287a80f1 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImpl.java @@ -53,4 +53,47 @@ public WxMpCommentListVo list(String msgDataId, Integer index, int begin, int co return WxMpCommentListVo.fromJson(this.wxMpService.post(LIST, json.toString())); } + + @Override + public void markElect(String msgDataId, Integer index, Long userCommentId) throws WxErrorException { + JsonObject json = this.buildJson(msgDataId, index, userCommentId); + this.wxMpService.post(MARK_ELECT, json.toString()); + } + + @Override + public void unmarkElect(String msgDataId, Integer index, Long userCommentId) throws WxErrorException { + JsonObject json = this.buildJson(msgDataId, index, userCommentId); + this.wxMpService.post(UNMARK_ELECT, json.toString()); + } + + @Override + public void delete(String msgDataId, Integer index, Long userCommentId) throws WxErrorException { + JsonObject json = this.buildJson(msgDataId, index, userCommentId); + + this.wxMpService.post(DELETE, json.toString()); + } + + @Override + public void replyAdd(String msgDataId, Integer index, Long userCommentId, String content) throws WxErrorException { + JsonObject json = this.buildJson(msgDataId, index, userCommentId); + json.addProperty("content", content); + + this.wxMpService.post(REPLY_ADD, json.toString()); + } + + @Override + public void replyDelete(String msgDataId, Integer index, Long userCommentId) throws WxErrorException { + JsonObject json = this.buildJson(msgDataId, index, userCommentId); + this.wxMpService.post(REPLY_DELETE, json.toString()); + } + + private JsonObject buildJson(String msgDataId, Integer index, Long userCommentId) { + JsonObject json = new JsonObject(); + json.addProperty("msg_data_id", msgDataId); + json.addProperty("user_comment_id", userCommentId); + if (index != null) { + json.addProperty("index", index); + } + return json; + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java index c296481a80..cbe3d4df92 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/enums/WxMpApiUrl.java @@ -1002,7 +1002,32 @@ enum Comment implements WxMpApiUrl { /** * 查看指定文章的评论数据. */ - LIST(API_DEFAULT_HOST_URL, "/cgi-bin/comment/list"); + LIST(API_DEFAULT_HOST_URL, "/cgi-bin/comment/list"), + + /** + * 将评论标记精选. + */ + MARK_ELECT(API_DEFAULT_HOST_URL, "/cgi-bin/comment/markelect"), + + /** + * 将评论取消精选. + */ + UNMARK_ELECT(API_DEFAULT_HOST_URL, "/cgi-bin/comment/unmarkelect"), + + /** + * 删除评论. + */ + DELETE(API_DEFAULT_HOST_URL, "/cgi-bin/comment/delete"), + + /** + * 回复评论. + */ + REPLY_ADD(API_DEFAULT_HOST_URL, "/cgi-bin/comment/reply/add"), + + /** + * 删除回复. + */ + REPLY_DELETE(API_DEFAULT_HOST_URL, "/cgi-bin/comment/reply/delete"); private String prefix; private String path; diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImplTest.java index 5f4bdecfb9..8efb70f9e3 100644 --- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImplTest.java +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpCommentServiceImplTest.java @@ -9,9 +9,7 @@ import org.testng.annotations.Guice; import org.testng.annotations.Test; -import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Comment.LIST; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; @@ -74,4 +72,29 @@ public void testList() throws WxErrorException { assertThat(commentListVo.getComment().get(0).getReply()).isNotNull(); } + + @Test + public void testMarkElect() throws WxErrorException { + this.wxService.getCommentService().markElect("1000000001", null, 1L); + } + + @Test + public void testUnmarkElect() throws WxErrorException { + this.wxService.getCommentService().unmarkElect("1000000001", null, 1L); + } + + @Test + public void testDelete() throws WxErrorException { + this.wxService.getCommentService().delete("1000000001", null, 1L); + } + + @Test + public void testReplyAdd() throws WxErrorException { + this.wxService.getCommentService().replyAdd("1000000001", null, 1L, "haha"); + } + + @Test + public void testReplyADelete() throws WxErrorException { + this.wxService.getCommentService().replyDelete("1000000001", null, 1L); + } } From 27d88a752e29436948c5382bc3140d8a9781d8cf Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 17 Feb 2020 18:44:44 +0800 Subject: [PATCH 0055/1706] =?UTF-8?q?:new:=20#1290=20=E5=B0=8F=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F=E5=A2=9E=E5=8A=A0=E5=8A=A8=E6=80=81=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wx/miniapp/api/WxMaMsgService.java | 44 +++++++++-- .../miniapp/api/impl/WxMaMsgServiceImpl.java | 17 ++++- .../wx/miniapp/bean/WxMaUpdatableMsg.java | 76 +++++++++++++++++++ .../api/impl/WxMaMsgServiceImplTest.java | 38 ++++++++-- 4 files changed, 158 insertions(+), 17 deletions(-) create mode 100644 weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUpdatableMsg.java 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 2dc627eb97..43c28bb804 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 @@ -1,9 +1,7 @@ package cn.binarywang.wx.miniapp.api; -import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; -import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage; -import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; -import cn.binarywang.wx.miniapp.bean.WxMaUniformMessage; +import cn.binarywang.wx.miniapp.bean.*; +import com.google.gson.JsonObject; import me.chanjar.weixin.common.error.WxErrorException; /** @@ -18,6 +16,8 @@ public interface WxMaMsgService { String TEMPLATE_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send"; String SUBSCRIBE_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send"; String UNIFORM_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send"; + String ACTIVITY_ID_CREATE_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/activityid/create"; + String UPDATABLE_MSG_SEND_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/updatablemsg/send"; /** *
@@ -25,6 +25,10 @@ public interface WxMaMsgService {
    * 详情请见: 发送客服消息
    * 接口url格式:https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=ACCESS_TOKEN
    * 
+ * + * @param message 客服消息 + * @return . + * @throws WxErrorException . */ boolean sendKefuMsg(WxMaKefuMessage message) throws WxErrorException; @@ -53,13 +57,43 @@ public interface WxMaMsgService { */ void sendSubscribeMsg(WxMaSubscribeMessage subscribeMessage) throws WxErrorException; - /** *
    * 下发小程序和公众号统一的服务消息
    * 详情请见: 下发小程序和公众号统一的服务消息
    * 接口url格式:https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=ACCESS_TOKEN
    * 
+ * + * @param uniformMessage 消息 + * @throws WxErrorException . */ void sendUniformMsg(WxMaUniformMessage uniformMessage) throws WxErrorException; + + /** + *
+   *  创建被分享动态消息的 activity_id.
+   *  动态消息: https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share/updatable-message.html
+   *
+   *  文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/updatable-message/updatableMessage.createActivityId.html
+   *  接口地址:GET https://api.weixin.qq.com/cgi-bin/message/wxopen/activityid/create?access_token=ACCESS_TOKEN
+   * 
+ * + * @return . + * @throws WxErrorException . + */ + JsonObject createUpdatableMessageActivityId() throws WxErrorException; + + /** + *
+   *  修改被分享的动态消息.
+   *  动态消息: https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/share/updatable-message.html
+   *
+   *  文档地址:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/updatable-message/updatableMessage.setUpdatableMsg.html
+   *  接口地址:POST https://api.weixin.qq.com/cgi-bin/message/wxopen/activityid/create?access_token=ACCESS_TOKEN
+   * 
+ * + * @param msg 动态消息 + * @throws WxErrorException . + */ + void setUpdatableMsg(WxMaUpdatableMsg msg) throws WxErrorException; } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java index 1a059983e2..c9e229e9ef 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java @@ -2,11 +2,9 @@ import cn.binarywang.wx.miniapp.api.WxMaMsgService; import cn.binarywang.wx.miniapp.api.WxMaService; -import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage; -import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage; -import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage; -import cn.binarywang.wx.miniapp.bean.WxMaUniformMessage; +import cn.binarywang.wx.miniapp.bean.*; import cn.binarywang.wx.miniapp.constant.WxMaConstants; +import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import lombok.AllArgsConstructor; @@ -55,4 +53,15 @@ public void sendUniformMsg(WxMaUniformMessage uniformMessage) throws WxErrorExce } } + @Override + public JsonObject createUpdatableMessageActivityId() throws WxErrorException { + final String responseContent = this.wxMaService.get(ACTIVITY_ID_CREATE_URL, null); + return JSON_PARSER.parse(responseContent).getAsJsonObject(); + } + + @Override + public void setUpdatableMsg(WxMaUpdatableMsg msg) throws WxErrorException { + this.wxMaService.post(UPDATABLE_MSG_SEND_URL, WxMaGsonBuilder.create().toJson(msg)); + } + } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUpdatableMsg.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUpdatableMsg.java new file mode 100644 index 0000000000..98429b850c --- /dev/null +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUpdatableMsg.java @@ -0,0 +1,76 @@ +package cn.binarywang.wx.miniapp.bean; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.List; + +/** + * 动态消息. + * + * @author Binary Wang + * @date 2020-02-17 + */ +@Data +@Accessors(chain = true) +public class WxMaUpdatableMsg implements Serializable { + private static final long serialVersionUID = 6231957192034798165L; + + /** + * 动态消息的 ID,通过 updatableMessage.createActivityId 接口获取 + */ + @SerializedName("activity_id") + private String activityId; + + /** + * 动态消息修改后的状态 + * 0 未开始 + * 1 已开始 + */ + @SerializedName("target_state") + private Integer targetState; + + /** + * 动态消息对应的模板信息 + */ + @SerializedName("template_info") + private TemplateInfo templateInfo; + + @Data + @Accessors(chain = true) + public static class TemplateInfo implements Serializable { + private static final long serialVersionUID = -9218473401759062841L; + + /** + * 模板中需要修改的参数 + */ + @SerializedName("parameter_list") + private List parameterList; + } + + @Data + @Accessors(chain = true) + public static class Parameter implements Serializable { + private static final long serialVersionUID = 7444716050341038046L; + + /** + * 要修改的参数名 + *
+     * 合法值:
+     * member_count	target_state = 0 时必填,文字内容模板中 member_count 的值
+     * room_limit	target_state = 0 时必填,文字内容模板中 room_limit 的值
+     * path	target_state = 1 时必填,点击「进入」启动小程序时使用的路径。对于小游戏,没有页面的概念,可以用于传递查询字符串(query),如 "?foo=bar"
+     * version_type	target_state = 1 时必填,点击「进入」启动小程序时使用的版本。
+     * 有效参数值为:develop(开发版),trial(体验版),release(正式版)
+     * 
+ */ + private String name; + + /** + * 修改后的参数值 + */ + private String value; + } +} 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 132ea55e88..7ff22290ea 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 @@ -1,17 +1,20 @@ package cn.binarywang.wx.miniapp.api.impl; -import java.text.SimpleDateFormat; -import java.util.Date; - -import cn.binarywang.wx.miniapp.bean.*; -import org.testng.annotations.*; - import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.bean.*; import cn.binarywang.wx.miniapp.test.ApiTestModule; import cn.binarywang.wx.miniapp.test.TestConfig; import com.google.common.collect.Lists; +import com.google.gson.JsonObject; import com.google.inject.Inject; import me.chanjar.weixin.common.error.WxErrorException; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import static org.assertj.core.api.Assertions.assertThat; /** * 测试消息相关接口 @@ -25,7 +28,8 @@ public class WxMaMsgServiceImplTest { @Inject private WxMaService wxService; - public void testSendKefuMessage() throws WxErrorException { + @Test + public void testSendKefuMsg() throws WxErrorException { TestConfig config = (TestConfig) this.wxService.getWxMaConfig(); WxMaKefuMessage message = WxMaKefuMessage.newTextBuilder() .toUser(config.getOpenid()) @@ -74,7 +78,7 @@ public void testSendSubscribeMsg() throws WxErrorException { @Test public void testSendUniformMsg() throws WxErrorException { TestConfig config = (TestConfig) this.wxService.getWxMaConfig(); - WxMaUniformMessage message = WxMaUniformMessage.builder() + WxMaUniformMessage message = WxMaUniformMessage.builder() .isMpTemplateMsg(false) .toUser(config.getOpenid()) .page("page/page/index") @@ -89,4 +93,22 @@ public void testSendUniformMsg() throws WxErrorException { this.wxService.getMsgService().sendUniformMsg(message); } + + @Test + public void testCreateUpdatableMessageActivityId() throws WxErrorException { + final JsonObject jsonObject = this.wxService.getMsgService().createUpdatableMessageActivityId(); + assertThat(jsonObject).isNotNull(); + assertThat(jsonObject.get("activity_id")).isNotNull(); + System.out.println(jsonObject.get("activity_id")); + assertThat(jsonObject.get("expiration_time")).isNotNull(); + } + + @Test + public void testSetUpdatableMsg() throws WxErrorException { + this.wxService.getMsgService().setUpdatableMsg(new WxMaUpdatableMsg() + .setActivityId("1048_4f61uDloWPZl9pAs1dGx07vDiHKZ7FwJ0suohS1iMH5z8zhFktYk4nRqqBY~") + .setTargetState(1) + .setTemplateInfo(new WxMaUpdatableMsg.TemplateInfo() + .setParameterList(Lists.newArrayList(new WxMaUpdatableMsg.Parameter().setName("member_count").setValue("1"))))); + } } From 2e2d5ffb569ca56b26997239cd1846d999b9f86d Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 17 Feb 2020 19:30:06 +0800 Subject: [PATCH 0056/1706] =?UTF-8?q?:bookmark:=20=E5=8F=91=E5=B8=833.6.9.?= =?UTF-8?q?B=E6=B5=8B=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 +- spring-boot-starters/pom.xml | 2 +- .../wx-java-miniapp-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml | 2 +- weixin-graal/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 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index 0ae8aacc1b..07e03e4bc2 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.github.binarywang wx-java - 3.6.8.B + 3.6.9.B pom WxJava - Weixin/Wechat Java SDK 微信开发Java SDK diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml index 2a3b61d117..9b11ce2e7d 100644 --- a/spring-boot-starters/pom.xml +++ b/spring-boot-starters/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 3.6.8.B + 3.6.9.B pom wx-java-spring-boot-starters diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml index f43fd4c122..44cbd2e444 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.8.B + 3.6.9.B 4.0.0 diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml index 7cc34343e0..bbfda84944 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.8.B + 3.6.9.B 4.0.0 diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml index dfeb28ebdf..2bd472a14f 100644 --- a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.8.B + 3.6.9.B 4.0.0 diff --git a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml index 5cb1c82ce2..aecf3b9f7e 100644 --- a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.8.B + 3.6.9.B 4.0.0 diff --git a/weixin-graal/pom.xml b/weixin-graal/pom.xml index bb17bb7073..099b73c0bf 100644 --- a/weixin-graal/pom.xml +++ b/weixin-graal/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 3.6.8.B + 3.6.9.B weixin-graal diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 82f0989346..6a9c4ab562 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 3.6.8.B + 3.6.9.B weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index ab505995b1..22f98e4a10 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.8.B + 3.6.9.B weixin-java-cp diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index 938438f214..3808a4c96a 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.8.B + 3.6.9.B weixin-java-miniapp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 29eaf3be9d..b92d14b36c 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.8.B + 3.6.9.B weixin-java-mp diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index bfcfc05090..6c83560004 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.8.B + 3.6.9.B weixin-java-open diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index 9d496a7d7c..0d9d97aa99 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ com.github.binarywang wx-java - 3.6.8.B + 3.6.9.B 4.0.0 From 8b280f4eb13989764bf17aba6b6cf0ae8354492a Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 22 Feb 2020 21:37:53 +0800 Subject: [PATCH 0057/1706] =?UTF-8?q?:art:=20#1381=20=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=A8=A1=E5=9D=97=E9=85=8D=E7=BD=AE=E7=B1=BB?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0autoRefreshToken=E5=8F=82=E6=95=B0=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=EF=BC=8C=E6=96=B9=E4=BE=BF=E6=8E=A7=E5=88=B6=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E8=87=AA=E5=8A=A8=E5=88=B7=E6=96=B0access=5Ftoken?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/cp/api/impl/BaseWxCpServiceImpl.java | 4 +++- .../chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java | 4 +++- .../java/me/chanjar/weixin/cp/config/WxCpConfigStorage.java | 6 ++++++ .../me/chanjar/weixin/cp/config/WxCpTpConfigStorage.java | 6 ++++++ .../weixin/cp/config/impl/WxCpDefaultConfigImpl.java | 5 +++++ .../weixin/cp/config/impl/WxCpTpDefaultConfigImpl.java | 5 +++++ 6 files changed, 28 insertions(+), 2 deletions(-) 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 700c4d2e66..9dd1333bfa 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 @@ -281,7 +281,9 @@ protected T executeInternal(RequestExecutor executor, String uri, E if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { // 强制设置wxCpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token this.configStorage.expireAccessToken(); - return execute(executor, uri, data); + if (this.getWxCpConfigStorage().autoRefreshToken()) { + return this.execute(executor, uri, data); + } } if (error.getErrorCode() != 0) { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java index fe8e3c08e3..dea5428c1b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/BaseWxCpTpServiceImpl.java @@ -194,7 +194,9 @@ protected T executeInternal(RequestExecutor executor, String uri, E if (error.getErrorCode() == 42009) { // 强制设置wxCpTpConfigStorage它的suite access token过期了,这样在下一次请求里就会刷新suite access token this.configStorage.expireSuiteAccessToken(); - return execute(executor, uri, data); + if (this.getWxCpTpConfigStorage().autoRefreshToken()) { + return this.execute(executor, uri, data); + } } if (error.getErrorCode() != 0) { 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 c4dbf8f1a1..c6ccf893b4 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 @@ -97,4 +97,10 @@ public interface WxCpConfigStorage { * @return ApacheHttpClientBuilder */ ApacheHttpClientBuilder getApacheHttpClientBuilder(); + + /** + * 是否自动刷新token + * @return . + */ + boolean autoRefreshToken(); } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpTpConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpTpConfigStorage.java index fadfb0bda6..40c29ed0c9 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpTpConfigStorage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpTpConfigStorage.java @@ -83,4 +83,10 @@ public interface WxCpTpConfigStorage { * @return ApacheHttpClientBuilder */ ApacheHttpClientBuilder getApacheHttpClientBuilder(); + + /** + * 是否自动刷新token + * @return . + */ + boolean autoRefreshToken(); } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java index 87ed4f611c..9f182180a3 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java @@ -262,6 +262,11 @@ public ApacheHttpClientBuilder getApacheHttpClientBuilder() { return this.apacheHttpClientBuilder; } + @Override + public boolean autoRefreshToken() { + return true; + } + public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { this.apacheHttpClientBuilder = apacheHttpClientBuilder; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpDefaultConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpDefaultConfigImpl.java index d8be83c2af..be4b046a48 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpDefaultConfigImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpTpDefaultConfigImpl.java @@ -242,6 +242,11 @@ public ApacheHttpClientBuilder getApacheHttpClientBuilder() { return this.apacheHttpClientBuilder; } + @Override + public boolean autoRefreshToken() { + return true; + } + public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { this.apacheHttpClientBuilder = apacheHttpClientBuilder; } From 3ccc2786c53539a3cc7cca0d535e9d205a540ea0 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 22 Feb 2020 21:40:54 +0800 Subject: [PATCH 0058/1706] =?UTF-8?q?:art:=20#1367=20=E5=85=AC=E4=BC=97?= =?UTF-8?q?=E5=8F=B7=E5=8F=91=E9=80=81=E6=A8=A1=E6=9D=BF=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E7=B1=BBusePath=E5=B1=9E=E6=80=A7?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E5=80=BC=E8=AE=BE=E4=B8=BAfalse=EF=BC=8C?= =?UTF-8?q?=E6=96=B9=E4=BE=BF=E7=94=9F=E6=88=90=E7=9B=AE=E5=89=8D=E5=AE=98?= =?UTF-8?q?=E6=96=B9=E7=A1=AE=E5=AE=9A=E7=9A=84=E6=AD=A3=E7=A1=AE=E5=8F=82?= =?UTF-8?q?=E6=95=B0pagepath?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java index f04f8c91a8..99c3df358e 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateMessage.java @@ -83,7 +83,7 @@ public static class MiniProgram implements Serializable { * 是否使用path,否则使用pagepath. * 加入此字段是基于微信官方接口变化多端的考虑 */ - private boolean usePath = true; + private boolean usePath = false; } } From 8012154ec9dff6e0a3f116f99a2782badfd52dcd Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 22 Feb 2020 21:48:31 +0800 Subject: [PATCH 0059/1706] =?UTF-8?q?:bug:=20#1405=20=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E5=88=9B=E5=BB=BA=E8=AE=A2=E5=8D=95=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E4=B8=AD=E4=BA=A4=E6=98=93=E7=B1=BB=E5=9E=8B=E4=B8=BA?= =?UTF-8?q?JSAPI=E6=97=B6=E7=9A=84=E7=AD=BE=E5=90=8D=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E4=B8=8D=E9=BB=98=E8=AE=A4=E4=B8=BAMD5=EF=BC=8C=E4=BB=8E?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E5=AF=B9=E8=B1=A1=E4=B8=AD=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 c0782f90d0..61dcee09ba 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 @@ -322,7 +322,11 @@ public T createOrder(WxPayUnifiedOrderRequest request) throws WxPayException } case TradeType.JSAPI: { - String signType = SignType.MD5; + String signType = request.getSignType(); + if (signType == null) { + signType = SignType.MD5; + } + String appid = unifiedOrderResult.getAppid(); if (StringUtils.isNotEmpty(unifiedOrderResult.getSubAppId())) { appid = unifiedOrderResult.getSubAppId(); From 8efed3ebc4e9b57a10e9c59724f5a8744b8fc905 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 23 Feb 2020 10:41:53 +0800 Subject: [PATCH 0060/1706] =?UTF-8?q?:art:=20#1381=20=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E6=A8=A1=E5=9D=97=E9=85=8D=E7=BD=AE=E7=B1=BB?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0autoRefreshToken=E5=8F=82=E6=95=B0=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=EF=BC=8C=E6=96=B9=E4=BE=BF=E6=8E=A7=E5=88=B6=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E8=87=AA=E5=8A=A8=E5=88=B7=E6=96=B0access=5Ftoken?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chanjar/weixin/cp/config/impl/WxCpRedisConfigImpl.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpRedisConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpRedisConfigImpl.java index ecaa47cc23..5b48f547fa 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpRedisConfigImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpRedisConfigImpl.java @@ -320,6 +320,11 @@ public ApacheHttpClientBuilder getApacheHttpClientBuilder() { return this.apacheHttpClientBuilder; } + @Override + public boolean autoRefreshToken() { + return true; + } + public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) { this.apacheHttpClientBuilder = apacheHttpClientBuilder; } From 70640f4d003d1a5252f2c3ea9311e5c1f8fd6967 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 23 Feb 2020 11:11:45 +0800 Subject: [PATCH 0061/1706] =?UTF-8?q?:art:=20=E8=A7=84=E8=8C=83=E9=83=A8?= =?UTF-8?q?=E5=88=86=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95=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 --- .../impl/ProfitSharingServiceImplTest.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/ProfitSharingServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/ProfitSharingServiceImplTest.java index d21cca55af..087ba7fc34 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/ProfitSharingServiceImplTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/ProfitSharingServiceImplTest.java @@ -23,7 +23,7 @@ public class ProfitSharingServiceImplTest { private WxPayService payService; @Test - public void testProfitsharing() throws WxPayException { + public void testProfitSharing() throws WxPayException { ReceiverList instance = ReceiverList.getInstance(); instance.add(new Receiver(WxPayConstants.ReceiverType.PERSONAL_OPENID, "oyOUE5ql4TtzrBg5cVOwxq6tbjOs", @@ -40,7 +40,7 @@ public void testProfitsharing() throws WxPayException { } @Test - public void testMultiprofitsharing() throws WxPayException { + public void testMultiProfitSharing() throws WxPayException { ReceiverList instance = ReceiverList.getInstance(); instance.add(new Receiver(WxPayConstants.ReceiverType.MERCHANT_ID, "86693852", @@ -56,7 +56,7 @@ public void testMultiprofitsharing() throws WxPayException { } @Test - public void testProfitsharingFinish() throws WxPayException { + public void testProfitSharingFinish() throws WxPayException { ProfitSharingFinishRequest request = ProfitSharingFinishRequest .newBuilder() .outOrderNo("20191023103251431856285") @@ -67,7 +67,7 @@ public void testProfitsharingFinish() throws WxPayException { } @Test - public void testAddreceiver() throws WxPayException { + public void testAddReceiver() throws WxPayException { Receiver receiver = new Receiver(WxPayConstants.ReceiverType.PERSONAL_OPENID, "oyOUE5ql4TtzrBg5cVOwxq6tbjOs", "***", @@ -92,7 +92,7 @@ public void testRemoveReceiver() throws WxPayException { } @Test - public void testProfitsharingQuery() throws WxPayException { + public void testProfitSharingQuery() throws WxPayException { ProfitSharingQueryRequest request = ProfitSharingQueryRequest .newBuilder() .outOrderNo("20191023112023031060677") @@ -104,7 +104,7 @@ public void testProfitsharingQuery() throws WxPayException { } @Test - public void testProfitsharingReturn() throws WxPayException { + public void testProfitSharingReturn() throws WxPayException { ProfitSharingReturnRequest request = ProfitSharingReturnRequest .newBuilder() .outOrderNo("20191023154723316420060") @@ -118,7 +118,7 @@ public void testProfitsharingReturn() throws WxPayException { } @Test - public void testProfitsharingReturnQuery() throws WxPayException { + public void testProfitSharingReturnQuery() throws WxPayException { ProfitSharingReturnQueryRequest request = ProfitSharingReturnQueryRequest .newBuilder() .outOrderNo("20191023154723316420060") @@ -127,5 +127,4 @@ public void testProfitsharingReturnQuery() throws WxPayException { this.logger.info(this.payService.getProfitSharingService().profitSharingReturnQuery(request).toString()); } - } From 6aa85599706943df68b5b5e702a67a81b2355fef Mon Sep 17 00:00:00 2001 From: S Date: Tue, 25 Feb 2020 16:06:39 +0800 Subject: [PATCH 0062/1706] =?UTF-8?q?:art:=20#1406=20=E5=B0=8F=E7=A8=8B?= =?UTF-8?q?=E5=BA=8F=E8=AE=A2=E9=98=85=E6=B6=88=E6=81=AF=E5=8F=91=E9=80=81?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E5=A2=9E=E5=8A=A0=E6=96=B0=E5=8F=82=E6=95=B0?= =?UTF-8?q?=EF=BC=9Amniprogram=5Fstate=20=E5=92=8C=20lang?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wx/miniapp/bean/WxMaSubscribeMessage.java | 11 ++++ .../wx/miniapp/constant/WxMaConstants.java | 50 +++++++++++++++++++ .../json/WxMaSubscribeMessageGsonAdapter.java | 8 +++ .../api/impl/WxMaMsgServiceImplTest.java | 6 +++ 4 files changed, 75 insertions(+) diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeMessage.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeMessage.java index d84be98aae..791687b6c0 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeMessage.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaSubscribeMessage.java @@ -1,5 +1,6 @@ package cn.binarywang.wx.miniapp.bean; +import cn.binarywang.wx.miniapp.constant.WxMaConstants; import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder; import lombok.*; @@ -61,6 +62,16 @@ public class WxMaSubscribeMessage implements Serializable { */ private List data; + /** + * 跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版 + */ + private String miniprogramState = WxMaConstants.MiniprogramState.FORMAL; + + /** + * 进入小程序查看的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN + */ + private String lang = WxMaConstants.MiniprogramLang.ZH_CN; + public WxMaSubscribeMessage addData(Data datum) { if (this.data == null) { this.data = new ArrayList<>(); diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java index 2c89b8a02e..0d2a8675eb 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java @@ -137,4 +137,54 @@ public static final class OrderAddInsured{ */ public static final int DEFAULT_INSURED_VALUE = 0; } + + + /** + * 小程序订阅消息跳转小程序类型 + * + * developer为开发版;trial为体验版;formal为正式版;默认为正式版 + */ + public static final class MiniprogramState{ + /** + * 开发版 + */ + public static final String DEVELOPER = "developer"; + + /** + * 体验版 + */ + public static final String TRIAL = "trial"; + + /** + * 正式版 + */ + public static final String FORMAL = "formal"; + } + + + /** + * 进入小程序查看的语言类型 + * 支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN + */ + public static final class MiniprogramLang{ + /** + * 简体中文 + */ + public static final String ZH_CN = "zh_CN"; + + /** + * 英文 + */ + public static final String EN_US = "en_US"; + + /** + * 繁体中文 + */ + public static final String ZH_HK = "zh_HK"; + + /** + * 繁体中文 + */ + public static final String ZH_TW = "zh_TW"; + } } diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaSubscribeMessageGsonAdapter.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaSubscribeMessageGsonAdapter.java index 1d213d4a05..89f8bad8d3 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaSubscribeMessageGsonAdapter.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/json/WxMaSubscribeMessageGsonAdapter.java @@ -23,6 +23,14 @@ public JsonElement serialize(WxMaSubscribeMessage message, Type typeOfSrc, JsonS messageJson.addProperty("page", message.getPage()); } + if (message.getMiniprogramState() != null) { + messageJson.addProperty("miniprogram_state", message.getMiniprogramState()); + } + + if (message.getLang() != null) { + messageJson.addProperty("lang", message.getLang()); + } + JsonObject data = new JsonObject(); messageJson.add("data", data); 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 7ff22290ea..3ca42b46fc 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 @@ -2,6 +2,10 @@ import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.bean.*; +import cn.binarywang.wx.miniapp.constant.WxMaConstants; +import org.testng.annotations.*; + +import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.test.ApiTestModule; import cn.binarywang.wx.miniapp.test.TestConfig; import com.google.common.collect.Lists; @@ -68,6 +72,8 @@ public void testSendSubscribeMsg() throws WxErrorException { WxMaSubscribeMessage message = new WxMaSubscribeMessage(); message.setTemplateId(config.getTemplateId()); message.setToUser(config.getOpenid()); + message.setLang(WxMaConstants.MiniprogramLang.ZH_CN); + message.setMiniprogramState(WxMaConstants.MiniprogramState.FORMAL); message.addData(new WxMaSubscribeMessage.Data("thing1", "苹果到货啦")); message.addData(new WxMaSubscribeMessage.Data("amount3", "¥5")); message.addData(new WxMaSubscribeMessage.Data("thing5", "记得领取哦")); From bb0771736f514b407794d0d3467f1762d96f76bd Mon Sep 17 00:00:00 2001 From: Gyv12345 Date: Thu, 27 Feb 2020 16:40:44 +0800 Subject: [PATCH 0063/1706] =?UTF-8?q?:new:=20#1416:=20=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E5=A2=9E=E5=8A=A0=E8=8E=B7=E5=8F=96OA?= =?UTF-8?q?=E5=AE=A1=E6=89=B9=E6=A8=A1=E6=9D=BF=E8=AF=A6=E6=83=85=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chanjar/weixin/cp/api/WxCpOaService.java | 8 ++++ .../weixin/cp/api/impl/WxCpOaServiceImpl.java | 9 ++++ .../weixin/cp/bean/oa/WxCpCheckinData.java | 4 ++ .../weixin/cp/bean/oa/WxCpTemplateResult.java | 35 ++++++++++++++++ .../bean/oa/templatedata/TemplateConfig.java | 37 +++++++++++++++++ .../bean/oa/templatedata/TemplateContent.java | 17 ++++++++ .../oa/templatedata/TemplateControls.java | 19 +++++++++ .../oa/templatedata/TemplateDateRange.java | 19 +++++++++ .../bean/oa/templatedata/TemplateOptions.java | 16 ++++++++ .../oa/templatedata/TemplateProperty.java | 41 +++++++++++++++++++ .../bean/oa/templatedata/TemplateTitle.java | 18 ++++++++ .../oa/templatedata/TemplateVacationItem.java | 18 ++++++++ .../control/TemplateAttendance.java | 25 +++++++++++ .../templatedata/control/TemplateContact.java | 22 ++++++++++ .../oa/templatedata/control/TemplateDate.java | 18 ++++++++ .../control/TemplateSelector.java | 20 +++++++++ .../templatedata/control/TemplateTable.java | 23 +++++++++++ .../control/TemplateVacation.java | 17 ++++++++ .../weixin/cp/constant/WxCpApiPathConsts.java | 2 + .../weixin/cp/constant/WxCpConsts.java | 5 +++ .../cp/api/impl/WxCpOaServiceImplTest.java | 20 +++++---- 21 files changed, 386 insertions(+), 7 deletions(-) create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpTemplateResult.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateConfig.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateContent.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateControls.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateDateRange.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateOptions.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateProperty.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTitle.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateVacationItem.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateAttendance.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateContact.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateDate.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateSelector.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateTable.java create mode 100644 weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateVacation.java 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 index f244700251..9af5a36e4b 100644 --- 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 @@ -124,4 +124,12 @@ WxCpApprovalInfo getApprovalInfo(@NonNull Date startTime, @NonNull Date endTime, List getDialRecord(Date startTime, Date endTime, Integer offset, Integer limit) throws WxErrorException; + /** + * 获取审批模板详情 + * @param templateId 模板ID + * @return + * @throws WxErrorException + */ + WxCpTemplateResult getTemplateDetail(@NonNull String templateId)throws WxErrorException; + } 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 index 2a1d41ec7a..0484e1f62a 100644 --- 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 @@ -209,4 +209,13 @@ public List getDialRecord(Date startTime, Date endTime, Integer }.getType() ); } + + @Override + public WxCpTemplateResult getTemplateDetail(@NonNull String templateId) throws WxErrorException { + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("template_id",templateId); + final String url = this.mainService.getWxCpConfigStorage().getApiUrl(GET_TEMPLATE_DETAIL); + String responseContent = this.mainService.post(url, jsonObject.toString()); + return WxCpGsonBuilder.create().fromJson(responseContent,WxCpTemplateResult.class); + } } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpCheckinData.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpCheckinData.java index 555f59c017..b76553ca63 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpCheckinData.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpCheckinData.java @@ -47,4 +47,8 @@ public class WxCpCheckinData implements Serializable { @SerializedName("mediaids") private List mediaIds; + + private Integer lat; + + private Integer lng; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpTemplateResult.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpTemplateResult.java new file mode 100644 index 0000000000..df25aabf37 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpTemplateResult.java @@ -0,0 +1,35 @@ +package me.chanjar.weixin.cp.bean.oa; + +import com.google.gson.JsonObject; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.cp.bean.oa.templatedata.TemplateContent; +import me.chanjar.weixin.cp.bean.oa.templatedata.TemplateControls; +import me.chanjar.weixin.cp.bean.oa.templatedata.TemplateTitle; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * 审批模板详情 + * + * @author gyv12345@163.com + */ +@Data +public class WxCpTemplateResult implements Serializable { + private static final long serialVersionUID = 6690547131189343887L; + + @SerializedName("errcode") + private Integer errCode; + + @SerializedName("errmsg") + private String errMsg; + + @SerializedName("template_names") + private List templateNames; + + @SerializedName("template_content") + private TemplateContent templateContent; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateConfig.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateConfig.java new file mode 100644 index 0000000000..54213d9d90 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateConfig.java @@ -0,0 +1,37 @@ +package me.chanjar.weixin.cp.bean.oa.templatedata; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.cp.bean.oa.templatedata.control.*; + +import java.io.Serializable; + +/** + * 模板控件配置,包含了部分控件类型的附加类型、属性,详见附录说明。 + * 目前有配置信息的控件类型有: + * Date-日期/日期+时间; + * Selector-单选/多选; + * Contact-成员/部门; + * Table-明细; + * Attendance-假勤组件(请假、外出、出差、加班) + * @author gyv12345@163.com + */ +@Data +public class TemplateConfig implements Serializable { + + private static final long serialVersionUID = 6993937809371277669L; + + private TemplateDate date; + + private TemplateSelector selector; + + private TemplateContact contact; + + private TemplateTable table; + + private TemplateAttendance attendance; + + @SerializedName("vacation_list") + private TemplateVacation vacationList; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateContent.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateContent.java new file mode 100644 index 0000000000..72fc02cd1f --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateContent.java @@ -0,0 +1,17 @@ +package me.chanjar.weixin.cp.bean.oa.templatedata; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @author gyv12345@163.com + */ +@Data +public class TemplateContent implements Serializable { + + private static final long serialVersionUID = -5640250983775840865L; + + private List controls; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateControls.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateControls.java new file mode 100644 index 0000000000..bc9919ac3f --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateControls.java @@ -0,0 +1,19 @@ +package me.chanjar.weixin.cp.bean.oa.templatedata; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Map; + +/** + * @author Administrator + */ +@Data +public class TemplateControls implements Serializable { + + private static final long serialVersionUID = -7496794407355510374L; + + private TemplateProperty property; + + private TemplateConfig config; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateDateRange.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateDateRange.java new file mode 100644 index 0000000000..716f0859da --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateDateRange.java @@ -0,0 +1,19 @@ +package me.chanjar.weixin.cp.bean.oa.templatedata; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author gyv12345@163.com + */ +@Data +public class TemplateDateRange implements Serializable { + + private static final long serialVersionUID = -9209035461466543180L; + + /** + * 时间刻度:hour-精确到分钟, halfday—上午/下午 + */ + private String type; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateOptions.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateOptions.java new file mode 100644 index 0000000000..7dc0b41a80 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateOptions.java @@ -0,0 +1,16 @@ +package me.chanjar.weixin.cp.bean.oa.templatedata; + +import java.io.Serializable; +import java.util.List; + +/** + * @author gyv123@163.com + */ +public class TemplateOptions implements Serializable { + + private static final long serialVersionUID = -7883792668568772078L; + + private String key; + + private List value; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateProperty.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateProperty.java new file mode 100644 index 0000000000..cf33f47175 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateProperty.java @@ -0,0 +1,41 @@ +package me.chanjar.weixin.cp.bean.oa.templatedata; + +import com.google.gson.JsonObject; +import com.google.gson.annotations.SerializedName; +import me.chanjar.weixin.cp.bean.oa.WxCpTemplateResult; +import me.chanjar.weixin.cp.bean.oa.templatedata.control.TemplateContact; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * @author gyv12345@163.com + */ +public class TemplateProperty implements Serializable { + + private static final long serialVersionUID = -3429251158540167453L; + + private String control; + + private String id; + + private List title; + + /** + * 控件说明,向申请者展示的控件填写说明,若配置了多语言则会包含中英文的控件说明,默认为zh_CN中文 + */ + private List placeholder; + + /** + * 是否必填:1-必填;0-非必填 + */ + private Integer require; + /** + * 是否参与打印:1-不参与打印;0-参与打印 + */ + @SerializedName("un_print") + private Integer unPrint; + + private TemplateConfig config; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTitle.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTitle.java new file mode 100644 index 0000000000..cdfe30c9b9 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateTitle.java @@ -0,0 +1,18 @@ +package me.chanjar.weixin.cp.bean.oa.templatedata; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author gyv12345@163.com + */ +@Data +public class TemplateTitle implements Serializable { + + private static final long serialVersionUID = -3229779834737051398L; + + private String text; + + private String lang; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateVacationItem.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateVacationItem.java new file mode 100644 index 0000000000..17aa33afc2 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/TemplateVacationItem.java @@ -0,0 +1,18 @@ +package me.chanjar.weixin.cp.bean.oa.templatedata; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author gyv12345@163.com + */ +@Data +public class TemplateVacationItem implements Serializable { + + private static final long serialVersionUID = 4510594801023791319L; + + private Integer id; + + private TemplateTitle name; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateAttendance.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateAttendance.java new file mode 100644 index 0000000000..21dca126e9 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateAttendance.java @@ -0,0 +1,25 @@ +package me.chanjar.weixin.cp.bean.oa.templatedata.control; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import me.chanjar.weixin.cp.bean.oa.templatedata.TemplateDateRange; + +import java.io.Serializable; +import java.util.Map; + +/** + * @author gyv12345@163.com + */ +@Data +public class TemplateAttendance implements Serializable { + + private static final long serialVersionUID = 5800412600894589065L; + + @SerializedName("date_range") + private TemplateDateRange dateRange; + + /** + * 假勤控件类型:1-请假,3-出差,4-外出,5-加班 + */ + private Integer type; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateContact.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateContact.java new file mode 100644 index 0000000000..15fcaf3ac1 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateContact.java @@ -0,0 +1,22 @@ +package me.chanjar.weixin.cp.bean.oa.templatedata.control; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author gyv12345@163.com + */ +@Data +public class TemplateContact implements Serializable { + + private static final long serialVersionUID = -7840088884653172851L; + /** + * 选择方式:single-单选;multi-多选 + */ + private String type; + /** + * 选择对象:user-成员;department-部门 + */ + private String mode; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateDate.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateDate.java new file mode 100644 index 0000000000..7d588ddc79 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateDate.java @@ -0,0 +1,18 @@ +package me.chanjar.weixin.cp.bean.oa.templatedata.control; + +import lombok.Data; + +import java.io.Serializable; + +/** + * @author Administrator + */ +@Data +public class TemplateDate implements Serializable { + + private static final long serialVersionUID = 1300634733160349684L; + /** + * day-日期;hour-日期+时间 + */ + private String type; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateSelector.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateSelector.java new file mode 100644 index 0000000000..1eb1c9359c --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateSelector.java @@ -0,0 +1,20 @@ +package me.chanjar.weixin.cp.bean.oa.templatedata.control; + +import me.chanjar.weixin.cp.bean.oa.templatedata.TemplateOptions; + +import java.io.Serializable; +import java.util.List; + +/** + * @author + */ +public class TemplateSelector implements Serializable { + + private static final long serialVersionUID = 4995408101489736881L; + /** + * single-单选;multi-多选 + */ + private String type; + + private List options; +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateTable.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateTable.java new file mode 100644 index 0000000000..08cdd5d4e7 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateTable.java @@ -0,0 +1,23 @@ +package me.chanjar.weixin.cp.bean.oa.templatedata.control; + +import lombok.Data; +import me.chanjar.weixin.cp.bean.oa.templatedata.TemplateControls; + +import java.io.Serializable; +import java.util.List; + +/** + * + * @author gyv12345@163.com + */ +@Data +public class TemplateTable implements Serializable { + + + private static final long serialVersionUID = -8181588935694605858L; + + private List children; + + private String[] statField; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateVacation.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateVacation.java new file mode 100644 index 0000000000..74b741a086 --- /dev/null +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/templatedata/control/TemplateVacation.java @@ -0,0 +1,17 @@ +package me.chanjar.weixin.cp.bean.oa.templatedata.control; + +import lombok.Data; +import me.chanjar.weixin.cp.bean.oa.templatedata.TemplateVacationItem; + +import java.io.Serializable; +import java.util.List; + +/** + * @author gyv12345@163.com + */ +@Data +public class TemplateVacation implements Serializable { + + private List item; + +} diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java index 2a26a40359..d65492d5c0 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java @@ -69,6 +69,8 @@ public static class Oa { public static final String GET_DIAL_RECORD = "/cgi-bin/dial/get_dial_record"; @Deprecated public static final String GET_APPROVAL_DATA = "/cgi-bin/corp/getapprovaldata"; + public static final String GET_TEMPLATE_DETAIL = "/cgi-bin/oa/gettemplatedetail"; + public static final String APPLY_EVENT="/cgi-bin/oa/applyevent"; } public static class Tag { diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java index 48bfc3ceb9..a69b8ea2ef 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java @@ -94,6 +94,11 @@ public static class EventType { */ public static final String CHANGE_EXTERNAL_CONTACT = "change_external_contact"; + /** + * 企业微信审批事件推送 + */ + public static final String OPEN_APPROVAL_CHANGE = "open_approval_change"; + } 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 bc220b599a..4515239084 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 @@ -5,10 +5,7 @@ import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.cp.api.ApiTestModule; import me.chanjar.weixin.cp.api.WxCpService; -import me.chanjar.weixin.cp.bean.oa.WxCpApprovalDetailResult; -import me.chanjar.weixin.cp.bean.oa.WxCpApprovalInfo; -import me.chanjar.weixin.cp.bean.oa.WxCpCheckinData; -import me.chanjar.weixin.cp.bean.oa.WxCpCheckinOption; +import me.chanjar.weixin.cp.bean.oa.*; import org.apache.commons.lang3.time.DateFormatUtils; import org.testng.annotations.Guice; import org.testng.annotations.Test; @@ -62,8 +59,8 @@ public void testGetCheckinOption() throws WxErrorException { @Test public void testGetApprovalInfo() throws WxErrorException, ParseException { - Date startTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-04-11"); - Date endTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-05-10"); + Date startTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-12-01"); + Date endTime = DateFormatUtils.ISO_8601_EXTENDED_DATE_FORMAT.parse("2019-12-31"); WxCpApprovalInfo result = wxService.getOAService().getApprovalInfo(startTime, endTime); assertThat(result).isNotNull(); @@ -74,7 +71,7 @@ public void testGetApprovalInfo() throws WxErrorException, ParseException { @Test public void testGetApprovalDetail() throws WxErrorException { - String spNo = "201909270001"; + String spNo = "201912020001"; WxCpApprovalDetailResult result = wxService.getOAService().getApprovalDetail(spNo); assertThat(result).isNotNull(); @@ -83,4 +80,13 @@ public void testGetApprovalDetail() throws WxErrorException { System.out.println(gson.toJson(result)); } + @Test + public void testGetTemplateDetail() throws WxErrorException{ + String templateId="3TkZjxugodbqpEMk9j7X6h6zKqYkc7MxQrrFmT7H"; + WxCpTemplateResult result=wxService.getOAService().getTemplateDetail(templateId); + assertThat(result).isNotNull(); + System.out.println("result "); + System.out.println(gson.toJson(result)); + } + } From 99d450f3cfe684cd4242ac1daf56b1fb52bf6413 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 29 Feb 2020 14:29:23 +0800 Subject: [PATCH 0064/1706] =?UTF-8?q?:art:=20=E4=BC=98=E5=8C=96=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/bean/profitsharing/ProfitSharingQueryRequest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java index c4009858cb..5f5282dbd6 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java @@ -5,6 +5,7 @@ import com.github.binarywang.wxpay.exception.WxPayException; import com.thoughtworks.xstream.annotations.XStreamAlias; import lombok.*; +import lombok.experimental.Accessors; import me.chanjar.weixin.common.annotation.Required; import java.util.Map; @@ -16,6 +17,7 @@ @Data @EqualsAndHashCode(callSuper = true) @Builder(builderMethodName = "newBuilder") +@Accessors(chain = true) @NoArgsConstructor @AllArgsConstructor @XStreamAlias("xml") From 9355b50cd538482a3a40b169a0038bafbbb5d8fd Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 29 Feb 2020 14:31:05 +0800 Subject: [PATCH 0065/1706] =?UTF-8?q?:art:=20=E6=81=A2=E5=A4=8D=E8=A2=AB?= =?UTF-8?q?=E8=AF=AF=E6=A0=87=E8=AE=B0=E4=B8=BAdeprecated=E7=9A=84?= =?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/cp/api/WxCpExternalContactService.java | 1 - .../java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpExternalContactService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpExternalContactService.java index 0d043735fe..df5326f249 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpExternalContactService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpExternalContactService.java @@ -83,7 +83,6 @@ public interface WxCpExternalContactService { * @return List of CpUser id * @throws WxErrorException . */ - @Deprecated List listFollowUser() throws WxErrorException; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java index d65492d5c0..d5287136e2 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java @@ -114,9 +114,8 @@ public static class User { public static class ExternalContact { @Deprecated public static final String GET_EXTERNAL_CONTACT = "/cgi-bin/crm/get_external_contact?external_userid="; - @Deprecated - public static final String GET_FOLLOW_USER_LIST = "/cgi-bin/externalcontact/get_follow_user_list"; + public static final String GET_FOLLOW_USER_LIST = "/cgi-bin/externalcontact/get_follow_user_list"; public static final String GET_CONTACT_DETAIL = "/cgi-bin/externalcontact/get?external_userid="; public static final String LIST_EXTERNAL_CONTACT = "/cgi-bin/externalcontact/list?userid="; } From 1dba5dba36611c1714cb380a4a88b715ecf82482 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 29 Feb 2020 14:44:29 +0800 Subject: [PATCH 0066/1706] =?UTF-8?q?:bug:=20#1415=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8FgetCardApiTicket=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=E9=94=99=E8=AF=AF=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImpl.java index 83dbc929b4..ed5b375e24 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImpl.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaJsapiServiceImpl.java @@ -51,7 +51,7 @@ public String getCardApiTicket(boolean forceRefresh) throws WxErrorException { } finally { lock.unlock(); } - return this.wxMaService.getWxMaConfig().getJsapiTicket(); + return this.wxMaService.getWxMaConfig().getCardApiTicket(); } @Override From 4b13a040140cc16efc71345cd50de7ee28ebe05a Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 29 Feb 2020 15:22:53 +0800 Subject: [PATCH 0067/1706] =?UTF-8?q?:bug:=20#1413=20=E5=85=AC=E4=BC=97?= =?UTF-8?q?=E5=8F=B7=E6=A8=A1=E5=9D=97=E4=BC=98=E5=8C=96=E8=A1=8C=E4=B8=9A?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E6=8E=A5=E5=8F=A3=E6=9E=9A=E4=B8=BE=E5=8C=B9?= =?UTF-8?q?=E9=85=8D=E4=BB=A3=E7=A0=81=EF=BC=8C=E5=B9=B6=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mp/util/json/WxMpIndustryGsonAdapter.java | 7 +++++- .../template/WxMpTemplateIndustryTest.java | 23 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateIndustryTest.java diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpIndustryGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpIndustryGsonAdapter.java index 0c45719548..04d9d7dadd 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpIndustryGsonAdapter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpIndustryGsonAdapter.java @@ -28,7 +28,12 @@ public WxMpTemplateIndustry deserialize(JsonElement jsonElement, Type type, Json } private WxMpTemplateIndustryEnum convertFromJson(JsonObject json) { - return WxMpTemplateIndustryEnum.findBySecondary(GsonHelper.getString(json, "second_class")); + String secondClass = GsonHelper.getString(json, "second_class"); + if (secondClass.contains("|")) { + secondClass = secondClass.split("\\|")[1]; + } + + return WxMpTemplateIndustryEnum.findBySecondary(secondClass); } } diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateIndustryTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateIndustryTest.java new file mode 100644 index 0000000000..d5affa288b --- /dev/null +++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/bean/template/WxMpTemplateIndustryTest.java @@ -0,0 +1,23 @@ +package me.chanjar.weixin.mp.bean.template; + +import org.testng.annotations.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.testng.Assert.*; + +/** + * 测试类. + * + * @author Binary Wang + * @date 2020-02-29 + */ +public class WxMpTemplateIndustryTest { + + @Test + public void testFromJson() { + String json="{\"primary_industry\":{\"first_class\":\"IT科技\",\"second_class\":\"IT软件与服务\"},\"secondary_industry\":{\"first_class\":\"房地产\",\"second_class\":\"房地产|建筑\"}}"; + final WxMpTemplateIndustry industry = WxMpTemplateIndustry.fromJson(json); + assertThat(industry).isNotNull(); + System.out.println(industry); + } +} From 1b66e77d71f6ed2bfe41e141a2ea626fe266913c Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 29 Feb 2020 17:18:50 +0800 Subject: [PATCH 0068/1706] =?UTF-8?q?:bookmark:=20=E5=8F=91=E5=B8=833.7.0?= =?UTF-8?q?=E6=AD=A3=E5=BC=8F=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- spring-boot-starters/pom.xml | 2 +- .../wx-java-miniapp-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml | 2 +- spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml | 2 +- weixin-graal/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 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index 07e03e4bc2..93b5df6b87 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 4.0.0 com.github.binarywang wx-java - 3.6.9.B + 3.7.0 pom WxJava - Weixin/Wechat Java SDK 微信开发Java SDK diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml index 9b11ce2e7d..ecf51716dd 100644 --- a/spring-boot-starters/pom.xml +++ b/spring-boot-starters/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 3.6.9.B + 3.7.0 pom wx-java-spring-boot-starters diff --git a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml index 44cbd2e444..899b7bb2e0 100644 --- a/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-miniapp-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.9.B + 3.7.0 4.0.0 diff --git a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml index bbfda84944..9053e72ba7 100644 --- a/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-mp-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.9.B + 3.7.0 4.0.0 diff --git a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml index 2bd472a14f..9d77c2c76a 100644 --- a/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-open-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.9.B + 3.7.0 4.0.0 diff --git a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml index aecf3b9f7e..870f3e7c77 100644 --- a/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml +++ b/spring-boot-starters/wx-java-pay-spring-boot-starter/pom.xml @@ -5,7 +5,7 @@ wx-java-spring-boot-starters com.github.binarywang - 3.6.9.B + 3.7.0 4.0.0 diff --git a/weixin-graal/pom.xml b/weixin-graal/pom.xml index 099b73c0bf..1f351580e1 100644 --- a/weixin-graal/pom.xml +++ b/weixin-graal/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 3.6.9.B + 3.7.0 weixin-graal diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 6a9c4ab562..0620e6ddfa 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -6,7 +6,7 @@ com.github.binarywang wx-java - 3.6.9.B + 3.7.0 weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 22f98e4a10..5892d6a3d6 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.9.B + 3.7.0 weixin-java-cp diff --git a/weixin-java-miniapp/pom.xml b/weixin-java-miniapp/pom.xml index 3808a4c96a..ca89968b44 100644 --- a/weixin-java-miniapp/pom.xml +++ b/weixin-java-miniapp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.9.B + 3.7.0 weixin-java-miniapp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index b92d14b36c..7ee22b56c2 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.9.B + 3.7.0 weixin-java-mp diff --git a/weixin-java-open/pom.xml b/weixin-java-open/pom.xml index 6c83560004..825a1e1a89 100644 --- a/weixin-java-open/pom.xml +++ b/weixin-java-open/pom.xml @@ -7,7 +7,7 @@ com.github.binarywang wx-java - 3.6.9.B + 3.7.0 weixin-java-open diff --git a/weixin-java-pay/pom.xml b/weixin-java-pay/pom.xml index 0d9d97aa99..7d9100c5cb 100644 --- a/weixin-java-pay/pom.xml +++ b/weixin-java-pay/pom.xml @@ -5,7 +5,7 @@ com.github.binarywang wx-java - 3.6.9.B + 3.7.0 4.0.0 From 68fa49cfc8a9054bae35af7171c46b822b36509a Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 29 Feb 2020 19:00:26 +0800 Subject: [PATCH 0069/1706] =?UTF-8?q?:memo:=20=E6=9B=B4=E6=96=B0=E7=89=88?= =?UTF-8?q?=E6=9C=AC=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d2ba10d465..6a05a94f25 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ ### 重要信息 -1. **2019-11-25 发布 [【3.6.0正式版】](https://github.com/Wechat-Group/WxJava/releases)**! +1. **2020-02-29 发布 [【3.7.0正式版】](https://github.com/Wechat-Group/WxJava/releases)**! 1. 新手重要提示:本项目仅是一个SDK开发工具包,未提供Web实现,建议使用 `maven` 或 `gradle` 引用本项目即可使用本SDK提供的各种功能,详情可参考 **[【Demo项目】](demo.md)** 或本项目中的部分单元测试代码;另外微信开发新手请务必阅读[【开发文档 Wiki 首页】](https://github.com/Wechat-Group/WxJava/wiki)的常见问题部分,可以少走很多弯路,节省不少时间。 1. 技术交流群:想获得QQ群/微信群/钉钉企业群等信息的同学,请使用微信扫描上面的微信公众号二维码关注 `WxJava` 后点击相关菜单即可获取加入方式,同时也可以在微信中搜索 `weixin-java-tools` 或 `WxJava` 后选择正确的公众号进行关注,该公众号会及时通知SDK相关更新信息,并不定期分享微信Java开发相关技术知识; 1. 付费QQ群:(**注意:刚入群会有5分钟禁言,稍等片刻即可正常发言**) [![加入QQ群](https://img.shields.io/badge/QQ群-343954419-blue.svg)](http://shang.qq.com/wpa/qunwpa?idkey=731dc3e7ea31ebe25376cc1a791445468612c63fd0e9e05399b088ec81fd9e15) 或 [![加入QQ群](https://img.shields.io/badge/QQ群-343954419-blue.svg)](http://jq.qq.com/?_wv=1027&k=40lRskK),或者请自行搜索群号`343954419`进行添加;当然由于某种原因无法入群的,可关注公众号后获取其他群的加入方式; @@ -73,7 +73,7 @@ com.github.binarywang (不同模块参考下文) - 3.6.0 + 3.7.0 ``` @@ -91,7 +91,7 @@ 点此展开查看 1. 本项目定为大约每两个月发布一次正式版(同时 `develop` 分支代码合并进入 `master` 分支),版本号格式为 `X.X.0`(如`2.1.0`,`2.2.0`等),遇到重大问题需修复会及时提交新版本,欢迎大家随时提交Pull Request; -1. BUG修复和新特性一般会先发布成小版本作为临时测试版本(如`3.1.8.B`,即尾号不为0,并添加B,以区别于正式版),代码仅存在于 `develop` 分支中; +1. BUG修复和新特性一般会先发布成小版本作为临时测试版本(如`3.6.8.B`,即尾号不为0,并添加B,以区别于正式版),代码仅存在于 `develop` 分支中; 1. 目前最新版本号为 [![Maven Central](https://img.shields.io/maven-central/v/com.github.binarywang/wx-java.svg)](http://mvnrepository.com/artifact/com.github.binarywang/wx-java) ,也可以通过访问链接 [【微信支付】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-pay%22) 、[【微信小程序】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-miniapp%22) 、[【公众号】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-mp%22) 、[【企业微信】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-cp%22)、[【开放平台】](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.github.binarywang%22%20AND%20a%3A%22weixin-java-open%22) 分别查看所有最新的版本。 From d9ea16fdc01b4a9c281cf1c3d5b4ebfb108a3f98 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Mon, 2 Mar 2020 16:41:03 +0800 Subject: [PATCH 0070/1706] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6a05a94f25..936837e7f4 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ 1. 新手重要提示:本项目仅是一个SDK开发工具包,未提供Web实现,建议使用 `maven` 或 `gradle` 引用本项目即可使用本SDK提供的各种功能,详情可参考 **[【Demo项目】](demo.md)** 或本项目中的部分单元测试代码;另外微信开发新手请务必阅读[【开发文档 Wiki 首页】](https://github.com/Wechat-Group/WxJava/wiki)的常见问题部分,可以少走很多弯路,节省不少时间。 1. 技术交流群:想获得QQ群/微信群/钉钉企业群等信息的同学,请使用微信扫描上面的微信公众号二维码关注 `WxJava` 后点击相关菜单即可获取加入方式,同时也可以在微信中搜索 `weixin-java-tools` 或 `WxJava` 后选择正确的公众号进行关注,该公众号会及时通知SDK相关更新信息,并不定期分享微信Java开发相关技术知识; 1. 付费QQ群:(**注意:刚入群会有5分钟禁言,稍等片刻即可正常发言**) [![加入QQ群](https://img.shields.io/badge/QQ群-343954419-blue.svg)](http://shang.qq.com/wpa/qunwpa?idkey=731dc3e7ea31ebe25376cc1a791445468612c63fd0e9e05399b088ec81fd9e15) 或 [![加入QQ群](https://img.shields.io/badge/QQ群-343954419-blue.svg)](http://jq.qq.com/?_wv=1027&k=40lRskK),或者请自行搜索群号`343954419`进行添加;当然由于某种原因无法入群的,可关注公众号后获取其他群的加入方式; -1. 钉钉企业群:[请点击链接申请加入](https://h5.dingtalk.com/inviteColleague/index.html#/invite/9ed100cc4a/E1DF918E32E398D191E7FE61FE0552A6) 或者 [用手机钉钉APP扫码](https://gitee.com/binary/weixin-java-tools/raw/master/images/qrcodes/ding.jpg) 申请加入。 +1. 钉钉群号: 30294972,或者[请点击链接申请加入钉钉企业组织](https://h5.dingtalk.com/inviteColleague/index.html#/invite/9ed100cc4a/E1DF918E32E398D191E7FE61FE0552A6) 或者 [用手机钉钉APP扫码](https://gitee.com/binary/weixin-java-tools/raw/master/images/qrcodes/ding.jpg) 申请加入。 1. 微信开发新手或者Java开发新手在群内提问或新开Issue提问前,请先阅读[【提问的智慧】](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way/blob/master/README-zh_CN.md),并确保已查阅过 [【开发文档Wiki】](https://github.com/wechat-group/WxJava/wiki) ,避免浪费大家的宝贵时间; 1. 寻求帮助时需贴代码或大长串异常信息的,请利用 http://paste.ubuntu.com From 80669d4c4d08090f54161815bc39d99e61076303 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sat, 7 Mar 2020 17:24:28 +0800 Subject: [PATCH 0071/1706] :art: upddate something --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 936837e7f4..a66bda1030 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -## WxJava - 微信开发 Java SDK(开发工具包) [![LICENSE](https://img.shields.io/badge/License-Anti%20996-blue.svg)](https://github.com/996icu/996.ICU/blob/master/LICENSE) [![Badge](https://img.shields.io/badge/Link-996.icu-red.svg)](https://996.icu/#/zh_CN) [![Badge](https://img.shields.io/badge/Link-京东内购福利-red.svg)](https://mp.weixin.qq.com/s/dfwatgMgARaBjh421Todyg) +## WxJava - 微信开发 Java SDK(开发工具包) [![LICENSE](https://img.shields.io/badge/License-Anti%20996-blue.svg)](https://github.com/996icu/996.ICU/blob/master/LICENSE) [![Badge](https://img.shields.io/badge/Link-996.icu-red.svg)](https://996.icu/#/zh_CN) [![Badge](https://img.shields.io/badge/Link-专属福利-red.svg)](https://mp.weixin.qq.com/s/dfwatgMgARaBjh421Todyg) [![码云Gitee](https://gitee.com/binary/weixin-java-tools/badge/star.svg?theme=blue)](https://gitee.com/binary/weixin-java-tools) [![Github](http://github-svg-buttons.herokuapp.com/star.svg?user=Wechat-Group&repo=WxJava&style=flat&background=1081C1)](https://github.com/Wechat-Group/WxJava) From 7ff934a51d17553f3abc09e58e503b82bae92840 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 8 Mar 2020 15:51:27 +0800 Subject: [PATCH 0072/1706] :art: add something --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a66bda1030..c30a6a3c6e 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,7 @@ - 专注批量推送的小而美的工具:https://github.com/rememberber/WePush - yshop意象商城系统:https://gitee.com/guchengwuyue/yshopmall - wx-manage(微信公众号管理项目):https://github.com/niefy/wx-manage +- 基于若依开发的微信公众号管理系统:https://gitee.com/joolun/JooLun-wx #### 小程序: - (京东)友家铺子,友家铺子店长版,京粉精选 From 0a99706b7460ec30a565b360a0e0ff4c7696c5c9 Mon Sep 17 00:00:00 2001 From: S Date: Sun, 8 Mar 2020 16:18:09 +0800 Subject: [PATCH 0073/1706] =?UTF-8?q?:bug:=20#1426=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=A4=9A=E5=85=AC=E4=BC=97=E5=8F=B7=E7=AE=A1=E7=90=86=E7=9A=84?= =?UTF-8?q?=E4=B8=A4=E4=B8=AA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1、允许动态更新公众号的配置,原有逻辑:更新配置时会报“该公众号标识已存在,请更换其他标识!”; 2、多公众号的消息路由,原有逻辑问题:handler里WxMpConfigStorageHolder不能获取到appid,意味着用的wxmpservice不对,只会走默认的,已测试存在该问题 --- .../me/chanjar/weixin/mp/api/WxMpMessageRouter.java | 11 +++++++++++ .../weixin/mp/api/impl/BaseWxMpServiceImpl.java | 3 --- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java index 2571ebaa68..98ef7716f9 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java @@ -152,6 +152,13 @@ public WxMpXmlOutMessage route(final WxMpXmlMessage wxMessage, final Map context) { + return route(wxMessage, context, this.wxMpService.switchoverTo(appid)); + } + /** * 处理微信消息. */ @@ -228,6 +235,10 @@ public WxMpXmlOutMessage route(final WxMpXmlMessage wxMessage) { return this.route(wxMessage, new HashMap(2)); } + public WxMpXmlOutMessage route(String appid, final WxMpXmlMessage wxMessage) { + return this.route(appid, wxMessage, new HashMap(2)); + } + private boolean isMsgDuplicated(WxMpXmlMessage wxMessage) { StringBuilder messageId = new StringBuilder(); if (wxMessage.getMsgId() == null) { 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 e57099e9d7..73b548c24f 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 @@ -399,9 +399,6 @@ public void setMultiConfigStorages(Map configStorages @Override public void addConfigStorage(String mpId, WxMpConfigStorage configStorages) { synchronized (this) { - if (this.configStorageMap.containsKey(mpId)) { - throw new RuntimeException("该公众号标识已存在,请更换其他标识!"); - } this.configStorageMap.put(mpId, configStorages); } } From 1b193e30705f0035366b0aee97c616fa17878adb Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 8 Mar 2020 16:26:49 +0800 Subject: [PATCH 0074/1706] =?UTF-8?q?:bug:=20#1420=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E4=BA=91=E5=BC=80=E5=8F=91=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E6=96=87=E4=BB=B6=E4=B8=8B=E8=BD=BD=E9=93=BE=E6=8E=A5?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/cn/binarywang/wx/miniapp/api/WxMaCloudService.java | 1 + .../cn/binarywang/wx/miniapp/api/impl/WxMaCloudServiceImpl.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaCloudService.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaCloudService.java index 7e59e6ec6f..2cb72fd07a 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaCloudService.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaCloudService.java @@ -19,6 +19,7 @@ public interface WxMaCloudService { String DATABASE_COLLECTION_ADD_URL = "https://api.weixin.qq.com/tcb/databasecollectionadd"; String GET_QCLOUD_TOKEN_URL = "https://api.weixin.qq.com/tcb/getqcloudtoken"; String BATCH_DELETE_FILE_URL = "https://api.weixin.qq.com/tcb/batchdeletefile"; + String BATCH_DOWNLOAD_FILE_URL = "https://api.weixin.qq.com/tcb/batchdownloadfile"; String UPLOAD_FILE_URL = "https://api.weixin.qq.com/tcb/uploadfile"; String DATABASE_MIGRATE_QUERY_INFO_URL = "https://api.weixin.qq.com/tcb/databasemigratequeryinfo"; String DATABASE_MIGRATE_EXPORT_URL = "https://api.weixin.qq.com/tcb/databasemigrateexport"; diff --git a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaCloudServiceImpl.java b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaCloudServiceImpl.java index 984185649c..f83a7bde65 100644 --- a/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaCloudServiceImpl.java +++ b/weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaCloudServiceImpl.java @@ -133,7 +133,7 @@ public WxCloudBatchDownloadFileResult batchDownloadFile(String env, String[] fil fileList.add(ImmutableMap.of("fileid", fileId, "max_age", (Serializable) maxAges[i++])); } - String response = this.wxMaService.post(GET_QCLOUD_TOKEN_URL, ImmutableMap.of("env", env, "file_list", fileList)); + String response = this.wxMaService.post(BATCH_DOWNLOAD_FILE_URL, ImmutableMap.of("env", env, "file_list", fileList)); return WxGsonBuilder.create().fromJson(response, WxCloudBatchDownloadFileResult.class); } From 06aaacce65558fe00e427967918b0a987cfe5c65 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 8 Mar 2020 19:54:20 +0800 Subject: [PATCH 0075/1706] =?UTF-8?q?:art:=20=E4=BC=98=E5=8C=96=E7=82=B9?= =?UTF-8?q?=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/common/util/BeanUtils.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java index 4b7f9be6a7..768f2e5324 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java @@ -50,14 +50,13 @@ public static void checkRequiredFields(Object bean) throws WxErrorException { } } field.setAccessible(isAccessible); - } catch (SecurityException | IllegalArgumentException - | IllegalAccessException e) { + } catch (SecurityException | IllegalArgumentException | IllegalAccessException e) { log.error(e.getMessage(), e); } } if (!requiredFields.isEmpty()) { - String msg = "必填字段 " + requiredFields + " 必须提供值"; + String msg = String.format("必填字段【%s】必须提供值!", requiredFields); log.debug(msg); throw new WxErrorException(WxError.builder().errorMsg(msg).build()); } From f58ba62acc24990861a86280cf1453b743fcf16c Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 8 Mar 2020 20:15:36 +0800 Subject: [PATCH 0076/1706] =?UTF-8?q?:art:=20#1428=20=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=94=AF=E4=BB=98=E7=BB=9F=E4=B8=80=E4=B8=8B=E5=8D=95=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E4=B8=AD=E7=9A=84attach=E5=92=8Cdetail=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E5=9C=A8=E7=94=9F=E6=88=90xml=E6=97=B6=E5=8A=A0?= =?UTF-8?q?=E5=85=A5CDATA=E6=A0=87=E7=AD=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../wxpay/bean/request/WxPayUnifiedOrderRequest.java | 4 ++++ .../wxpay/service/impl/BaseWxPayServiceImplTest.java | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) 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 fc5949dfdf..3a80c82787 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 @@ -4,9 +4,11 @@ import com.github.binarywang.wxpay.constant.WxPayConstants.TradeType; import com.github.binarywang.wxpay.exception.WxPayException; import com.thoughtworks.xstream.annotations.XStreamAlias; +import com.thoughtworks.xstream.annotations.XStreamConverter; import lombok.*; import lombok.experimental.Accessors; import me.chanjar.weixin.common.annotation.Required; +import me.chanjar.weixin.common.util.xml.XStreamCDataConverter; import org.apache.commons.lang3.StringUtils; import java.util.Map; @@ -111,6 +113,7 @@ public class WxPayUnifiedOrderRequest extends BaseWxPayRequest { * */ @XStreamAlias("detail") + @XStreamConverter(value = XStreamCDataConverter.class) private String detail; /** @@ -124,6 +127,7 @@ public class WxPayUnifiedOrderRequest extends BaseWxPayRequest { * */ @XStreamAlias("attach") + @XStreamConverter(value = XStreamCDataConverter.class) private String attach; /** diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java index ab850d0b5b..de7b1e586e 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImplTest.java @@ -63,12 +63,13 @@ public void testUnifiedOrder() throws WxPayException { .notifyUrl("111111") .tradeType(TradeType.JSAPI) .openid(((XmlWxPayConfig) this.payService.getConfig()).getOpenid()) - .outTradeNo("1111112") + .outTradeNo("111111826") + .attach("#*#{\"pn\":\"粤B87965\",\"aid\":\"wx123\"}#*#") .build(); request.setSignType(SignType.HMAC_SHA256); WxPayUnifiedOrderResult result = this.payService.unifiedOrder(request); log.info(result.toString()); - log.warn(this.payService.getWxApiData().toString()); +// log.warn(this.payService.getWxApiData().toString()); } /** From fb4705281a0a0ed5e41358b7517f4e99e1abad9c Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 8 Mar 2020 20:20:10 +0800 Subject: [PATCH 0077/1706] =?UTF-8?q?:art:=20=E4=BC=98=E5=8C=96=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=EF=BC=8C=E5=A2=9E=E5=8A=A0serialVersionUID?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/github/binarywang/wxpay/bean/entpay/EntPayResult.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayResult.java index 9863e83bcc..23a3cb7f23 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/entpay/EntPayResult.java @@ -20,6 +20,8 @@ @NoArgsConstructor @XStreamAlias("xml") public class EntPayResult extends BaseWxPayResult { + private static final long serialVersionUID = 8523569987269603097L; + /** * 商户号. */ From 8aa4758e0161909ebaccd2cf1f8c293d8a7c8e06 Mon Sep 17 00:00:00 2001 From: Binary Wang Date: Sun, 8 Mar 2020 20:37:10 +0800 Subject: [PATCH 0078/1706] =?UTF-8?q?:bug:=20#1425=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=BC=81=E4=B8=9A=E5=BE=AE=E4=BF=A1OA=E5=AE=A1=E6=89=B9?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E5=87=A0=E4=B8=AA=E5=8F=82=E6=95=B0=E7=9A=84?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E6=88=96=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/cp/bean/oa/WxCpApprovalComment.java | 1 - .../weixin/cp/bean/oa/WxCpApprovalDetail.java | 8 ++++---- .../cp/bean/oa/applydata/ContentValue.java | 17 ++++------------- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalComment.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalComment.java index 8a70e3e6e9..1bf06ec51b 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalComment.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalComment.java @@ -13,7 +13,6 @@ */ @Data public class WxCpApprovalComment implements Serializable { - private static final long serialVersionUID = -5430367411926856292L; /** diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetail.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetail.java index 5021a57ee6..a22a435844 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetail.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/WxCpApprovalDetail.java @@ -13,7 +13,6 @@ */ @Data public class WxCpApprovalDetail implements Serializable { - private static final long serialVersionUID = 1353393306564207170L; /** @@ -49,19 +48,20 @@ public class WxCpApprovalDetail implements Serializable { /** * 申请人信息 */ - private WxCpApprovalApplyer applyer; + @SerializedName("applyer") + private WxCpApprovalApplyer applier; /** * 审批流程信息,可能有多个审批节点 */ @SerializedName("sp_record") - private WxCpApprovalRecord spRecord; + private WxCpApprovalRecord[] spRecords; /** * 抄送信息,可能有多个抄送节点 */ @SerializedName("notifyer") - private WxCpOperator notifyer; + private WxCpOperator[] notifiers; /** * 审批申请数据 diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentValue.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentValue.java index 7798338aa1..609b8dfb7c 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentValue.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/oa/applydata/ContentValue.java @@ -11,16 +11,15 @@ */ @Data public class ContentValue implements Serializable { - private static final long serialVersionUID = -5607678965965065261L; private String text; @SerializedName("new_number") - private Integer newNumber; + private Double newNumber; @SerializedName("new_money") - private Integer newMoney; + private Double newMoney; private ContentValue.Date date; @@ -36,24 +35,21 @@ public class ContentValue implements Serializable { @Data public static class Date implements Serializable { - private static final long serialVersionUID = -6181554080062231138L; private String type; @SerializedName("s_timestamp") - private Long timestamp; + private Double timestamp; } @Data public static class Selector implements Serializable { - private static final long serialVersionUID = 7305458759126951773L; private String type; private List